“Tailoring” the Christmas Sweater

Yesterday I wrote about The Snowing Christmas Sweater, my entry to the Vintage Computing Christmas Challenge 2023, a small programming contest targeting preferably vintage computers.

Animated gif showing my entry to the Vintage Computing Christmas Challenge 2023
The Snowing Christmas Sweater (ZX Spectrum BASIC), my entry to the Vintage Computing Christmas Challenge 2023, in action.

I also posted the details about my program on the BASIC on the ZX Spectrum Facebook group and I am particularly happy that Johan “Dr Beep” Koelman and Uwe Geiken, two authorities when it comes to ZX programming, expressed sincere appreciation for it!
Moreover, Dr Beep further optimized my code, reducing it from 63 bytes to just 54 bytes!

Starting from my BASIC listing for the ZX Spectrum:

3 LET x=RND*VAL "18": PRINT AT x,INT (RND+RND)*VAL "18"-ABS (x+VAL "6"*INT (RND*INT PI)-VAL "15");"*": GO TO PI

a first optimization that allows to save 1 byte is replacing the code that randomly chooses either 0 or 1: INT (RND+RND) with the more concise form: (RND>RND).

Another optimization consists in moving the RND, ABS and INT functions inside the string parsed by the VAL function; this is a feature I wasn’t aware of (I need to study the ZX Spectrum manual more thoroughly!).
When doing so, the token codes corresponding to the functions (and not the function names) must be put inside the VAL string. Here is the result of these optimizations:

3 LET x=VAL "RND*18": PRINT AT x,VAL "(RND>RND)*18-ABS (x+6*INT (RND*3)-15)";"*": GO TO PI

And here is the code formatted for BasinC (Sinclair BASIC IDE), in which you can see the token codes inside the strings (165 is the code for RND, 186 is the code for INT, 189 is the code for ABS; see the the ZX Spectrum character set):

3 LET x=VAL "\#165*18": PRINT AT x,VAL "(\#165>\#165)*18-\#189(x+6*\#186(\#165*3)-15)";"*": GO TO PI

With these changes, the code size drops to 55 bytes.

A final refactoring of the formula used to calculate the column of the “*” allows to save one more byte, so the final size is 54 bytes:

3 LET x=VAL "RND*18": PRINT AT x,VAL "(RND>RND)*18-ABS (x-3-6*INT (RND*3))";"*": GO TO PI

Here is the code that can be copied and pasted to BasinC:

3 LET x=VAL "\#165*18": PRINT AT x,VAL "(\#165>\#165)*18-\#189(x-3-6*\#186(\#165*3))";"*": GO TO PI

And here is the code formatted for the bas2tap tool:

3 LET x=VAL "{A5}*18": PRINT AT x,VAL "({A5}>{A5})*18-{BD}(x-3-6*{BA}({A5}*3))";"*": GO TO PI

Finally, Johan posted on the ZX81 Owners Club group a port to the Sinclair ZX81 of the Snowing Christmas Sweater. In this case, since the ZX81 version of Sinclair BASIC allows only one statement per line, the program is 3 lines long:

3 LET x=VAL "RND*18"
4 PRINT AT x,VAL "(RND>RND)*18-ABS (x-3-6*INT (RND*3))";"*"
5 GOTO PI
Animated gif showing the ZX81 port by Dr Beep
ZX81 port by Dr Beep

I’m very happy with the appreciation my little program has received and that with this challenge, I had the opportunity to learn something new about the ZX Spectrum!

Now, waiting for Logiker to publish the results!

Leggi in Italiano

Leave a comment

Your email address will not be published. Required fields are marked *

2 thoughts on ““Tailoring” the Christmas Sweater”