La sfida della Stella di Natale

Si è da poco conclusa la Vintage Computing Christmas Challenge 2022 (VC³ 2022), un simpatico concorso di programmazione organizzato da Logiker per il periodo di Natale.

L’obiettivo della sfida principale, chiamata Christmas Star Challenge, consiste nella realizzazione di un programma per qualsiasi computer e linguaggio (preferibilmente per sistemi vintage), in grado di rappresentare fedelmente la figura mostrata nell’immagine seguente, ottimizzando il codice il più possibile, oppure di migliorarla.

Immagine da realizzare per la Christmas Star Challenge
Immagine da realizzare per la Christmas Star Challenge (fonte: Logiker).

In alternativa, optando per la challenge Wild, era possibile creare un programma completamente differente, purché a tema natalizio.

Centinaia di persone si sono cimentate con la sfida e tutti i programmi in gara sono presentati nel video realizzato dall’organizzatore:

Video dei Logiker con i risultati della sfida e presentazione di tutti i programmi in concorso.

La mia implementazione della Stella di Natale in Tiny BASIC

Ho deciso di partecipare alla Christmas Star Challenge realizzando un programma in Tiny BASIC. La stella, che occupa una superficie quadrata il cui lato misura 17 caratteri, può essere suddivisa in quattro triangoli sovrapposti:

01    *            
02    **           
03    ***          
04    ****         
05    *****        
06    ******       
07    *******      
08    ********     
09    *********    
10    **********   
11    ***********  
12    ************ 
13    *************
14
15
16
17
01            *    
02           **    
03          ***    
04         ****    
05        *****    
06       ******    
07      *******    
08     ********    
09    *********    
10   **********    
11  ***********    
12 ************    
13*************    
14
15
16
17
01
02
03
04
05*************    
06 ************    
07  ***********    
08   **********    
09    *********    
10     ********    
11      *******    
12       ******    
13        *****    
14         ****    
15          ***    
16           **    
17            *    
01
02
03
04
05    *************
06    ************ 
07    ***********  
08    **********   
09    *********    
10    ********     
11    *******      
12    ******       
13    *****        
14    ****         
15    ***          
16    **           
17    *            

L’idea è quindi quella di iterare su ciascuna delle 17*17 posizioni e di stampare un carattere “*” se il “punto” considerato appartiene ad almeno uno dei 4 triangoli, altrimenti uno spazio vuoto ” “:

 100 LET R=0
 110 LET C=0
 120 LET S=0
 130 IF R<13 THEN IF C>3 THEN IF C<R+5 THEN LET S=1
 140 IF R<13 THEN IF C<13 THEN IF C>11-R THEN LET S=1
 150 IF R>3 THEN IF C<13 THEN IF C>R-5 THEN LET S=1
 160 IF R>3 THEN IF C>3 THEN IF C<21-R THEN LET S=1
 800 IF S=0 THEN PRINT " ";
 810 IF S=1 THEN PRINT "*";
 900 LET C=C+1
 910 IF C<17 THEN GOTO 120
 915 PRINT
 920 LET R=R+1
 930 IF R<17 THEN GOTO 110
1000 END

Rimuovendo gli spazi superflui e sfruttando le abbreviazioni delle istruzioni Tiny BASIC, è stato possibile ridurre la dimensione del listato del programma a 203 caratteri:

1R=0
2C=0
3S=0
4IFR<13IFC>3IFC<R+5S=1
5IFR<13IFC<13IFC>11-RS=1
6IFR>3IFC<13IFC>R-5S=1
7IFR>3IFC>3IFC<21-RS=1
8IFS=0PR" ";
9IFS=1PR"*";
10C=C+1
11IFC<17GOTO3
12PR
13R=R+1
14IFR<17GOTO2
15END

Ed ecco l’output:

    *       *    
    **     **    
    ***   ***    
    **** ****    
*****************
 *************** 
  *************  
   ***********   
    *********    
   ***********   
  *************  
 *************** 
*****************
    **** ****    
    ***   ***    
    **     **    
    *       *    

Non ho trovato un modo per ottimizzare ulteriormente il programma prima della fine della sfida; accetto comunque eventuali suggerimenti a riguardo!

Puoi osservare il programma in esecuzione su un computer Cosmac ELF emulato con Emma 02 nel seguente video, oppure eseguirlo e/o modificarne il codice utilizzando l’interprete online TinyBASICBlazor.

La mia implementazione in Tiny BASIC della Stella di Natale, in (lenta) esecuzione su Cosmac ELF, emulato con Emma 02.
La mia implementazione in Tiny BASIC della Stella di Natale, in esecuzione su TinyBASICBlazor, interprete Tiny BASIC per browser web.

Varianti ed evoluzioni

Data la semplicità della sintassi Tiny BASIC, che può essere considerato come un sottoinsieme della maggior parte dei dialetti BASIC disponibili, il programma può essere eseguito su una vastità di piattaform senza alcuna modifica (ad es. BBC Basic) o con modifiche minime. Ad esempio, su Sinclair ZX81 è sufficiente rimuovere l’istruzione “END” o sostituirla con “STOP” per avere una sintassi corretta.

Christmas Star - programma in esecuzione in BBC BASIC for SDL
La mia implementazione della Stella di Natale in esecuzione in BBC BASIC for SDL.

Proprio per il piccolo computer Sinclair, ho provato a compattare ulteriormente il codice del mio programma Tiny BASIC originale, anche se per ottenere risultati migliori in termini di dimensioni sarebbe stato necessario riscriverlo completamente sfruttando le caratteristiche del BASIC Sinclair.

Christmas Star - listato del programma per ZX81
Listato del programma per Sinclair ZX81.
Christmas Star - output del programma per ZX81
Output del programma per ZX81.
Programma per ZX81 in azione.

Infine, dato che lo scopo principale della competizione era quello di divertirsi, ho realizzato una versione Teletext della Stella di Natale, che riprende l’immagine di riferimento della sfida:

Christmas Star - versione Teletext
La Stella di Natale, versione Teletext.

La classifica ordinata per dimensione del codice sorgente è disponibile, insieme ai download di tutte le entry, su demozoo.org. Complimenti all’impareggiabile Dr. BEEP, che si è aggiudicato le prime posizioni con le versioni in Assembly per ZX81 e ZX Spectrum, il cui codice occupa solamente 27 e 29 byte rispettivamente!

Read in English