ANSI C: giocare con la numerazione binaria per indovinare l’eta’

tavole per indovinare l'etàDiversi anni fa, ero alla ricerca di spunti divertenti e non troppo banali per insegnare agli allievi di un corso di programmazione in ANSI C
come funziona il sistema di numerazione binaria. Ho trovato su un vecchio libretto di curiosità matematiche un gioco per indovinare l’età attraverso l’utilizzo di tavole “magiche”. Va premesso che, ovviamente le tavole non sono magiche e vedremo il perché, e che per limiti di spazio, il gioco funziona solo per età inferiori ai 32 anni (la mia versione arriva a 64). Il gioco consiste nell’individuare la propria età in ciascuna delle colonne della figura a fianco, e segnare in quale di queste è presente. Mettiamo che individuate la vostra età nelle colonne 1,3,4,5 la vostra età è 29 anni.
Vediamo come sono composte le colonne, partendo da sinistra: la prima colonna è una serie di numeri dispari da 1 a 31, la seconda coppie alterne, la terza quadruple alterne, la quarta ottuple alterne e così via. A questo punto si intuisce che la tabella è un sistema per convertire i numeri decimali in cifre binarie, dove la prima colonna corrisponde a 20 nel sistema posizionale binario,
la seconda a 21, la terza a 22 e così via. Per calcolare l’età, quindi, basta sommare le intestazioni delle colonne dove essa viene individuata.
La stringa individuata, indicando con 1 e con 0 rispettivamente la presenza e l’assenza, e nel caso di 29 anni è 10111 che rovesciata da 11101 ovvero il numero 29 in notazione binaria. E’ necessario capovolgere la stringa perché, nella numerazione posizionale, la prima colonna si deve trovare a destra.

Questo è il codice in linguaggio C per l’implementazione del gioco. (Per comodità di costruzione dell’algoritmo, le colonne sono state trasposte in righe)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include 
#include 
 
int main(int argc, char *argv[])
{
  int i,j,a,b,tabella[6][32],anni=0;
  char risposta[6];    
  a=1;  
  tabella[0][0]=1;  
  for (i=0;i<6;i++){      
      printf("\nriga %d:\t",i+1);
      b=1;            
      for (j=0;j<32;j++){ if (j==0){ tabella[i][j]= a;} else {tabella[i][j] = tabella[i][j-1]+1;} if (b>a){
             tabella[i][j] = tabella[i][j] + a;
             b=1;   
          }                           
          printf("%2d ",tabella[i][j]);
          if (!((j+1)%16)) printf("\n\t");
          b++;                   
      }      
      a=a<<1;      
  }    
  printf("\nIn quale di queste righe e' presente la tua eta'?\n");  
  printf("\n(immettere: p.e. 110010 per indicare riga1, riga2, riga5)? ");      
  gets(risposta);      
  for (i=0;i<6;i++){ switch (i){ case 0: if (risposta[i]!='0') anni++; break; case 1: if (risposta[i]!='0') anni+=2; break; case 2: if (risposta[i]!='0') anni+=4; break; case 3: if (risposta[i]!='0') anni+=8; break; case 4: if (risposta[i]!='0') anni+=16; break; case 5: if (risposta[i]!='0') anni+=32; break; default: anni=-1; } } if (anni>0) printf ("\n Tu hai %d anni!\n",anni);
  else printf("\n hai sbagliato ad immettere i dati!\n");
  return 0;
}

output del programma per indovinare l'età

Notate che ho aggiunto la riga 6 (che corrisponde a 25) per avere a disposizione un range di età fra 1 e 63 anni.

Nella figura a fianco, l’output del programma per la mia età…

Più che la reale comprensione del giochino, forse la difficoltà maggiore si incontra nel strutturare l’algoritmo per la costruzione della tabella, io l’ho risolto così: un paio di cicli annidati e una serie di costrutti condizionali. Ho usato anche un operatore bit a bit per l’incremento della variabile a, nei casi di moltiplicazione *2 (shift a sinistra) è estremamente veloce!
Mi aspetto che ci siano altri modi anche più compatti, a voi il divertimento! (fatemi sapere…)

Download (compilato per win32): indovina.exe

Conclusioni:

Vi consiglio di evitare di proporre il giochino a matematici o esperti informatici che scopriranno subito il meccanismo, a parte questo mi sembra un esercizio divertente per rispolverare qualche reminiscenza di C, un linguaggio oggi forse un po’ in disuso ma da sempre un caposaldo della programmazione.

Riferimenti ed approfondimenti: