Verso la fine di novembre, sul solito socialino di nicchia dove già l'anno passato avevo scoperto l'esistenza di Advent of Code, abbiamo cominciato a parlare della possibilità di lanciarsi nell'impresa anche quest'anno. Inizialmente pensavo di non avere tempo di partecipare: troppo lavoro, e troppe ore passate davanti allo schermo a occuparsi del bosone di Higgs, mi avevano convinto che quest'anno non ce l'avrei fatta. Ovviamente sono bastati tre o quattro giorni passati a leggere degli altri amici immaginari che risolvevano i primi quesiti e che discutevano delle strategie scelte, a trascinarmi nel gorgo dei puzzle di programmazione di AOC. Non ci sono molte cose che danno più "dipendenza" di una serie di enigmi logico-matematici da risolvere in fretta, conditi con un pizzico di competizione tra amici, ma soprattutto dal supporto reciproco in caso di difficoltà, e dalla possibilità di comparare e discutere le rispettive soluzioni.
Sull'esperienza di Advent of Code ho già scritto parecchio l'anno passato, e molte delle considerazioni fatte in quell'occasione sono ancora valide oggi. Ne aggiungo qualcuna dopo l'esperienza di questo annus horribilis 2020, a completare quanto già detto un anno fa. Se non avete nessuna idea di che cosa sia Advent of Code, l'articolo sull'edizione del 2019 è un buon punto di partenza per capire di cosa io stia parlando.
- Gli enigmi di quest'anno erano più facili di quelli dell'anno passato. Forse sono io ad essere migliorato, tanto nell'uso di Python che nella soluzione dei problemi, ma penso di poter dire senza sbagliare troppo che la difficoltà media dei problemi del 2020 era inferiore a quella di quelli del 2019. In parte la cosa è legata all'assenza di un filo conduttore, che invece c'era l'anno scorso: nessun problema richiedeva di aver risolto un problema dei giorni precedenti per avanzare, cosa che invece l'anno passato era un aspetto ben presente: questo ha certamente facilitato l'impresa.
- Ho imparato meno che l'anno passato. In parte per l'oggettiva maggiore facilità degli enigmi del 2020 di cui sopra, in parte grazie all'esperienza accumulata duramente l'edizione dell'anno passato. Se nel 2019 mi ero dovuto confrontare con il fatto che, in quanto fisico, c'erano aspetti teorici dell'informatica o ambiti della matematica che non conoscevo per niente (penso per esempio agli algoritmi di ricerca e navigazione di grafi e alberi, essenziali per esempio per navigare un labirinto; o, per quanti riguarda la matematica, all'algebra modulare o alla teoria dei numeri), quest'anno non posso dire di avere imparato molti approcci veramente nuovi per risolvere i problemi. Provando a fare un elenco (probabilmente non completo) delle nuove conoscenze che mi porto a casa dopo aver completato AOC 2020, ci trovo queste cose:
- Alcune tecniche di Python che non avevo mai usato prima: l'uso delle funzioni lambda, o come fare una matrice numpy di oggetti generici come una lista;
- Il teorema cinese del resto, usato per risolvere il problema del tredicesimo giorno;
- Le regular expression, la cui bieca ignoranza fino a un mese fa ammetto senza troppa vergogna, e che senza l'uso delle quali trovare la soluzione al problema del giorno 19 sarebbe stato impossibile;
- Una cosa che ho poi scoperto a posteriori chiamarsi linked list, ovvero l'idea di una collezione "ricursiva" di oggetti, come in un anello, in cui quello che conta non è tanto la posizione assoluta di ogni membro, quanto quella relativa, ovvero chi segue chi, e come la catena cambi nel tempo.
Non è male, ma non è nemmeno moltissimo.
- L'assenza di un tema ricorrente, di cui mi ero un po' lamentato l'anno passato, mi è invece pesata un po'. A posteriori, la dipendenza di alcuni problemi del 2019 dalla soluzione dei problemi dei giorni precedenti dava all'avventura un senso di unità e continuità che nel 2020 non ho invece provato. Sebbene la cosa rendesse certe soluzioni del 2019 complesse e laboriose, nel completarle tutte avevo provato un senso di soddisfazione ben maggiore. La stessa considerazione vale per la presenza nel 2019 di enigmi la cui soluzione necessitava l'uso ricorrente di una stessa classe di algoritmi - nel 2019 c'erano per esempio spesso labirinti da risolvere - cosa che all'epoca per esempio mi aveva obbligato a imparare diversi modi di risolvere lo stesso problema in contesti diversi - nel caso specifico, approcci come come breadth-first search, o algoritmi di Dijkstra e A*, di cui prima non sapevo veramente nulla!
- Ho giocato molto meno con l'aspetto visivo delle soluzioni. In parte non tutti i problemi del 2020 si prestavano a esperimenti di visualizzazione, ma è stata soprattutto la disponibilità limitata di tempo "libero" (ricordate? All'inizio nemmeno volevo partecipare...) a portarmi a "risolvere e basta" molti problemi, senza investire più tempo del dovuto nell'animare anche una visualizzazione della soluzione.
- Insegnare a un computer a risolvere un problema apparentemente semplice (per un umano) può essere un'impresa complessa. La cosa è stata chiarissima per il problema del giorno 20, quello che quest'anno mi ha dato più filo da torcere, e che richiedeva per la sua seconda parte di risolvere un puzzle, inteso questa volta proprio nel senso più comune del dover ricomporre una figura fatta da tessere i cui lati combaciano. Che istruzioni si danno a un computer per dirgli di risolvere un puzzle? Cerca gli angoli e i bordi, e inizia dall'esterno? Prova tutte le tessere e le loro possibili orientazioni fino a che trovi quelle che combaciano? Una procedura che potrebbe sembrare banale persino per un bambino, si rivela invece una sequenza complessa di operazioni, verifiche e decisioni che modificano e influenzano quali altre operazioni eseguire in seguito. Molto spesso diamo per scontata la flessibilità del nostro cervello nel risolvere problemi complessi, adattando in maniera fluida le nostri azioni a quello che osserviamo. Programmare un comportamento simile in un computer, oltre a essere difficile, è stata per me una lezione di umiltà rispetto a quello che la nostra mente sa fare, o può facilmente imparare a fare.
- La persona dietro ad Advent of Code, Eric Wastl, fa un lavoro veramente impressionante, che è sorgente di divertimento e occasione di scambio e apprendimento per tanti. Per questo, quest'anno ho deciso di fargli una piccola donazione: mi è sembrato il minimo per ringraziarlo per le ore di di divertimento che AOC mi ha regalato. Se vi interessa sapere qualcosa di più su cosa sta dietro le quinte dell'evento, vi consiglio la visione di questo video: la storia della genesi di AOC è interessante, la comunità che si è formata intorno agli enigmi natalizi ancora di più.
- La comunità, in effetti, è la cosa migliore di Advent of Code. Certamente quella della manciata di amici immaginari del socialino di nicchia, ma anche quella estesa su reddit, sempre pronta a dare un aiuto o un suggerimento, o anche solo a condividere soluzioni mille volte migliori delle mie, dalle quali imparare come si possa risolvere lo stesso problema in maniera molto più elegante di come io possa mai aver pensato. Se mai ce ne fosse bisogno, mi pare una bella dimostrazione che, perlomeno in certe nicchie, la rete può ancora essere qualcosa di simile a quello per cui è stato immaginata ai suoi albori.
- La mia paura di non avere tempo si è rivelata infondata, e c'è una lezione da imparare. Ho affrontato praticamente tutti gli enigmi di AOC 2020, tranne gli ultimi a ridosso di Natale, tra le 8 e le 9 del mattino dei giorni di dicembre, dopo aver portato Giulia a scuola, ed essere tornato a casa per telelavorare in questi tempi di sconfinamento pandemico. Avrei potuto usare quel tempo mi modo diverso? Certo! Decine di email e messaggi Skype a cui rispondere mi aspettavano ogni giorno, e spesso la prima riunione (virtuale) era prevista per le 9. Ho lavorato meno o peggio a causa di quel tempo dedicato a risolvere enigmi? Non credo, anzi, sono praticamente certo che la cosa mi abbia fatto bene, e reso capace di lavorare meglio e di relazionarmi in modo più sereno con chi mi stava intorno, che fossero colleghi o la famiglia. La verità è che sentirci freneticamente occupati, privi della possibilità di dedicare un po' di tempo allo svago o a coltivare una passione che sia non legata a lavoro o famiglia, è spesso una scusa che ci fa magari sentire bene, utili e indispensabili nell'immediato, ma che non ci rende persone migliori. Come direbbe il capitano Picard:
Come già per l'edizione dell'anno passato, tutte le mie soluzioni sono raccolte in questa repository di GitHub, con qualche appunto raccolto in questo sommario, e delle note più estese in ognuno dei notebook. Non esitate a farmi sapere che cosa ne pensate!
juhan dice
Una curiosità? Python (e i packages scientifici come SciPy, NumPy, MathPlotLib &co) li usi anche per lavoro?
Bello pubblicare il codice e i commenti.
Marco dice
Si, anche se non tanto quanto vorrei. Di fatto da solo (o con quelle librerie) lo uso soprattutto come strumento per analisi dati veloci, mentre per robe più complesse python è soprattutto un'interfaccia da e verso ROOT (tramite pyroot o uproot) per usare cose come RooFit, oppure librerie di machine learning come Keras o Tensorflow
Marco dice
(per codice e commenti, su GitHub ci sono anche le soluzioni dell'anno scorso: se le guardi mi dirai se ti sembra che sia migliorato o meno, perché io ho sempre l'impressione di usare python come se fosse c++ senza i punti-e-virgola 🙂 )
zoomx dice
E senza la tipizzazione delle variabili, la cosa che mi manca di più.
juhan dice
A un confronto veloce tra il 2019 e il 2020 mi sembra che c'è del nuovo (list comprehension p.es): non si finisce mai di imparare!
Soluzioni di AOC ne trovi (ed è il bello) di typi diversi da chi sta cominciando e chi ormai è un nerd finito e dovrebbe forse cambiare linguaggio --avendo tempo. Però Python usato con i packages scientifici e i componenti ML è --secondo me-- quel che ci vuole.
Anche se, in un ambito diverso trovi cose come questa: https://twitter.com/samth/status/1345118036504825858
Potrebbe essere anche peggio, p.es Java.
Marco dice
Oh, ma sei andato veramente a vedere? Mitico!
Comunque si, quest'anno meno loop for e uno sforzo di avere una scrittura più "pythonica".
Sul migliore linguaggio per insegnare a programmare si potrebbe discutere, per esempio sulla vessata questione di strongly typed vs weakly typed e sull'utilità di usare un linguaggio dichiarativo oppure no (io penso che per chi impara da zero ed è molto giovane - elementari, medie - non serva, perché quello è il momento di capire i fondamentali e gli algoritmi, mentre dopo - livello universitario - sia utile e persino necessario per porsi delle questioni più tecniche per esempio sulla rappresentazione dei dati o sull'uso della memoria - allora roba come Java, C o C++ sono probabilmente più adatti).