Sie haben n
Münzen, von denen jede entweder -1 oder 1 wiegt. Jede ist mit 0
bis gekennzeichnet , n-1
damit Sie die Münzen voneinander unterscheiden können. Sie haben auch eine (magische) Waage. Bei der ersten Wende können Sie so viele Münzen wie Sie möchten auf die Waage legen, die sowohl negative als auch positive Gewichte messen kann und Ihnen genau sagt, wie viel sie wiegen.
Das Wägegerät hat jedoch etwas wirklich Merkwürdiges. Wenn Sie x_1, x_2, ..., x_j
das erste Mal Münzen auf das Gerät legen , müssen Sie das nächste Mal Münzen (x_1+1), (x_2+1) , ..., (x_j+1)
auf die Waage legen, mit der Ausnahme, dass Sie natürlich keine Münze mit einer höheren Nummer als einsetzen können n-1
. Darüber hinaus können Sie bei jedem neuen Wiegen auswählen, ob Sie auch eine Münze 0
auf die Waage legen möchten .
Was ist nach dieser Regel die kleinste Anzahl von Wägungen, die Ihnen immer genau sagen, welche Münzen 1 wiegen und welche -1 wiegen?
Es ist klar, dass Sie 0
in der ersten Runde einfach eine Münze auf das Gerät legen könnten und dann genau das n
Wägen erforderlich wäre, um das Problem zu lösen.
Sprachen und Bibliotheken
Sie können eine beliebige Sprache oder Bibliothek verwenden (die nicht für diese Herausforderung entwickelt wurde). Ich würde jedoch gerne in der Lage sein, Ihren Code nach Möglichkeit zu testen. Wenn Sie also klare Anweisungen zur Ausführung in Ubuntu geben können, wären Sie sehr dankbar.
Ergebnis
Für eine gegebene wird n
Ihre Punktzahl n
durch die Anzahl der Wägungen geteilt, die Sie im schlimmsten Fall benötigen. Höhere Werte sind daher besser. Es gibt keine Eingabe für dieses Rätsel, aber Ihr Ziel ist es, eine zu finden, n
für die Sie die höchste Punktzahl erzielen können.
Bei Gleichstand gewinnt die erste Antwort. In der äußerst unwahrscheinlichen Situation, in der jemand einen Weg findet, eine unendliche Punktzahl zu erzielen, gewinnt diese Person sofort.
Aufgabe
Ihre Aufgabe ist es einfach, Code zu schreiben, der die höchste Punktzahl erzielt. Ihr Code muss sowohl ein n geschickt auswählen als auch die Anzahl der Wägungen dafür optimieren n
.
Führende Einträge
4/37/5 in Python von Sarge Borsch- 26/14 in Java von Peter Taylor
quelle
x_i
: Wir können zum Beispiel eine erste Wägung von (x_1, x_2, x_3) = (3, 2, 7) haben, und dann kann die zweite Wägung entweder (4, 3, 8) oder ( 0, 4, 3, 8). Die Münzetiketten müssen nicht aufeinander folgen, und der Indexi
inx_i
bezieht sich nicht auf das Etikett der Münze.Antworten:
C ++, Score
23/1225/1327/1428/14 = 231/15Die Lösungen der Matrix-Eigenschaft X revisited (oder Joy of X) können direkt als Lösungen für dieses Problem verwendet werden. ZB die Lösung von 31 Zeilen, 15 Spalten:
Zeile N stellt dar, welche Münzen Sie für die Messung N auf die Waage legen. Unabhängig von den Ergebnissen der Gewichtung gibt es offensichtlich eine Reihe von Münzwerten, die dieses Gewicht ergeben. Wenn es auch eine andere Kombination gibt (die Lösung ist nicht eindeutig), überlegen Sie, wie sie sich unterscheiden. Sie müssen einen Satz Münzengewichtungen
1
durch Münzengewichtungen ersetzen-1
. Dies ergibt eine Reihe von Spalten, die diesem Flip entsprechen. Es gibt auch eine Reihe von Münzen Gewicht-1
, die Sie durch ersetzen1
. Das ist ein weiterer Satz von Spalten. Da sich die Messungen zwischen den beiden Lösungen nicht ändern, müssen die Spaltensummen der beiden Sätze gleich sein. Aber die Lösungen für Matrix-Eigenschaft X überarbeitet (oder die Freude an X) die genau in diesen Matrizen werden, in denen solche Spaltenmengen nicht existieren, sodass es keine Duplikate gibt und jede Lösung einzigartig ist.Jeder tatsächliche Satz von Messungen kann von einigen beschrieben werden
0/1
Matrix . Aber selbst wenn einige Spaltenmengen dieselben Vektoren ergeben, kann es sein, dass die Vorzeichen der Münzwerte der Kandidatenlösung nicht genau einer solchen Menge entsprechen. Ich weiß also nicht, ob Matrizen wie die oben genannte optimal sind. Aber zumindest bieten sie eine Untergrenze. So ist die Möglichkeit, dass 31 Münzen in weniger als 15 Messungen durchgeführt werden können, noch offen.Beachten Sie, dass dies nur für eine nicht festgelegte Strategie gilt, bei der Ihre Entscheidung, eine Münze
0
auf die Waage zu setzen, vom Ergebnis der vorherigen Gewichtung abhängt. Sonst Sie werden Lösungen, wo die Zeichen der Münzen mit den Sätzen entsprechen, die die gleiche Spaltensumme haben.quelle
Python 2, Punktzahl = 1,0
Dies ist die einfache Punktzahl, falls niemand eine bessere Punktzahl findet (zweifelhaft).
n
Wägungen für jedenn
.Ich habe importiert,
antigravity
damit das Programm mit negativen Gewichten arbeiten kann.quelle
antigravity
ist im Grunde genommen ein No-Op, oder?Score = 26/14 ~ = 1,857
Speichern als
LembikWeighingOptimisation.java
, Kompilieren alsjavac LembikWeighingOptimisation.java
, Ausführen alsjava LembikWeighingOptimisation
.Vielen Dank an Mitch Schwartz für den Hinweis auf einen Fehler in der ersten Version des Quick Reject.
Dies verwendet einige ziemlich grundlegende Techniken, die ich nicht konsequent rechtfertigen kann. Brute-Forces, aber nur zum Starten von Wiegevorgängen, bei denen höchstens die Hälfte der Münzen verwendet wird: Sequenzen, bei denen mehr als die Hälfte der Münzen verwendet wird, können nicht direkt auf die Zusatzwägungen übertragen werden (da das Gesamtgewicht nicht bekannt ist). Auf einer handgewellten Ebene sollte es jedoch ungefähr die gleiche Menge an Informationen geben. Es iteriert auch durch das Starten der Wägungen in der Reihenfolge der Anzahl der beteiligten Münzen, auf der Grundlage, dass es verteilte Wägungen abdeckt (die hoffentlich relativ früh Informationen über das obere Ende liefern), ohne zuerst durch einen Haufen zu kriechen, der mit einer dichten Teilmenge bei beginnt das untere Ende.
Die
MaskRange
Klasse ist eine massive Verbesserung gegenüber der früheren Version in Bezug auf die Speichernutzung und beseitigt den Engpass bei GC.quelle
Python 3,
Punktzahl = 4/3 = 1,33… (N = 4)Punktzahl = 1,4 (N = 7)Update: Brute-Force-Suche in "statischen" Lösungssätzen implementiert und neues Ergebnis erzielt
Ich denke, es kann weiter verbessert werden, indem nach dynamischen Lösern gesucht wird, die Gewichtungsergebnisse für weitere Entscheidungen verwenden können.
Hier ist ein Python-Code, der alle statischen Löser nach kleinen
n
Werten durchsucht (diese Löser wiegen immer die gleichen Münzsätze, daher der "statische" Name) und die Anzahl der Schritte im ungünstigsten Fall ermittelt, indem er einfach überprüft, ob die Messergebnisse nur eine übereinstimmende Münze zulassen in allen fällen eingestellt. Außerdem werden die bisher besten Ergebnisse und die frühen Pflaumenlöser protokolliert, die gezeigt haben, dass sie definitiv schlechter sind als diejenigen, die zuvor gefunden wurden. Dies war eine wichtige Optimierung, ansonsten konnte ich mitn
= 7 nicht auf dieses Ergebnis warten . (Aber es ist eindeutig immer noch nicht sehr gut optimiert)Sie können gerne Fragen stellen, wenn nicht klar ist, wie es funktioniert.
Die Ausgabe:
Diese Zeile
(StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4
deckt den besten gefundenen Löser auf. Die Zahlen in{}
Klammern sind die Indizes der Münzen, die bei jedem Schritt an der Wägevorrichtung angebracht werden müssen.quelle