Tackling the Logiker 2022 Vintage Computing Christmas Challenge – part 1

See also: part 1, part 2, part 3, part 4, part 5, part 6 and part 7.

Here we go again! Over in the Facebook Color Computer group, David M. shared a link to this year’s Vintage Computing Christmas Challenge from Logiker. Although I did not submit an entry, I did play with last year’s challenge on my TRS-80 Color Computer.

Last year, it was this:

This year, the challenge is a bit more challenging. Per the challenge website, here is sample code for Commodore:

 10 print"{clear}"
 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"               **** ****"
190 print"               ***   ***"
200 print"               **     **"
210 print"               *       *"
220 goto 220

Starting with that un-optimized version, I will change it to work on the CoCo 1/2/3’s 32-column screen by adjusting it to be properly centered on that display.

 10 CLS
 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"           **** ****"
190 PRINT"           ***   ***"
200 PRINT"           **     **"
210 PRINT"           *       *"
220 GOTO 220

Unfortunately, this design is 17 rows tall, and the CoCo’s standard display is only 16. It won’t fit:

We should still be able to enter the challenge by having the program print this pattern, even if it scrolls off the screen a bit. To get one extra line there, we can get rid of the line feed at the end of the final PRINT statement in line 210 by adding a semi-colon to the end:

210 PRINT"           *       *";

And so it begins…

And so it begins

The goal is to make this as small as possible. There were many ways to approach last year’s Christmas tree challenge, and you can read about the results and a follow-up with suggestions folks gave to save a byte or two.

A simple thing is to remove the spaces at the front and replace them with the TAB() command:

 10 CLS
 50 PRINTTAB(7)"    *       *"
 60 PRINTTAB(7)"    **     **"
 70 PRINTTAB(7)"    ***   ***"
 80 PRINTTAB(7)"    **** ****"
 90 PRINTTAB(7)"*****************"
100 PRINTTAB(7)" ***************"
110 PRINTTAB(7)"  *************"
120 PRINTTAB(7)"   ***********"
130 PRINTTAB(7)"    *********"
140 PRINTTAB(7)"   ***********"
150 PRINTTAB(7)"  *************"
160 PRINTTAB(7)" ***************"
170 PRINTTAB(7)"*****************"
180 PRINTTAB(7)"    **** ****"
190 PRINTTAB(7)"    ***   ***"
200 PRINTTAB(7)"    **     **"
210 PRINTTAB(7)"    *       *";
220 GOTO 220

Although this only looks like it saves a character per line (“TAB(8)” versus “seven spaces”), the code itself will be smaller since the TAB command tokenizes down to one (or maybe two?) bytes.

Also, the ending quote is not needed if it’s the last thing on a line, so they could be removed:

 50 PRINTTAB(7)"    *       *
 60 PRINTTAB(7)"    **     **
 70 PRINTTAB(7)"    ***   ***

That would save one byte per line.

But, each line number consumes 5-bytes on it’s own, so a better way to save space would be to pack the lines together. Each line you eliminate saves five bytes. That would become pretty unreadable though, but let’s do it anyway:

10 CLS:PRINTTAB(7)"    *       *":PRINTTAB(7)"    **     **":PRINTTAB(7)"    ***   ***":PRINTTAB(7)"    **** ****":PRINTTAB(7)"*****************":PRINTTAB(7)" ***************":PRINTTAB(7)"  *************":PRINTTAB(7)"   ***********"
130 PRINTTAB(7)"    *********":PRINTTAB(7)"   ***********":PRINTTAB(7)"  *************":PRINTTAB(7)" ***************":PRINTTAB(7)"*****************":PRINTTAB(7)"    **** ****":PRINTTAB(7)"    ***   ***":PRINTTAB(7)"    **     **"
210 PRINTTAB(7)"    *       *";
220 GOTO 220

That’s quite the unreadable mess!

This could still be made better, since the text lines were kept under the input buffer limitation size, but when you enter that line, BASIC compresses it (tokenizes keywords like PRINT, TAB and GOTO) making it take less space. You can then sometimes EDIT the line, Xtend to the end and type a few more characters.

That may or may not be allowed for the Logiker challenge. And since I want to provide code here you could copy and then load in to an emulator, I’ll keep it to the limit of what you could type in.

In the next installment, I’ll see if my brane can figure out a way to generate this code using program logic rather than brute-force PRINT statements.

Until then…

20 thoughts on “Tackling the Logiker 2022 Vintage Computing Christmas Challenge – part 1

  1. Jason Pittman

    I had to play around with an idea on this. Since the star is basically four diagonal lines and four straight lines, could it be made smaller if you build the outline and then loop through and fill in the area inside the outline? It’d be slow, but speed isn’t mentioned in the goals. I tinkered with the idea for a few minutes on the COCO3 WIDTH 40 screen so the shape fits on the screen, but I forgot that when you do a LOCATE and PRINT; that it wipes out the next character (I forget…can you POKE a character directly on the 40 column screen the way you can on a COCO2’s 32-column screen and prevent this?) When I realized this, I didn’t bother filling the shape in, but I thought it might give you an idea for something to try.

    10 WIDTH40:CLS
    20 FOR X=0TO16
    30 IF X<=12THEN LOCATE24-X,X:PRINT”“;:LOCATE16+X,X:PRINT”“;
    40 IF X>=4THEN LOCATE32-X,X:PRINT”“;:LOCATE8+X,X:PRINT”“;
    50 IF X12THEN LOCATE16,X:PRINT”“;:LOCATE24,X:PRINT”“;
    60 IF X=4OR X=12THEN FOR Y=12TO28:LOCATE Y,X:PRINT”*”;:NEXT Y
    70 NEXT X

    Reply
  2. Jason Pittman

    Sorry, wordpress butchered that code. Does these comments support markdown code? Excuse me while I try.

    10 PRINT "TEST"

    Reply
  3. Jason Pittman

    (Cool…I guess so!) So anyway, I played around with that idea I posted above and wound up with the code below. The screen being a line short is frustrating, but if the screen could somehow magically have an extra line, removing the IF part of line 90 outta fix it.

    10 CLS
    20 FOR X=0TO4
    30 IF X<=3 GOSUB 70
    40 T$=STRING$(17-(X*2),"*"):PRINT @(4*32)+(32*X)+X,T$:PRINT @(12*32)-(32*X)+X,T$
    50 NEXT X
    60 GOTO 60
    70 S=4+X*32:E=S+X+1:T$=STRING$(E-S,"*")
    80 PRINT @S,T$;:PRINT @S+8-X,T$;
    90 IF X>0 THEN PRINT @(16*32)-(X*32)+4,T$;:PRINT @(16*32)-(X*32)+12-X,T$;
    100 RETURN

    Reply
      1. Jason Pittman

        Actually, I was making it too hard with that example. Try this:

        10 CLS
        20 FOR X = 1 TO 13
        30 T$=STRING$(X,"*"):PRINT @(32*(X-1)+4),T$;:PRINT @(32*(X-1)+13-X),T$;
        40 IF X > 1 THEN PRINT@(32*17)-(32*X)+4,T$;:PRINT@(32*17)-(32*X)+13-X,T$;
        50 NEXT X
        60 GOTO 60

        Reply
  4. Jason Pittman

    (Hopefully this isn’t a double post.) Actually, this makes it a lot simpler/smaller and work in one loop, where the IF on 40 keeps the last line from going off the low res screen.

    10 CLS
    20 FOR X = 1 TO 13
    30 T$=STRING$(X,"*"):PRINT @(32*(X-1)+4),T$;:PRINT @(32*(X-1)+13-X),T$;
    40 IF X > 1 THEN PRINT@(32*17)-(32*X)+4,T$;:PRINT@(32*17)-(32*X)+13-X,T$;
    50 NEXT X
    60 GOTO 60

    Reply
  5. Jason Pittman

    Ugh. If not for that line number constraint, you could start at 32 instead of 64 and have it.

    1 CLS
    2 FOR X=64TO416STEP32:L=X/32:T$=STRING$(L,"*"):PRINT@X-28,T$;:PRINT@(X-19-L),T$;:PRINT@544-X+4,T$;:PRINT@557-X-L,T$;:NEXTX:GOTO2

    Reply
    1. Allen Huffman Post author

      Oh wow. Black magic! I copied that text out to an editor on my iPad and saved it to my iCloud desktop, then I went to the XROAR emulator online and it has a button called RUN that let me browse to the file and it does the load and RUN. That’s very impressive. CLS isn’t required for the challenge. How much ?MEM before and after loading it does it show? I ended up with a 115 byte version (part 6 coming up) and yours looks smaller. This one didn’t put the single stars on the ends – was it supposed to?

      Reply
    2. Allen Huffman Post author

      “*” can go to 42 and be slower but take up one less byte. Space after FOR can remove a second byte. NEXTX can be NEXT to save a third byte. Wow. I’m really impressed by this. I don’t understand how it works yet but I will be checking it out tomorrow.

      Reply
      1. Jason Pittman

        Essentially, it’s just drawing four overlapping right-angle triangles.
        I think this first example is using 96 bytes. If you split it apart and REM out 3 of the 4 print statements, you’ll see exactly what it’s doing. I was just cheating and skipping the first (and thus last) lines here to make it fit in the screen without scrolling.

        1 FORX=64TO416STEP32:L=X/32:T$=STRING$(L,42):PRINT@X-28,T$;:PRINT@(X-19-L),T$;:PRINT@544-X+4,T$;:PRINT@557-X-L,T$;:NEXT:GOTO1

        Now, if we want to print that first line, I’ll add an IF to make sure it isn’t on that last line, which will be outside the bounds and crash. It’s 98 bytes.

        1 FORX=32TO416STEP32:L=X/32:T$=STRING$(L,42):PRINT@X-28,T$;:PRINT@(X-19-L),T$;:IF X>32THEN PRINT@544-X+4,T$;:PRINT@557-X-L,T$;
        2 NEXT
        3 GOTO3

        Now, this COCO3 (WIDTH 40) example uses 88 bytes and shows the whole shape.

        1 WIDTH40:FORX=1TO13:L$=STRING$(X,42):LOCATE14-X,X:PRINTL$;:LOCATE14-X,18-X:PRINTL$;:LOCATE5+L,X:PRINTL$;:LOCATE5,18-X:PRINTL$;:NEXT:GOTO1

        Fun stuff! I probably shouldn’t have tinkered with this for so long. You should have your own contests like this!

        Reply
        1. Allen Huffman Post author

          I think the CC3 version should be submitted. I didn’t submit list year, but did enjoy writing about it. But after six parts of working through it, your first attempt is way better!

          Reply
          1. Jason Pittman

            Thanks…but the great think about what you’re doing is that it works for anything. This “star” challenge just happened to work well because I fiddled around long enough on this one example to figure out how to do the overlapping triangles in a single loop. But, I went back and played around with the Christmas tree one from last year, and came up with a similar pattern for it, too, but your compression was half the size.

          2. Allen Huffman Post author

            I didn’t even “see” the right triangles until you said that. Now it seems obvious, but I’m not sure I could figure that out. May I include your version in part 7?

          3. Allen Huffman Post author

            83 bytes. Wow. Just wow. Part 7 ends with a bang.

            0 FORX=1TO13:L$=STRING$(X,42):LOCATE14-X,X:PRINTL$;:LOCATE14-X,18-X:PRINTL$;:LOCATE5+L,X:PRINTL$;:LOCATE5,18-X:PRINTL$;:NEXT:GOTO

          4. Jason Pittman

            Sure! I didn’t see the triangles either for a long time. Sorry for posting so much jibberish leading up to it.

          5. Jason Pittman

            By the way…I was wrong. I’m not sure what kind of late-night math I was doing, but the working COCO3 one isn’t 88 bytes…it’s 100 bytes. I’ve got another different idea I’m going to try, and if I can beat that, I’m going to submit it.

  6. Jason Pittman

    Or finally…a working one for COCO3.

    1 WIDTH40:FOR X=1TO13:L$=STRING$(X,"*"):LOCATE 13-X,X:PRINT L$;:LOCATE 13-X,17-X:PRINT L$;:LOCATE 4,X:PRINT L$;:LOCATE 4,17-X:PRINT L$;:NEXT X:GOTO 1

    Reply
  7. Pingback: Tackling the Logiker 2022 Vintage Computing Christmas Challenge – part 7 | Sub-Etha Software

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.