Alcuni giorni fa, mi sono imbattuto in un post, pubblicato sul gruppo facebook dedicato al linguaggio di programmazione BASIC, in cui si fa riferimento a una challenge indetta sul forum della community di Liberty BASIC. L’obiettivo della sfida consiste nella realizzazione di un programma per risolvere il seguente “rompicapo” matematico:
C'è una cassetta di mele e pere. Alcune sono grandi, altre piccole; alcune sono gialle, le altre sono verdi. Non ci sono pere piccole né mele piccole e verdi. Sono resi noti alcuni numeri: 25 mele, 17 pere, 32 frutti grandi, 28 gialli. Ci sono due mele verdi in più rispetto alle pere verdi. Trova il numero di mele grandi gialle.
Il problema è riconducibile a un sistema lineare di 5 equazioni in 5 incognite, per la cui risoluzione sono disponibili strumenti matematici ben noti (forse ne ho anche implementato qualcuno, quando ero studente), ma in questo caso ho deciso di divertirmi un po’ implementando in Tiny BASIC un algoritmo di forza bruta per verificare tutte le soluzioni teoricamente possibili, fino a che si trova quella effettivamente corretta. Il listato del programma è riportato di seguito:
1 REM ********************
2 REM * APPLES AND PEARS *
3 REM ********************
4 REM BRUTE FORCE TINYBASIC IMPLEMENTATION
5 REM BY MARCO'S RETROBITS
6 REM RETROBITS.ALTERVISTA.ORG
7 REM PLEASE TAKE A SEAT, THIS COULD BE SLOW
8 REM ********************
10 REM THERE WAS A BOX OF APPLES AND PEARS
11 REM SOME ARE BIG, SOME ARE SMALL;
12 REM SOME ARE YELLOW, REST ARE GREEN
13 REM THERE ARE NO SMALL PEARS
14 REM AND NO SMALL GREEN APPLES.
15 REM SOME NUMBERS ARE GIVEN:
16 REM 25 APPLES, 17 PEARS
17 REM 32 BIG FRUITS
18 REM 28 YELLOW ONES.
19 REM THERE ARE TWO MORE GREEN APPLES THAN GREEN PEARS.
20 REM FIND THE NUMBER OF BIG YELLOW APPLES.
30 REM C: SMALL YELLOW APPLES
40 REM D: BIG YELLOW APPLES
50 REM E: BIG GREEN APPLES
60 REM F: BIG YELLOW PEARS
70 REM G: BIG GREEN PEARS
80 REM A: APPLES; P: PEARS
90 REM B: BIG FRUITS; Y: YELLOW ONES
100 LET A = 25
110 LET P = 17
120 LET B = 32
130 LET Y = 28
200 REM FOR C = 1 TO A
201 LET C=1
210 REM FOR D = 1 TO A-C
211 LET D = 1
220 REM FOR E = 1 TO A-C-D
221 LET E = 1
230 REM FOR F = 1 TO P
231 LET F = 1
240 REM FOR G = 1 TO P-F
241 LET G = 1
250 GOSUB 2000
260 IF S = 0 THEN GOTO 460
270 PRINT "SOLVED!"
280 PRINT "SMALL YELLOW APPLES:", C
290 PRINT "BIG YELLOW APPLES:", D, "*"
300 PRINT "BIG GREEN APPLES:", E
310 PRINT "BIG YELLOW PEARS:", F
320 PRINT "BIG GREEN PEARS:", G
400 END
460 REM NEXT G
461 LET G = G+1
462 IF G <= P-F THEN GOTO 250
470 REM NEXT F
471 LET F = F+1
472 IF F <= P THEN GOTO 240
480 REM NEXT E
481 LET E = E+1
482 IF E <= A-C-D THEN GOTO 230
490 REM NEXT D
491 LET D = D+1
492 IF D <= A-C THEN GOTO 220
500 REM NEXT C
501 LET C = C+1
502 IF C <= A THEN GOTO 210
510 PRINT "NO SOLUTION!"
520 END
1990 REM ** CHECK ROUTINE **
2000 LET S = 0
2001 REM PRINT C, D, E, F, G
2010 REM 25 APPLES, 17 PEARS
2020 IF C + D + E <> A THEN RETURN
2030 IF F + G <> P THEN RETURN
2040 REM 32 BIG FRUITS
2050 IF D + E + F + G <> B THEN RETURN
2060 REM 28 YELLOW ONES
2070 IF C + D + F <> Y THEN RETURN
2080 REM THERE ARE TWO MORE GREEN APPLES THAN GREEN PEARS
2090 IF E <> G + 2 THEN RETURN
2100 REM ** SOLVED! **
2110 LET S = 1
2990 RETURN
Ogni volta che ho a che fare con Tiny BASIC, inizialmente mi stupisco del fatto che questo dialetto non preveda i cicli FOR…NEXT. Questo in realtà non è un grosso problema, in quanto si può ovviare con le (meno eleganti) istruzioni di IF e GOTO. Un’altra limitazione è data dai nomi delle variabili, che possono essere costituiti da un’unica lettera maiuscola.
Ho eseguito il programma “Mele e Pere” su TinyBasicBlazor, l’ambiente TinyBASIC interattivo per web browser da me realizzato a partire da TinyBasic.NET e descritto in questo post. La soluzione ha richiesto più di mezz’ora (devo verificare il motivo), mentre con TinyBasic.NET in versione console, sono necessari pochi secondi.
Ah, quasi dimenticavo: ci sono 7 mele grandi e gialle!
SMALL YELLOW APPLES: 10
BIG YELLOW APPLES: 7 *
BIG GREEN APPLES: 8
BIG YELLOW PEARS: 11
BIG GREEN PEARS: 6