Kürzlich an der neu veröffentlichten Puzzling.SE , gab es ein Problem , über Spione Steine in einen Fluss werfen , die eigentlich recht war eine Herausforderung:
Zwei Spione müssen sich zwei geheime Nummern geben (eine Nummer pro Spion), die ihre Feinde nicht bemerken. Sie haben sich auf eine Methode geeinigt, bei der nur 26 nicht unterscheidbare Steine im Voraus verwendet werden.
Sie treffen sich an einem Fluss, wo sich ein Stapel von 26 Steinen befindet. Beginnend mit dem ersten Spion werfen sie abwechselnd eine Gruppe Steine in den Fluss: Der erste Spion wirft einige Steine, dann den zweiten, dann den ersten wieder ...
Jeder Spion muss mindestens einen Stein werfen, bis alle Steine verschwunden sind.
Sie beobachten alle Würfe und gehen auseinander, wenn es keine Steine mehr gibt. Sie schweigen die ganze Zeit und es werden keine Informationen ausgetauscht, außer die Anzahl der Steine, die in jeder Runde geworfen werden.
Wie können sie die Nummern erfolgreich austauschen, wenn die Nummern von 1 bis M sein können?
Ihre Aufgabe ist es, ein Paar von Programmen zu bauen, spy1
und spy2
, dass dieses Problem für die höchstmögliche lösen kann M
.
Ihre Programme nehmen jeweils eine Nummer von 1
zu Ihrer Wahl M
als Eingabe. Anschließend spy1
wird eine Zahl ausgegeben, die die Anzahl der Steine darstellt, die in den Fluss geworfen werden. Diese spy2
Zahl wird eingegeben spy1
, und es wird auch eine Zahl ausgegeben, in die eingegeben werden soll , usw., bis sich die ausgegebenen Zahlen summieren 26
. Am Ende des Wurfs gibt jedes Programm die Nummer aus, von der es glaubt, dass sie das andere Programm hatte, die mit der Nummer übereinstimmen muss, die tatsächlich in das andere Programm eingegeben wurde.
Ihr Programm muss für alle möglichen geordneten Zahlenpaare funktionieren, (i, j)
wobei beide i
und j
von 1
bis variieren können M
.
Das Programm, das für das größte Programm funktioniert M
, ist der Gewinner, und die erste Antwort wird als Unentschieden gemeldet. Zusätzlich werde ich eine Reputationsprämie von +100 für die erste Lösung vergeben, die nachweislich funktioniert M >= 2286
, und +300 für die erste Lösung, die nachweislich funktioniert M >= 2535
.
Antworten:
C #, M = 2535
Dies implementiert das System, das ich mathematisch in dem Thread beschrieben habe, der diesen Wettbewerb provoziert hat. Ich beanspruche den 300 Wiederholungsbonus. Das Programm führt einen Selbsttest durch, wenn Sie es entweder ohne Befehlszeilenargumente oder
--test
als Befehlszeilenargument ausführen . für Spion 1 laufen mit--spy1
und für Spion 2 mit--spy2
. In jedem Fall nimmt es die Nummer, die ich von stdin mitteilen soll, und führt dann die Würfe über stdin und stdout aus.* Tatsächlich habe ich eine Optimierung gefunden, die einen großen Unterschied macht (von einigen Minuten zum Generieren des Entscheidungsbaums bis zu weniger als einer Sekunde). Der Baum, den es erzeugt, ist im Grunde derselbe, aber ich arbeite immer noch an einem Beweis dafür. Wenn Sie eine direkte Implementierung des Systems wünschen, das ich an anderer Stelle beschrieben habe, lesen Sie Revision 2 , obwohl Sie möglicherweise die zusätzliche Protokollierung von
Main
und die bessere Kommunikation zwischen Threads von zurückportieren möchtenTestSpyIO
.Wenn Sie einen Testfall wünschen, der in weniger als einer Minute abgeschlossen ist, wechseln Sie
N
zu16
undM
zu87
.Anweisungen für Linux-Benutzer
Sie müssen
mono-csc
kompilieren (auf Debian-basierten Systemen ist es immono-devel
Paket enthalten) undmono
ausführen (mono-runtime
Paket). Dann sind die Beschwörungsformelnetc.
quelle
yum install mono-core
(als Root). 2.dmcs Puzzle625.cs
3.mono Puzzle625.exe --test
Python-Tester-Programm
Ich denke, es wäre nützlich, ein Testprogramm zu haben, das überprüfen kann, ob Ihre Implementierung funktioniert. Die beiden folgenden Skripte funktionieren entweder mit Python 2 oder Python 3.
Testerprogramm (
tester.py
):Protokoll: Die beiden in der Befehlszeile angegebenen Spionageprogramme werden ausgeführt. Es wird erwartet, dass sie nur über stdin / stdout interagieren. Jedes Programm erhält seine zugewiesene Nummer als erste Eingabezeile. In jedem Zug gibt Spion 1 die Anzahl der Steine aus, die geworfen werden sollen, Spion 2 liest eine Zahl aus dem Standardwert (der den Wurf von Spion 1 darstellt) und wiederholt sie dann (mit umgekehrten Positionen). Wenn einer der beiden Spione feststellt, dass 26 Steine geworfen wurden, halten sie an und geben ihre Schätzung für die Nummer des anderen Spions ab.
Beispielsitzung mit einem kompatiblen Spion1 (
>
kennzeichnet die Eingabe für den Spion)Wenn Sie einen sehr großen M wählen, und es dauert zu lange laufen, können Sie schalen
test(
fürtestrand(
in der letzten Zeile zufällige Tests auszuführen. Im letzteren Fall lassen Sie das Programm mindestens einige tausend Versuche laufen, um Vertrauen aufzubauen.Beispielprogramm (
spy.py
) für M = 42:Anwendungsbeispiel:
quelle
Java, M = 2535
OK, hier ist meine Implementierung. Bei jedem Schritt macht ein Spion eine Bewegung. Jede mögliche Bewegung repräsentiert eine Reihe von Codes. Der Spion wählt den Zug, der seinem Geheimcode entspricht. Wenn sie mehr Steine werfen, verringert sich die Reichweite der möglichen Codes, bis am Ende für beide Spione nur noch ein Code möglich ist, je nach den von ihnen ausgeführten Zügen.
Um die Geheimcodes wiederherzustellen, können Sie alle Züge wiederholen und die entsprechenden Codebereiche berechnen. Am Ende bleibt nur ein Code für jeden Spion, das ist der Geheimcode, den er senden wollte.
Leider basiert der Algorithmus auf einer großen vorberechneten Tabelle mit hunderttausenden ganzen Zahlen. Die Methode konnte vielleicht nicht mit mehr als 8-10 Steinen mental angewendet werden.
Die erste Datei implementiert den Algorithmus von Spy. Der statische Teil berechnet vorab eine
codeCount
Tabelle, die später zur Berechnung jeder Bewegung verwendet wird. Im zweiten Teil werden zwei Verfahren implementiert, eines zum Auswählen der Anzahl der zu werfenden Steine und das andere zum Wiederholen von Zügen, um die Wiederherstellung der Geheimcodes zu unterstützen.Die zweite Datei testet die Spy-Klasse ausgiebig. Die Methode
simulate
simuliert den Prozess. Es verwendet die Spy-Klasse, um eine Folge von Würfen aus den Geheimcodes zu generieren, und rekonstruiert dann die Codes aus der Folge.Spy.java
ThrowingStones.java
Als Referenz enthält das vorberechnete codeCount-Array die folgenden Werte:
Dies bezog sich direkt auf Peter Taylors Tk-Sets. Wir haben:
quelle
range
Felder zu teilen . Aber ich bin sehr fasziniert von Ihrer Methode zur Berechnung der Tabelle. Haben Sie einen Richtigkeitsnachweis? Und sind Sie daran interessiert, an einem Papier mitzuarbeiten, in dem das Problem erörtert und dessen Lösung berechnet wird?ksh / zsh, M = 126
In diesem einfachen System wirft jeder Spion Binärziffern an den anderen Spion. Bei jedem Wurf wird der erste Stein ignoriert, die nächsten Steine sind jeweils Bit 0 und der letzte Stein ist Bit 1. Wenn ein Spion beispielsweise 20 wirft, wirft er 4 Steine (ignoriere, 0, 2, addiere 4). wirf dann 3 Steine (ignoriere, 8, addiere 16), denn 4 + 16 = 20.
Die Zahlenreihe ist nicht zusammenhängend. 0 bis 126 sind in, aber 127 ist out. (Wenn beide Spione 127 haben, brauchen sie 28 Steine, aber sie haben 26 Steine.) Dann sind 128 bis 158 im Spiel, 159 sind im Spiel, 160 bis 174 sind im Spiel, 175 sind im Spiel, 176 bis 182 sind im Spiel, 183 sind im Spiel. 184 bis 186 sind drin, 187 sind draußen und so weiter.
Führen Sie einen automatischen Tausch mit
ksh spy.sh 125 126
oder einzelne Spione mitksh spy.sh spy1 125
und ausksh spy.sh spy2 126
. Hierksh
kann ksh93, pdksh oder zsh sein.BEARBEITEN 14. Juni 2014: Behebung eines Problems mit einigen Co-Prozessen in zsh. Sie würden für immer untätig bleiben und nicht verlassen, bis der Benutzer sie tötete.
quelle