Alla TV francese danno un programma TV che si intitola Des chiffres et des lettres in cui i concorrenti si sfidano a risolvere sia giochi di parole che di aritmetica. Uno dei giochini si intitola Le compte est bon: vengono dati alcuni numeri, e un numero obiettivo, e lo scopo è di ottenere l’obiettivo (o avvicinarcisi il più possibile) applicando le quattro operazioni aritmetiche alla serie di iniziale numeri.
Per capire di cosa si tratta, facciamo subito un piccolo esempio: dati i numeri 5, 100, 6, 3, 10 e 1, bisogna cercare di ottenere il numero 635 utilizzando soltanto le quattro operazioni +, -, * e /.
Una possibile sequenza che porta alla soluzione è:
5+100 = 105; 6*105 = 630; 3-1 = 2; 10/2 = 5; 630+5 = 635;
Come vedete, non è poi molto difficile, ma bisogna perderci un attimo di tempo a provare un po’ di combinazioni.
Viene fuori che la maestra di mio figlio, che frequenta la CM2 (quinta elementare) qui in Francia, propone questo tipo di esercizi per allenare i ragazzini a fare i conti. Divertente, no? Non l’avevo mai visto fare in Italia, ma può darsi che mi sbagli, se seguite questo blog e ne sapete di più sugli esercizi che vengono dati in quinta elementare in Italia, scrivetelo nei commenti! A questo sito trovare parecchi esercizi simili per tutte le classi delle elementari.
Fatto sta che qualche giorno fa, mio figlio si presenta con questa sequenza: 1, 2, 5, 10, 25, 50
, e il numero da ottenere era 668
. Non riusciva a trovare la soluzione, e voleva sapere se potevo trovarla io.
Dopo averci pensato qualche secondo, gli ho detto che secondo me non c’era soluzione. “Forse ho sbagliato a copiare qualche numero”, mi risponde lui, “ma mi sembrava di aver ricopiato attentamente dalla lavagna”.
Come sapere se c’è o no soluzione al problema? Beh, da buon ingegnere, ho pensato che il modo migliore era di scrivere un programmino che provasse tutte le combinazioni. Con 5 numeri non dovrebbero essere tantissime. Ovviamente, essendo un problema semplice, il modo veloce di risolverlo era usare il Python, il mio lignuaggio di fast-prototyping preferito ormai.
Volete provarci da soli? Allora non guardate il programma seguente.
import copy import argparse numeri = [5, 100, 6, 3, 10, 1] soluzione = 635 def elimina(i, lista): l = [] l = copy.copy(lista[:i]) l = l + copy.copy(lista[(i+1):]) return l def operazione(lista, sol, ops, ris, operazione, a, b): l3 = copy.copy(lista) l3.append(ris) op = ops + str(a) + operazione + str(b) + ' = ' + str(ris) + '; ' calcola(l3, sol, op) def calcola(lista, sol, ops): if len(lista) == 1: if lista[0] == sol: print "TROVATO! ", ops else: n = lista[0] l = elimina(0, lista) for i, x in enumerate(l): l2 = elimina(i, l) n1 = n + x operazione(l2, sol, ops, n1, '+', n, x) n1 = n - x operazione(l2, sol, ops, n1, '-', n, x) n1 = x - n operazione(l2, sol, ops, n1, '-', x, n) n1 = n * x operazione(l2, sol, ops, n1, '*', n, x) if x != 0 and n % x == 0: n1 = n / x operazione(l2, sol, ops, n1, '/', n, x) if n != 0 and x % n == 0: n1 = x / n operazione(l2, sol, ops, n1, '/', x, n) def main(): parser = argparse.ArgumentParser(description='Inserisci i numeri') parser.add_argument('nums', nargs='+', default=numeri) parser.add_argument('--s', default=soluzione) args = parser.parse_args() num = [int(x) for x in args.nums] sol = int(args.s) print num, ' ??? ', sol calcola(num, sol, "") if __name__ == "__main__": main()
E lanciando il programma si ottengono… ben 2 risultati!
[1, 2, 5, 10, 25, 50] ??? 668 TROVATO! 10-1 = 9; 2+5 = 7; 25+50 = 75; 9*75 = 675; 675-7 = 668; TROVATO! 1-25 = -24; 2+5 = 7; 10*50 = 500; -24*7 = -168; 500--168 = 668; TROVATO! 25-1 = 24; 2+5 = 7; 10*50 = 500; 24*7 = 168; 500+168 = 668;
La seconda in realtà coinvolge dei numeri negativi, quindi andrebbe eliminata. E quindi aveva ragione mio figlio e torto io. Mai contare troppo sulle proprie doti matematiche!
Il programma l’ho scritto un po’ di fretta e non è il massimo dello stile, e non sono neanche completamente sicuro che sia corretto. E quindi, per chi volesse esercitarsi, ho tre domande a diverso grado di difficoltà:
- Sapete modificare il programma per evitare che stampi soluzioni negative?
- E se voleste memorizzarle tutte le soluzioni in un vettore per riutilizzarle dopo?
- Infine, sapete dimostrarne la correttezza?
Dimenticavo: ovviamente, un programma analogo è disponibile in linea qui.
Ah, questi francesi!