sabato 29 giugno 2019

Quesito con la Susi n. 960

Susi si imbuca ad una festa di compleanno di una certa Anna e per sentirsi più a suo agio decide di fingere di volerla conoscere. Gianni, sapendo di questa sua intenzione, raggiunge il gruppetto dei bambini in festa, fa la conoscenza di Anna e istruisce lei e le sue amiche per far cadere Susi nella solita trappola.

Ignara di tutto ciò, Susi va verso le bambine impegnate in un girotondo. Curioso, pensa tra sé, che abbiano delle magliette con dei numeri impressi; forse stanno facendo un gioco a squadre!

Quando è a portata di voce chiede: «Chi di voi è Anna?»

La bambina con la maglietta col numero 1 risponde: «Sono io!»

Logico: la festeggiata ha la numero uno.

Purtroppo per Susi le altre bambine ridacchiano «È vicino a me» mentre continuano a saltellare in tondo tenendosi per mano. Susi a questo punto è confusa. Gianni sbuca fuori da un cespuglio e le spiega che solo una bambina dice la verità.

«Susi, prova a richiederglielo» la incoraggia Gianni trattenendo un sorriso beffardo.

Prima di rispondere le bambine ricompongono il cerchio cambiandosi di posizione. La maglietta numero uno di nuovo sostiene di essere Anna e le altre bambine ripetono: «È vicino a me!»

Gianni spiega a Susi che anche questa volta quattro bambine mentono e aggiunge che quella che dice la verità non è la stessa di prima.

Dài Susi, adesso puoi dirmi qual è il numero sulla maglietta di Anna.

Soluzione “automatica”

Supponiamo che ogni volta Anna sia una delle bambine e contiamo quante affermazioni risultano vere per ciascuna delle due configurazioni di girotondo. La bambina che dice la verità è solo una, quindi se ci sono più affermazioni vere, scartiamo l’ipotesi.

Proviamo in PHP.1

// mappe di prossimità
$proxmap1 = array(2 => [1, 3],
                  3 => [2, 4],
                  4 => [3, 5],
                  5 => [4, 1]);

$proxmap2 = array(5 => [1, 2],
                  2 => [5, 3],
                  3 => [2, 4],
                  4 => [3, 1]);


function count_true($chi, $m)
{
    echo "** se Anna e' $chi ...\n";
    $c = $chi == 1 ? 1 : 0;
    $vera = null;    
    if ($chi == 1) {
        echo "La 1 dice il vero\n";
        $vera = 1;
    }
    foreach ($m as $k => $v) {
        if (in_array($chi, $v)) {
            $c++;
            echo "$k si trova vicina a $chi\n";
            $vera = $k;
        }
    }
    if ($c > 1) {
        $vera = null;
    }
    echo "\n";
    return array($c, $vera);
}

for ($b = 1; $b <= 5; $b++) {
    echo "===== configurazione 1\n";
    $c1 = count_true($b, $proxmap1);
    if ($c1[0] > 1) {
        echo "NON puo' essere\n\n\n";
        continue;
    }
    echo "\nforse forse...";
    echo "\n\n===== configurazione 2\n";
    $c2 = count_true($b, $proxmap2);
    if ($c2[0] > 1) {
        echo "NON puo' essere\n\n\n";
        continue;
    }
    echo "\nci siamo...?\n";
    $diversi = isset($c1[1]) && isset($c2[1]) &&
             ($c1[1] != $c2[1]);
    if ($diversi) {
        echo "Si'! Anna e' $b\n";
        break;
    } else {
        echo "\nno, falso allarme!\n\n";
    }
}

Nel codice l’aggiunta del controllo sul fatto che chi dice il vero nella prima configurazione non può essere chi dice il vero nella seconda configurazione è posticcia: nella prima stesura l’avevo tralasciato… e il risultato è lo stesso e unico 😄

Perché dunque è stata data un’informazione che non serve ad eliminare delle ambiguità?

Probabilmente serve per aiutare a trovare la soluzione “a mano”…? In effetti, volendo…

Soluzione “a mano”

Chi dice il vero nella prima configurazione del girotondo non può essere chi dice il vero nella seconda.

Quindi Anna non è la bambina con la maglietta col numero uno (se dice il vero la prima volta, mente la seconda, o viceversa; dalla contraddizione che ne risulta deduciamo che non può essere lei Anna).

Se nella prima configurazione la 2 dicesse la verità, Anna sarebbe la 3. Ma nella seconda configurazione la 2 si trova vicino alla 3. Quindi la 2 non può dire la verità nella prima configurazione. E la 3 non può essere Anna.

Se nella prima configurazione la 5 dicesse la verità, Anna sarebbe per forza la 4. Nella seconda configurazione la 5 non è vicino alla 4, quindi, se Anna fosse la 4, nella seconda configurazione la 5 starebbe mentendo, come atteso. Ma Anna non può essere nemmeno la 4 perché allora sarebbe la 3 a dire due volte la verità (3 e 4 si trovano vicine nelle due configurazioni).

Ci restano solo due candidate per Anna: la 2 e la 5. Se fosse la due, però, la 3 direbbe la verità in tutte e due le configurazioni, e ciò non è possibile.

Quindi Anna deve essere la 5.

Verifichiamo: nella prima configurazione è la 4 a dire il vero, e nella seconda configurazione è la 2, che nella prima mente, così come mente la 4 nella seconda.

Tutto torna, forse non nel modo più lineare per come l’ho dedotto… Forse c’è un modo più diretto e meno contorto di arrivare alla soluzione, o di spiegarla.

Comunque… In questo arzigogolo ho sfruttato il fatto che chi dice il vero nella prima configurazione deve mentire nella seconda.

Il programma suscritto, senza il controllo posticcio, prova che si perviene ad una unica soluzione anche ignorando questa informazione e usando solo il fatto che in tutte e due le configurazioni solo una bambina dice il vero.

Il programma scrive sullo standard output dei testi che servono a mostrare il “ragionamento” che possiamo benissimo imitare andando a contare le affermazioni vere nell’ipotesi che Anna sia una volta una bambina, una volta un’altra.

  • Supponiamo che Anna sia la 1
    • 1 affermazione vera (dalla 1 stessa)
    • La 2 e la 5 nella prima configurazione dicono il vero
    • Nella prima configurazione ci sono 3 affermazioni vere ⇒ Anna non può essere la 1 (non ci scomodiamo a verificare la seconda configurazione)
  • Supponiamo che Anna sia la 2
    • La 3 nella prima configurazione dice il vero ⇒ 1 affermazione vera
    • La 3 e la 5 nella seconda configurazione dicono il vero
    • Nella seconda configurazione ci sono 2 affermazioni vere ⇒ Anna non può essere la 2
  • Supponiamo che Anna sia la 3
    • Due affermazioni vere nella prima configurazione ⇒ Anna non può essere la 3
  • Supponiamo che Anna sia la 4
    • Due affermazioni vere nella prima configurazione ⇒ Anna non può essere la 4
  • Supponiamo che Anna sia la 5
    • 1 affermazione vera nella prima configurazione (da parte della 4)
    • 1 affermazione vera nella seconda configurazione (da parte della 2)

Anna deve essere la 5.

Non abbiamo avuto bisogno del vincolo sul fatto che l’affermazione vera non debba essere detta dalla stessa bambina nelle due configurazioni.

Possiamo comunque usarla per scartare almeno la prima supposizione. (E, ricordando il primo ragionamento2, anche la 3 e la 4.)

Eventuali correzioni su sviste o errori sostanziali sono sempre benvenute nei commenti.


  1. L’evidenziazione della sintassi è cambiata con una version di pandoc più recente rispetto a quella che usavo prima, e sembra che sia peggiorata — secondo loro è migliorata. Guardando l’HTML che genera per il sorgente, si vede che c’è molto più rumore, che tra l’altro mi ha costretto ad aggiornare il CSS… Nuove “feature” non richieste, attive di default e non disattivabili… Bah. Invece di highlighting-kate ora usa il suo successore skylighting, che comunque parte dai file XML di KDE per generare il codice che fa il parsing, che poi viene compilato nel programma… Buono per le performance, pessimo per la configurabilità. Tanto che, avendo modificato il php.xml (che per qualche misterioso motivo assegna lo stile di keyword alle variabili), ho dovuto ricompilare il programma. Avendo inizialmente installato dei precompilati di pandoc (che incorporano questo skylighting), ho dovuto ricompilare anche pandoc, una versione dinamica che usa lo skylighting installato… La modifica all’XML del PHP è commitata sul fork di skylighting.↩︎

  2. La 1 non può dire il vero perché altrimenti direbbe il vero entrambe le volte; quindi la 1 non può essere Anna. Ora supponiamo che la 2 dica la verità. Allora Anna deve essere la 3; ma allora la 2 direbbe la verità due volte. Ecc. Insomma ho fatto ipotesi su chi dice la verità per trarre delle conclusioni sfruttando ampiamente proprio il vincolo della “doppia verità”.↩︎

Nessun commento:

Posta un commento

Sii educato, costruisci con cura le frasi, rifletti prima di pubblicare, evita parolacce e offese dirette, non uscire dal tema, cerca di non omettere la punteggiatura, evita errori ortografici, rileggi quel che hai scritto.