Kürzlich bei Puzzling.SE gab es ein Problem, das ich darüber schrieb, welche zwei Flaschen einer größeren Anzahl vergiftet sind, wenn das Gift nur aktiviert wird, wenn beide Komponenten getrunken sind. Es war eine ziemliche Tortur, und die meisten Menschen schafften es, es mit völlig anderen Algorithmen auf 18 oder 19 Gefangene zu bringen.
Die ursprüngliche Problemstellung lautet wie folgt:
Sie sind der Herrscher eines mittelalterlichen Königreichs, das gerne Partys veranstaltet. Der Höfling, der beim letzten Mal versucht hat, eine Ihrer Weinflaschen zu vergiften, war wütend darüber, dass Sie mit nur zehn Gefangenen herausgefunden haben, welche Flasche er von 1.000 vergiftet hat.
Diesmal ist er ein bisschen schlauer. Er hat ein zusammengesetztes Gift entwickelt
P
: eine binäre Flüssigkeit, die nur dann tödlich ist, wenn sich zwei einzeln harmlose Komponenten mischen. Das funktioniert ähnlich wie Epoxy. Er hat Ihnen eine weitere Kiste mit 1.000 Weinflaschen geschickt. Eine Flasche hat eine KomponenteC_a
und eine andere hat eine KomponenteC_b
. (P = C_a + C_b
)Jeder, der beide Komponenten trinkt, stirbt um Mitternacht in der Nacht, in der er die letzte Komponente getrunken hat, unabhängig davon, wann er am Tag die Flüssigkeit getrunken hat. Jede Giftkomponente bleibt im Körper, bis die zweite Komponente aktiviert wird. Wenn Sie also an einem Tag eine Komponente und am nächsten eine andere Komponente trinken, sterben Sie am Ende des zweiten Tages um Mitternacht.
Sie haben zwei Tage vor Ihrer nächsten Party. Wie viele Gefangene müssen Sie mindestens testen, um festzustellen, welche zwei Flaschen befallen sind, und welchen Algorithmus müssen Sie bei dieser Anzahl von Gefangenen anwenden?
Bonus
Angenommen, Sie hatten ein festes Limit von 20 Gefangenen zur Verfügung. Wie viele Flaschen konnten Sie theoretisch maximal testen und zu einer genauen Schlussfolgerung gelangen, welche Flaschen betroffen waren?
Ihre Aufgabe ist es, ein Programm zur Lösung des Bonusproblems zu erstellen. Angesichts von n
Gefangenen erstellt Ihr Programm einen Testplan, der es ermöglicht, die beiden vergifteten Flaschen in m
Flaschen zu finden, m
sofern diese so groß wie möglich sind.
In Ihrem Programm wird zunächst N
die Anzahl der Gefangenen als Eingabe verwendet . Es wird dann ausgegeben:
M
, die Anzahl der Flaschen, die Sie testen möchten. Diese Flaschen werden von1
bis etikettiertM
.N
Linien, die die Etiketten der Flaschen enthalten, die jeder Gefangene trinkt.
Ihr Programm nimmt dann als Eingabe, welche Gefangenen am ersten Tag gestorben sind, wobei der Gefangene in der ersten Zeile 1
, die nächste Zeile 2
usw. ist. Dann gibt es Folgendes aus:
N
Weitere Zeilen mit den Etiketten der Flaschen, die jeder Gefangene trinkt. Tote Gefangene haben leere Zeilen.
Ihr Programm nimmt dann als Eingabe, welche Gefangenen am zweiten Tag gestorben sind, und gibt zwei Zahlen aus, A
und B
stellt dar, welche zwei Flaschen Ihres Programms das Gift enthalten.
Eine Beispieleingabe für zwei Gefangene und vier Flaschen könnte als solche gelten, wenn Flaschen 1
und 3
vergiftet sind:
> 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.
Der Testplan Ihres Programms muss jedes mögliche Paar vergifteter Flaschen erfolgreich ermitteln, damit es eine gültige Einreichung ist.
Ihr Programm wird nach folgenden Kriterien bewertet:
Die maximale Anzahl Flaschen, die für den Fall erkannt werden kann
N = 20
.Die Anzahl der Flaschen für den Fall
N = 21
und nacheinander höhere Fälle danach.Die Länge des Codes. (Kürzere Code gewinnt.)
quelle
Antworten:
Python 2.7.9 - 21 Flaschen
Unter der Annahme, dass ESultaniks Spekulationen zu Recht zutreffen, was der Input ist, wenn mehrere Gefangene sterben
Algorithmus: Jeder Gefangene trinkt von jeder Flasche bis auf seine Nummer (der erste Gefangene trinkt nicht die erste Flasche). Wenn sie nicht sterben, ist ihre Nummernflasche vergiftet. Überlebt nur ein Gefangener, ist die zusätzliche Flasche vergiftet.
quelle
Perl 5 , 66 Flaschen
(72 Flaschen für 21 Gefangene)
Die Gefangenen sind optimal in 2 Gruppen aufgeteilt. Die Flaschen sind in Sets zusammengefasst.
Jeder Gefangene der Gruppe 1 trinkt von allen Sätzen bis auf einen. Es wird 1 oder 2 Überlebende geben. Die 1 oder 2 Sätze, die nicht von ihnen getrunken wurden, werden bis Tag 2 fortgesetzt.
Am zweiten Tag trinken die verbleibenden Gefangenen (einschließlich der Überlebenden) von allen verbleibenden Flaschen bis auf eine.
Wenn 2 Gefangene überleben, sind die Flaschen, die sie nicht getrunken haben, vergiftet.
Wenn nur noch 1 Gefangener übrig ist, ist auch die Flasche, die sie alle getrunken haben, verdächtig.
Der Code enthält zusätzliche Funktionen, um das Testen zu erleichtern. Wenn die vergifteten Flaschen als zusätzliche Parameter hinzugefügt werden, werden Sie nicht gefragt, wer gestorben ist.
Prüfung
Test ohne manuelle Eingabe
quelle
Wie es Tradition ist, werde ich eine letzte Referenzantwort posten.
Python - 7 Flaschen
Lassen Sie jeden Gefangenen ein mögliches Paar Flaschen trinken, mit Ausnahme der letzten beiden. Wenn ein Gefangener stirbt, war das Paar, das dieser Gefangene getrunken hat, das vergiftete. Ansonsten waren es die letzten beiden Flaschen, die vergiftet wurden.
Für Zuteilungen von mindestens
n(n-1)/2 - 1
Gefangenen können Sie bis zun
Flaschen tun . Dennn = 7
diese Untergrenze liegt bei20
.Wir brauchen eigentlich nur einen Tag, damit diese Lösung funktioniert. Eine zweitägige Lösung mit einem ähnlichen Anwendungsbereich kann bis zu 20 Flaschen kosten
N = 20
, ist aber für eine triviale Antwort zu aufwändig.quelle