carlsson Posted December 5, 2022 Share Posted December 5, 2022 For the second year in a row, Logiker is inviting programmers to the Vintage Computing Christmas Challenge. Last year when we drew a Christmas tree, it appears only two entries (one strict and one creative) came from the A8 camp, compared to 30++ entries for various Commodore 8-bit computers, so here's your chance to improve on that. This year the challenge is to draw a star with eight points. Suitable programming languages are BASIC, machine code or whatever is available on your computer. The shorter implementation (measured in bytes), the better. Note that you're not supposed to spill the beans about your implementation, not even how many bytes you're down to. https://logiker.com/Vintage-Computing-Christmas-Challenge-2022 Logiker will be making a submission form on the website, but it isn't quite yet there. In the mean time, I already made three entirely different implementations in C64 BASIC (without getting into details how or at what sizes). 6 Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 (edited) Well, now that I blew 3 hours messing around with this, I've got somewhat tight Atari BASIC version but can't say how small it is, of course. I decided to quickly port the sample code just to compare my program. The port of the sample code takes 390 bytes. I found the number by finding the difference in the free memory before and after loading the program. i.e. NEW ? FRE(0) 32274 LOAD"D:STARP.BAS" ? FRE(0) 31884 ? 32274-31884 390 So, if anyone wants to give it a try, they need to get under 390 bytes. 😁 10 GRAPHICS 0 20 PRINT " * *" 30 PRINT " ** **" 40 PRINT " *** ***" 50 PRINT " **** ****" 60 PRINT "*****************" 70 PRINT " ***************" 80 PRINT " *************" 90 PRINT " ***********" 100 PRINT " *********" 110 PRINT " ***********" 120 PRINT " *************" 130 PRINT " ***************" 140 PRINT "*****************" 150 PRINT " **** ****" 160 PRINT " *** ***" 170 PRINT " ** **" 180 PRINT " * *" EDIT: After a little more experimenting, I don't think relying on BASIC to provide the free memory is an accurate way to determine the size of the program. Anybody have any ideas? Edited December 5, 2022 by reifsnyderb 1 Quote Link to comment Share on other sites More sharing options...
MichaG Posted December 5, 2022 Share Posted December 5, 2022 Logiker says: "Make the size of the program file (e.g. PRG on C64) as small as possible" so I think you have to compare the *.com or *.bas files. Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 2 minutes ago, MichaG said: Logiker says: "Make the size of the program file (e.g. PRG on C64) as small as possible" so I think you have to compare the *.com or *.bas files. That would work. But DOS 2.5 only shows 128 byte sectors. Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 5, 2022 Share Posted December 5, 2022 (edited) @reifsnyderb try this In BASIC, this will give you the byte count of any file:- 100 Open #1,4,0,"D:RAMTEST.BAS" 110 A=0 120 Trap 160:REM END OF FILE TRAP 130 Get #1,B 140 A=A+1 150 Goto 130 160 Trap 40000 170 Close #1 180 Print "FILE LENGTH IS ";A;" BYTES" 190 End Ready RUN FILE LENGTH IS 1422 BYTES Edited December 5, 2022 by TGB1718 Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 (edited) Ok. This is weird. I just ran the program @TGB1718 supplied and the sample code is 424 bytes vs 390 bytes in memory. I guess BASIC adds some other information to the file when it saves it? Edited December 5, 2022 by reifsnyderb Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 5, 2022 Share Posted December 5, 2022 If you want to make your program look smaller, "LIST" it and run the length program again. My "STAR" program is coming in at 409 bytes on disk the listed version is 330 bytes on disk and the program when in memory and has run is 216 bytes I don't know anything about the C64, maybe it's easier to tell what the program size is, personally I think for the A8 we should use FRE(0) with no program in memory, load the program, run it and do FRE(0) again and subtract second number from first @carlsson can you decide what method we should use ? ( I had a SAAB model with your name on the badge ) 1 Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 (edited) @TGB1718 216 bytes in memory? 😞 (Good for you! Bad for me.) What language? Edited December 5, 2022 by reifsnyderb Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 5, 2022 Share Posted December 5, 2022 Rev B Atari Basic adds 16 bytes padding to the end of the program (a bug fixed in Rev C / doesn't exist in Rev A) - and that is cumulative - e.g. do a 1-line program then just repeatedly save then load it and it'll grow each time. Any version can get unwanted bloat due to unused variable names etc. which can be fixed by LIST/ENTER. Counting program size for Basic can be a bit unfair - C64 can have an advantage in that numeric constants are just the characters where Atari has the 6 byte FP number. Then again, C64 stores stuff like spaces between some statements and parameters. Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 (edited) 20 minutes ago, Rybags said: Rev B Atari Basic adds 16 bytes padding to the end of the program (a bug fixed in Rev C / doesn't exist in Rev A) - and that is cumulative - e.g. do a 1-line program then just repeatedly save then load it and it'll grow each time. Any version can get unwanted bloat due to unused variable names etc. which can be fixed by LIST/ENTER. Counting program size for Basic can be a bit unfair - C64 can have an advantage in that numeric constants are just the characters where Atari has the 6 byte FP number. Then again, C64 stores stuff like spaces between some statements and parameters. Ok. Great tip on using list/enter to load and save the program. I am quite pleased now. 🙂 I just couldn't believe that my program was 443 bytes, as compact as it is, while the ported sample program is 424 bytes as saved. The ported sample program, when listed to disk, is now 468 bytes on disk. Edited December 5, 2022 by reifsnyderb Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 5, 2022 Share Posted December 5, 2022 29 minutes ago, reifsnyderb said: What language? Just good old BASIC 1 Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 @carlsson I am now fine with using the size on the disk as long as I can LIST the program to disk. 😁😜😎 Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 5, 2022 Share Posted December 5, 2022 (edited) In most cases SAVE will be a smaller file but sometimes LIST can be. I wonder how they'd treat a bootable disk - really it should be the 6 byte header + size of the program not rounded to next sector. And also not including ATR overheads. I guess though you could have it as a raw XFD image (only suggesting this disk image stuff since a binary file has extra bloat - 2 x leading FF plus 6 bytes extra to supply a RUN address. Edited December 5, 2022 by Rybags Quote Link to comment Share on other sites More sharing options...
carlsson Posted December 5, 2022 Author Share Posted December 5, 2022 A C64 PRG is 2 bytes load address and then the tokenized program, possibly including up to three zero bytes at the end. I believe the FRE(0) method without variables assigned is just as good. How would you measure machine code, by effective bytes or file format length on disk? Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 58 minutes ago, carlsson said: A C64 PRG is 2 bytes load address and then the tokenized program, possibly including up to three zero bytes at the end. I believe the FRE(0) method without variables assigned is just as good. How would you measure machine code, by effective bytes or file format length on disk? So, to confirm, either size on disk or size in memory both are good? Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted December 5, 2022 Share Posted December 5, 2022 (edited) Atari can mirror horizontally the star can be halved maybe Edited December 5, 2022 by _The Doctor__ 2 Quote Link to comment Share on other sites More sharing options...
carlsson Posted December 5, 2022 Author Share Posted December 5, 2022 To be clear: I'm not the arranger or the one to set the rules. Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 5, 2022 Share Posted December 5, 2022 4 hours ago, carlsson said: To be clear: I'm not the arranger or the one to set the rules. Good enough. I'll worry more about the program file size...as per the rules. 🙂 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 6, 2022 Share Posted December 6, 2022 20 hours ago, reifsnyderb said: @TGB1718 216 bytes in memory? 😞 (Good for you! Bad for me.) Think I might have mis-calculated, now fixed it, my little BASIC program is:- 223 Bytes on disk 231 Bytes in memory 3 lines of code so not far from my original 2 Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 6, 2022 Share Posted December 6, 2022 1 hour ago, TGB1718 said: Think I might have mis-calculated, now fixed it, my little BASIC program is:- 223 Bytes on disk 231 Bytes in memory 3 lines of code so not far from my original Not bad. Is the program listed or saved to disk? Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 6, 2022 Share Posted December 6, 2022 DL tricks could reduce the program size though whether that would result in the shortest overall program? My thoughts on how to do it - use the CIO PUT Characters vector to do the output. The star is 17 characters wide, symetrical. Whether to print the middle character is merely dependent on a range of Y positions. The remaining 16 characters could be read as a bitmap. Only need to store the left top part since its' symetrical. Bit-shift then output space or * depending on result. I do suspect that not resorting to DL tricks would produce the shortest program. If the bitmap is only costing a single byte per line with a comparison in the middle of the loop to determine if we output the middle character, it will be way cheaper than a custom DLI with a bunch of LMS to duplicate/invert the top half. Quote Link to comment Share on other sites More sharing options...
reifsnyderb Posted December 6, 2022 Share Posted December 6, 2022 (edited) 12 minutes ago, Rybags said: DL tricks could reduce the program size though whether that would result in the shortest overall program? My thoughts on how to do it - use the CIO PUT Characters vector to do the output. The star is 17 characters wide, symetrical. Whether to print the middle character is merely dependent on a range of Y positions. The remaining 16 characters could be read as a bitmap. Only need to store the left top part since its' symetrical. Bit-shift then output space or * depending on result. I do suspect that not resorting to DL tricks would produce the shortest program. If the bitmap is only costing a single byte per line with a comparison in the middle of the loop to determine if we output the middle character, it will be way cheaper than a custom DLI with a bunch of LMS to duplicate/invert the top half. I was thinking about using a bitmap. While I didn't try it, my belief is that using a bitmap would result in a larger program due to the code required to process the bitmap. So far, I've done this using 2 different strategies. The second strategy is 39 bytes smaller on disk. I decided to optimize for disk size, though, as the rules say to make the program file as small as possible. It would be nice to have single byte variables, though. Three bytes to store small integers is overkill. Admittedly, that was probably a compromise solution to stuff BASIC into 8k. Edited December 6, 2022 by reifsnyderb Quote Link to comment Share on other sites More sharing options...
Rybags Posted December 6, 2022 Share Posted December 6, 2022 In some cases strings can be used in Basic and processed with functions "numerically" which could save memory. 1 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted December 6, 2022 Share Posted December 6, 2022 22 hours ago, carlsson said: How would you measure machine code, by effective bytes or file format length on disk? I think it should be the size on disk minus the 6 byte header. For BASIC just the size on disk would be reasonable with the program LISTED SAVING also stores garbage like previously used variables that's why its always good to LIST to disk, NEW, ENTER, then SAVE to get rid of the garbage. 1 hour ago, reifsnyderb said: Not bad. Is the program listed or saved to disk? LISTED to disk (now down to 210 Bytes ) Interestingly, this latest version although smaller on disk when LISTED is 290 Bytes when SAVED and 288 Bytes when FRE(0) is used, very close the the SAVED version Quote Link to comment Share on other sites More sharing options...
_The Doctor__ Posted December 6, 2022 Share Posted December 6, 2022 you are not supposed to be discussing what your size is or any that, you rule breakers you! maybe mirror trick does not need all of that either... 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.