Tackling the Logiker 2022 Vintage Computing Christmas Challenge – part 7

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

Updates:

  • 2022-12-30 – Update to Jason’s final version to make it two bytes smaller.

In this final (?) installment, I wanted to share some other approaches that were taken to by members of the CoCo community draw this:

…including one that immediately was smaller than the version I did.

Rick Adams – PDP8/I

Early on, a version was shared by legendary CoCo programmer Rick Adams. His version was not for the CoCo – he chose to do it “in a very primitive BASIC, BASIC8 on a simulated PDP8/I running the TSS8 OS”…


0 'RICK ADAMS
12 FOR B = 1 TO 4
14 GOSUB 2000
20 NEXT B
22 C = 0
24 D = 0
30 FOR I = 1 TO 9
32 READ A, B
34 GOSUB 1000
36 NEXT I
50 FOR B = 4 TO 1 STEP -1
52 GOSUB 2000
58 NEXT B
200 DATA 0, 17, 1, 15, 2, 13, 3, 11, 4, 9, 3, 11, 2, 13, 1, 15, 0, 17
300 STOP
1000 PRINT TAB(A);
1010 FOR J = 1 TO B
1020 PRINT "*";
1030 NEXT J
1040 PRINT TAB(A + B + C);
1050 FOR J = 1 TO D
1060 PRINT "*";
1070 NEXT J
1080 PRINT
1090 RETURN
2000 A = 4
2002 D = B
2010 C = 9 - 2 * B
2020 GOSUB 1000
2030 RETURN
2046 END

I am unfamiliar with the BASIC on this machine, but at least it doesn’t require using “LET“. This version can run on the CoCo as well, and correctly reproduces the pattern.

Jim Gerrie – MC-10/CoCo

Next, take a look a this one by MC-10 BASIC-meister, Jim Gerrie:

Jim Gerrie’s fancier solution

His approach uses DATA statements and then draws the star in an interesting way.

Jason Pittman

In the comments on an earlier installment, Jason shared his attempt. His approach was realizing that the shape was just “four overlapping right triangles.”

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

This version is just 100 bytes! Due to the CoCo’s 32 column screen being too short, it doesn’t draw the top and end lines of the pattern, so it wouldn’t meet the challenge requirements. To fix that, he needed to add an IF:

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

Since the CoC 3 also has a 40×24 and 80×24 screen, the entire pattern could fit on those screens. Version three looked like this:

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

That one is a mere 88 bytes! And, the GOTO1 at the end is just to make it keep redrawing, else it stops near the top and would print the “OK” in the middle of the pattern.

I’d say the “WIDTH40:” is not required, since you could just say “run this from the 40 column screen.” And, to keep the loop, starting on LINE 0 allows just saying “GOTO” with no line number:

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

By my count, that turns in to 83 bytes! Amazing.

UPDATE: L. Curtis Boyle pointed out there was an unnecessary “+L” left in the code, which can be removed to make this 81 bytes. More amazing!

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

Here is what it looks like, though I paused it to capture the full image:

Please read his comments to part 1 for more background and earlier versions he shared.

I’m really blown away by this.

Are we done? Is this as small as it gets?

Unless there are more ideas, I think that is the end.

Merry Christmas, everyone!

23 thoughts on “Tackling the Logiker 2022 Vintage Computing Christmas Challenge – part 7

  1. Jason Pittman

    Thank you! This was fun! Thanks for posting this series. The RLE encoding is really cool and I’m going to have to do some tinkering with it.

    I came up with another way to do it and submitted it as an entry, and I guess I’ll follow the rules and not share it until after the contest, but I think it’s a smidge smaller than the last example (even without that unneeded “+L”). It’s similar, but it doesn’t draw triangles. I’m really curious if you guys will know a trick to make it even smaller, but I’ve racked my brain trying to shave another byte or two and couldn’t come up with a way to do it, but I have a feeling that it’s possible.

    Reply
    1. Allen Huffman Post author

      You beat the 83 bytes of your last one (after removing WIDTH40: and the GOTO # at the end)???

      I was just looking at this again (to fix some text in the article that was in the wrong place). I completely see what your version is doing now, with the overlapping triangles.

      Reply
      1. Jason Pittman

        I think my math was somehow wrong on the 88 bytes. It was a little larger. If I load the last example (Without WIDTH and the GOTO line number, and also remove the errant “+L”), I get 93 bytes

        On my new version that I submitted, if I also remove WIDTH, it’s smaller, but I couldn’t get it to work in one line and I’m really curious if there’s a way to make it stay on a single line or otherwise shorten it. It’s similar to the one that draws triangles because, once you see how it works, you say “Of course!” and smack yourself in the forehead, or at least I did. I’m not sure if it means anything, but when I submitted it, Logiker responded and said “Btw: Your algorithm is the same one as I used.” I don’t care about winning it at all, but I thought it’d be fun to sprinkle a little CoCo into their Commodore soup.

        Reply
        1. Allen Huffman Post author

          Nice. Great minds, and all that. I think memory is tricky because using ?MEM has to be clean after a CLEAR else it counts variables from earlier runs and stuff. I kept getting different values, but I got 83 for your smallest.

          Reply
  2. Kim Slawson

    I sprinkled a little Atari into the soup. I’m really interested to see if anyone else tried using polar coordinates for this.

    Reply
  3. Jason Pittman

    I just saw this on a forum and got a kick out of it. Apparently someone’s entry in this contest is the “Christmas bonus” feature in this in-browser PDP-11 emulator. If you type “UNIX” and then “XMAS” is draws the elusive Christmas star…

    https://mdfs.net/tty/

    Reply
    1. Allen Huffman Post author

      I LOVE the printer on this. Noisy. Reminds me of the thing my elementary school had in its “computer room”. I see this version prints spaces at the end of the lines, as well. How do we see the code?

      Reply
  4. Jason Pittman

    This is what I submitted. Can it be any smaller? I made two mistakes.

    I included WIDTH 40 in the submission and probably shouldn’t have. It works fine with or without, but for some reason I decided it’d be better to show it all on one screen.

    1 FORX=-8TO8:FORY=-8TO8:IFABS(Y)>4ANDABS(X)>4ORABS(ABS(Y)-ABS(X))>4THEN?" ";ELSE?"*";
    2 NEXT:?:NEXT

    I was mentally stuck on doing it in BASIC, but I should have done it in c/cmoc, because the binary that cmoc compiles from this is 12 bytes!

    #include "cmoc.h"

    int main()
    {
    for(int y=-8;y<9;y++)
    {
    for(int x=-8;x<9;x++)
    {
    if ((abs(x) > 4 && abs(y) > 4) || abs(abs(y)-abs(x)) > 4)
    printf(" ");
    else
    printf("*");
    }
    printf("\n");
    }
    return 0;
    }

    Reply
    1. Jason Pittman

      (Eh…I maybe take back “12 bytes”…that’s just what ?MEM shows before and after loading, and that probably isn’t showing the size of the binary.)

      Reply
      1. Jason Pittman

        Ugh. I just looked back at the presentation and what I submitted was very close to what the winner submitted, but he saved a byte by looping the screen width (and thus not needing to do a PRINT statement to go to the next line) and came up with a slick “9OR…” to use for the character decision that works on one line. Try this out…

        0 FORY=-8TO8:FORX=-8TO23:PRINT CHR$(33+(9ORABS(ABS(Y)-ABS(X))>4ORABS(X)>4ANDABS(Y)>4));:NEXT:NEXT

        Reply
        1. Allen Huffman Post author

          Wow, interesting. Slow, but interesting. Lets see. 9 is “00001001” and space 32 is “00100000” and asterisk 42 is “00101010”. Ah, I see. They use 33 for the base then OR with 9 or .. okay, I gotta pull this one apart. Interesting.

          Reply
      1. Jason Pittman

        The basic and c versions do the same thing…it’s drawing an x and y axis from -8 to 8 (so the center line is zero on both x and y). That way, it can use absolute value to treat all 4 quadrants the same. If the abs of x and y are both >4, it prints a space to cut off the corners. If abs( abs(y) – abs(x) ) is >4, it prints a space to make the top and side indentions.

        Reply
      1. Jason Pittman

        I made a spreadsheet in excel with the whole 9×9 shape size on it and highlighted the cells that needed to be spaces. Then fiddled around with finding a rule for those highlighted cells. I tried several ways of taking each cell’s x and y and adding, multiplying, dividing, bit shifting them, etc, and this is the only one I came up with that worked. It was a pretty quick way to just visualize it and play around. I still think there’s probably some kooky piece of math that would make it smaller.

        Reply

Leave a Reply

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