[Un GRANDE Grazie a Stefano Saraulli per aver suggerito diverse modifiche a questo articolo]
Sembrava un programma semplice. “Trovare le coppie in una lista di numeri che danno come somma un certo valore noto”. Ma metà dei test ancora non passano, il codice non scala, è lento – e la deadline è tra pochi minuti: “Come posso evitare di fare un doppio for?“
È una serata di Coding organizzata da ++it. Come atleti delle arti marziali, programmatori di ogni linguaggio ed esperienza si incontrano nel Dojo per affinare le loro capacità di “lottare” contro domande di questo tipo. Stiamo organizzando queste serate da circa due mesi. Vorrei raccontarvi qualcosa in più su quest’iniziativa perché, sebbene sia nata come esperimento, ora sta diventando una vera e propria attività della nostra community.
L’idea iniziale era quella di organizzare delle competizioni di coding, riprendendo il concetto comunemente chiamato Competitive Programming. Il format doveva essere qualcosa del tipo:
- i partecipanti si iscrivono, in anticipo, su un portale
- risolvono gli esercizi nel tempo a disposizione (eventualmente a squadre)
- al termine viene premiato il vincitore .
Quello che non ci ha convinto è che il “valore aggiunto” è ben poco rispetto all’esperienza che già si può trovare comodamente online su portali come TopCoder o HackerRank. L’idea di fare una competizione dal vivo è interessante, ma volevamo spingerci oltre, riflettendo sul potenziale che questi incontri avrebbero potuto avere.
Da competizione a collaborazione
Abbiamo capito che la competizione non avrebbe dato quel “qualcosa in più”. L’abbiamo allora trasformata in collaborazione. Il format dei nostri incontri è diventato una declinazione di quello che da diversi anni è conosciuto come Code Retreat:
- i partecipanti si iscrivono, in anticipo, su un portale
- scelgono dei linguaggi con i quali vorrebbero programmare
- si formano liberamente delle coppie, magari in base alle preferenze di linguaggio
- si risolve un esercizio, in un certo tempo limite (intanto noi giriamo tra le coppie dando supporto/feedback)
- scaduto il tempo moderiamo una retrospettiva per discutere le possibili soluzioni
- si cambiano le coppie e si torna al punto 2.
Vi spiego i vari passaggi raccontandovi com’è andata, circa un mese fa, a Modena, quando siamo stati ospitati dall’Associazione Conoscere Linux, che ci ha messo a disposizione una sala PC (i partecipanti quindi si sono tenuti leggeri, senza aver bisogno di un portatile).
Quello che ho chiamato “portale” è HackerRank.com, uno dei siti di Competitive Programming più importanti in circolazione. HackerRank permette di creare gratuitamente dei contest con esercizi risolvibili in qualsiasi linguaggio e direttamente nel browser – non serve altro per partecipare. Una volta scritto il programma, il sito lo verifica tramite dei test-case (input e output atteso) preimpostati da noi. Il “contest” per noi è solo una raccolta di esercizi da proporre, la competizione, ripeto, è assente.
Aperta la serata con una breve introduzione, abbiamo mostrato HackerRank e alcuni esempi di funzionamento. A questo punto i partecipanti si sono messi a coppie in base alla preferenza di linguaggi oppure in base al fattore “ehi, ma non ti vedevo da un sacco di tempo!“. Ci siamo dati circa 30 minuti per risolvere ogni esercizio.
Le prove hanno una componente algoritmica importante, ma per affrontarle non occorre conoscere tecniche avanzate o strutture dati di nicchia. Quello che serve è ragionare da programmatori: riflettendo sui vincoli, sul dominio, su input/output, eccetera.
Ad esempio, un esercizio consisteva nel trovare il numero più frequente in una sequenza di interi (quella che in statistica è comunemente chiamata moda). In caso di più risultati “a pari merito”, andava stampato il valore numericamente più piccolo. Ad esempio:
5 10 10 11 16 20 20 25
10 e 20 appaiono due volte, ma 10 è numericamente più piccolo e quindi quello da stampare.
Questo esercizio, sebbene semplice, ha una componente su cui ragionare: in caso di più risultati, stampare l’elemento più piccolo. Tutti i partecipanti hanno usato una struttura dati associativa tipo una mappa o un dizionario per contare le occorrenze. Poi hanno scritto un loop per cercare la più frequente, gestendo anche la particolarità sul pareggio. Affrontare questo aspetto non è stato per tutti banale. I linguaggi usati sono stati Python, Ruby e Javascript. La nostra soluzione in C++ era la più breve di tutte e non usava mappe! Non la rivelo così potete pensarci 🙂
Durante la risoluzione degli esercizi, i partecipanti facevano domande e chiedevano supporto. Chiaramente non volevamo “sbottonarci” troppo e quindi cercavamo di trasformare le loro domande in altre più specifiche. Ad esempio, un partecipante, davvero brillante, è ad un passo dalla soluzione, ma vede fallire metà dei suoi test per timeout (il codice era troppo lento): “Come posso evitare di fare un doppio for?” Cercando di “allontanarlo” da un algoritmo quadratico, abbiamo risposto: “Quali ricerche efficienti conosci su una sequenza?“. Ha capito e ha ordinato la sequenza effettuando poi una ricerca binaria ad ogni step del loop. Il suo codice è diventato O(N log N) e tutti i test sono diventati verdi!
Infine, la fase di retrospettiva nasce sempre da qualche partecipante che si offre di raccontare la sua soluzione. Noi moderiamo la discussione e – alla fine – mostriamo la nostra versione in C++. Questa fase è importante perché si discute di tutto: dai possibili miglioramenti algoritmici, alle varianti del problema, fino ad arrivare al design e all’estensibilità delle soluzioni date. Nascono sempre tanti spunti importanti. Ad esempio, nell’esercizio della moda ci siamo posti domande sullo spazio a disposizione in memoria, oppure se convenga usare una struttura dati particolare nel caso in cui ci siano tantissimi duplicati. Per il futuro stiamo pensando di aumentare il tempo dedicato alla discussione e di preparare in anticipo alcune riflessioni sull’esercizio in questione.
L’obiettivo dei nostri incontri
Torniamo un attimo al passaggio mentale dietro la soluzione del doppio for. E’ stata bello vedere la reazione, la soddisfazione, del nostro concorrente al passaggio di tutti i test! Ma la grande soddisfazione nell’aver trovato una soluzione efficiente non è fine a se stessa, non si esaurisce al termine dell’esercizio. Essa fa parte di un processo mentale molto più importante: l’aumento della consapevolezza delle proprie abilità.
L’obiettivo delle nostre serate è dare spunti ai partecipanti affinché, allenandosi, aumentino la consapevolezza delle proprie abilità di programmatori, a prescindere dalla tecnologia utilizzata. Spunti vicini, piuttosto, a concetti che sono alla base del nostro mestiere. Tale consapevolezza può essere alimentata solo con la pratica. Spesso il lavoro diventa routine, poco stimolante. Cimentarsi in problemi di programmazione nuovi e alternativi è un modo creativo per rompere la quotidianità e diventare più consapevoli dei propri mezzi. Gli stessi mezzi che torneranno utili nel lavoro quotidiano.
Prossimo incontro: Martedì 26 Aprile a Modena
Il nostro prossimo incontro è previsto per Martedì 26 Aprile a Modena, ancora una volta ospitati dall’Associazione Conoscere Linux. Questo il link ufficiale per iscrizioni e indicazioni su come arrivare. Come ho detto vorremmo rendere questi incontri delle attività ricorrenti della community quindi ne organizzeremo altri. Se siete interessati a collaborare e magari ospitarci nella vostra città/università/scuola/user group/ecc scriveteci!