Di recente su Puzzling.SE, ho scritto un problema per determinare quali due bottiglie di un numero maggiore sono avvelenate quando il veleno si attiva solo se entrambi i componenti sono ubriachi. Alla fine è stato un vero calvario, con la maggior parte delle persone che è riuscita a farlo arrivare a 18 o 19 prigionieri usando algoritmi completamente diversi.
La dichiarazione del problema originale è la seguente:
Sei il sovrano di un regno medievale che ama organizzare feste. Il cortigiano che ha tentato di avvelenare una delle tue bottiglie di vino l'ultima volta è stato furioso di apprendere che sei riuscito a identificare quale bottiglia aveva avvelenato su 1.000 con solo dieci prigionieri.
Questa volta è un po 'più furbo. Ha sviluppato un veleno composito
P
: un liquido binario che è mortale solo quando due componenti individualmente innocui si mescolano; questo è simile a come funziona la resina epossidica. Ti ha inviato un'altra cassa da 1.000 bottiglie di vino. Una bottiglia ha componenteC_a
e un'altra ha componenteC_b
. (P = C_a + C_b
)Chiunque beva entrambi i componenti morirà nel colpo di mezzanotte della notte in cui ha bevuto il componente finale, indipendentemente da quando nel giorno hanno assorbito il liquido. Ogni componente velenoso rimane nel corpo fino all'attivazione del secondo componente, quindi se bevi un componente un giorno e un altro componente il successivo, morirai a mezzanotte alla fine del secondo giorno.
Hai due giorni prima della prossima festa. Qual è il numero minimo di prigionieri che è necessario utilizzare per i test al fine di identificare quali due bottiglie sono contaminate e quale algoritmo è necessario seguire con quel numero di prigionieri?
Bonus
Inoltre, supponiamo che tu abbia un limite fisso di 20 prigionieri a tua disposizione, qual è il numero massimo di bottiglie che potresti teoricamente testare e giungere a una conclusione accurata su quali bottiglie sono state colpite?
Il tuo compito è costruire un programma per risolvere il problema del bonus. Dati i n
prigionieri, il tuo programma elaborerà un programma di test che sarà in grado di rilevare le due bottiglie avvelenate tra le m
bottiglie, dove m
è il più grande possibile.
Il tuo programma inizialmente prenderà come input il numero N
, il numero di prigionieri. Verrà quindi emesso:
M
, il numero di bottiglie che proverai a testare. Queste bottiglie saranno etichettate da1
aM
.N
linee, contenenti le etichette delle bottiglie che ogni prigioniero berrà.
Il tuo programma prenderà quindi come input quali prigionieri sono morti il primo giorno, con il prigioniero in prima linea essendo 1
, la linea successiva essendo 2
, ecc. Quindi, produrrà:
N
più righe, contenenti le etichette delle bottiglie che ogni prigioniero berrà. I prigionieri morti avranno righe vuote.
Il tuo programma prenderà quindi come input quali prigionieri sono morti il secondo giorno, e produrrà due numeri A
e B
, rappresentando quali due bottiglie il tuo programma ritiene contenga il veleno.
Un input di esempio per due prigionieri e quattro bottiglie potrebbe andare come tale, se le bottiglie 1
e 3
sono avvelenate:
> 2 // INPUT: 2 prisoners
4 // OUTPUT: 4 bottles
1 2 3 // OUTPUT: prisoner 1 will drink 1, 2, 3
1 4 // OUTPUT: prisoner 2 will drink 1, 4
> 1 // INPUT: only the first prisoner died
// OUTPUT: prisoner 1 is dead, he can't drink any more bottles
3 // OUTPUT: prisoner 2 drinks bottle 3
> 2 // INPUT: prisoner 2 died
1 3 // OUTPUT: therefore, the poisoned bottles are 1 and 3.
The above algorithm may not actually work in all
cases; it's just an example of input and output.
Il programma di test del programma deve determinare con successo ogni possibile coppia di flaconi avvelenati affinché sia valida.
Il tuo programma verrà valutato in base ai seguenti criteri, in ordine:
Il numero massimo di bottiglie che può discernere per il caso
N = 20
.Il numero di bottiglie per il caso
N = 21
e successivamente casi più elevati.La lunghezza del codice. (Il codice più corto vince.)