Hintergrund
Nonogram , auch bekannt als Picross oder Griddlers, ist ein Puzzle, bei dem das Ziel darin besteht, anhand der Anzahl aufeinanderfolgender farbiger Zellen in jeder Zeile zu bestimmen, ob jede Zelle im 2D-Raster farbig oder leer sein soll.
Das folgende Beispiel zeigt ein Nonogramm-Puzzle mit einer Lösung.
Das Problem ist, dass einige kommerzielle Nonogram-Spiele / mobile Apps Rätsel haben, die nicht von Hand lösbar sind (z. B. mehrere Lösungen haben oder tiefes Backtracking erfordern). Sie bieten dem Spieler jedoch auch einige Leben, bei denen ein Leben verloren geht, wenn Sie versuchen, eine Zelle zu färben, deren richtige Antwort leer ist . Jetzt ist es an der Zeit, diese fiesen "Rätsel" zu lösen!
Um die Aufgabe zu vereinfachen, stellen Sie sich nur eine Zeile mit dem Hinweis und nichts anderes vor:
3 7 | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Das [3,7]
sind die Hinweise, und die Zeilenlänge beträgt 15 Zellen. Da es mehrere mögliche Lösungen gibt, müssen wir einige Leben riskieren, um diese Linie vollständig zu lösen (dh alle farbigen Zellen bestimmen).
Herausforderung
Bestimmen Sie anhand einer Linie mit Hinweisen (einer Liste positiver Ganzzahlen) und der Linienlänge die maximale Anzahl an Leben, die Sie verlieren werden, vorausgesetzt, Sie erzwingen die Linie mit optimaler Strategie.
Beachten Sie, dass Sie immer farbige Zellen erraten . In tatsächlichen Spielen hat das Erraten leerer Zellen (richtig oder falsch) keine Auswirkung auf Ihr Leben, sodass Sie das Rätsel nicht auf diese Weise "lösen" können.
Sie können auch davon ausgehen, dass die Eingabe immer eine gültige Nonogram-Zeile darstellt, sodass Sie sich nicht um etwas kümmern müssen [6], 5
.
Erläuterung
Schauen wir uns zunächst einige einfachere Beispiele an.
[1,2], 5
Für diese Zeile gibt es genau drei Möglichkeiten ( O
ist eine farbige Zelle, .
ist eine leere):
O . O O .
O . . O O
. O . O O
Wenn wir versuchen, Zelle 0 einzufärben (0-basierter Index von links), geschieht Folgendes:
- Die Zelle ist richtig gefärbt. Jetzt haben wir zwei Möglichkeiten, und wir können zwischen Zelle 2 und Zelle 4 wählen, um die Linie vollständig zu lösen. In beiden Fällen verlieren wir im schlimmsten Fall ein Leben.
- Die Zelle ist leer und wir verlieren ein Leben. In diesem Fall haben wir bereits die einzigartige Lösung für diese Linie identifiziert, sodass wir mit 1 verlorenen Leben fertig sind.
Daher [1,2], 5
lautet die Antwort für 1.
[5], 10
Binäre Suche? Nee.
Die naheliegendste erste Wahl ist 4 oder 5, was eine Möglichkeit aufzeigt, wenn sie leer ist (bei einem Preis von 1 Leben). Nehmen wir an, wir haben zuerst 4 gewählt. Wenn Zelle 4 tatsächlich farbig ist, verlängern wir sie nach links, dh versuchen Sie 3, 2, 1 und 0, bis ein Leben verloren geht (oder Zelle 0 farbig ist, geben wir am Ende überhaupt keine Leben aus). Wenn ein Leben verloren geht, können wir die Lösung eindeutig bestimmen, z. B. wenn wir so etwas sehen:
_ _ X O O _ _ _ _ _
Dann wissen wir bereits, dass die Antwort lautet:
. . . O O O O O . .
Daher [5], 10
lautet die Antwort für auch 1.
[3,7], 15
Beginnen Sie mit Zelle 11, die, wenn sie leer ist, sofort die folgende Lösung anzeigt.
O O O . O O O O O O O X . . .
Dann versuchen Sie es mit 12, was, wenn leer, zwei Möglichkeiten ergibt, die auf Kosten von 1 zusätzlichen Leben gelöst werden können.
O O O . . O O O O O O O X . .
. O O O . O O O O O O O X . .
Versuchen Sie nun 2. Wenn leer, ergeben sich drei Möglichkeiten, die ähnlich wie im [1,2], 5
Beispiel gelöst werden können .
. . X O O O . O O O O O O O .
. . X O O O . . O O O O O O O
. . X . O O O . O O O O O O O
Wenn Sie das Risiko auf diese Weise weiter minimieren, können Sie jede Lösung mit max. 2 Leben verbracht.
Testfälle
[1,2] 5 => 1
[2] 5 => 2
[1] 5 => 4
[] 5 => 0
[5] 10 => 1
[2,1,5] 10 => 0
[2,4] 10 => 2
[6] 15 => 2
[5] 15 => 2
[4] 15 => 3
[3,7] 15 => 2
[3,4] 15 => 3
[2,2,4] 15 => 4
[1,1,1,1,1,1,1] 15 => 2
[2,1,1,3,1] 15 => 3
[1,1,1,2,1] 15 => 5
In den letzten beiden Fällen durchläuft die optimale Strategie nicht die minimalen Lücken, sondern geht einfach von links nach rechts (oder von rechts nach links). Vielen Dank an @crashoz für den Hinweis.
Regeln
Es gelten die Standardregeln für Code-Golf . Die kürzeste gültige Übermittlung in Bytes gewinnt.
Kopfgeld
Wenn jemand einen Algorithmus für die Polynomzeit (mit dem Beweis der Korrektheit) findet, werde ich eine solche Lösung mit +100 Kopfgeld belohnen.
quelle
[6], 5
?Antworten:
Ruby , 85 Bytes
Probieren Sie es online!
Erläuterung
Hier ist ein Beispiel
_
unbekannt,X
ist ein bekannter Raum,O
ist eine bekannte farbige Zelle undL
ist Leben verlorenquelle
Python,
303289 BytesDas erste Golfspiel seit langer Zeit, daher kann es zu viel Fettüberschuss kommen. (Danke, Jo King, für das Auffinden von 14 Bytes.)
Die Funktion f generiert alle möglichen Anordnungen (allerdings immer mit einem Leerzeichen als erstem Zeichen, aber das ist in Ordnung, solange wir die Länge um 1 erhöhen, bevor wir sie aufrufen). Funktion g wählt die Position mit der geringsten Anzahl von Leerzeichen und Rekursionen aus. Funktion h fügt sie zusammen.
Die Beispiele laufen alle gut:
quelle
False
zu0
? Wenn ja, können Sie ändern ,(len(q)>1)*1and
zulen(q)>1and
. Wenn Sie nicht zurückkehrenFalse
zu0
, dann das tun, aber änderng(f(l,n+1),n+1)
zu1*g(f(l,n+1),n+1)
und es wird immer noch speichert eine ByteFalse
ist nicht erlaubt für0
, statt Wechselg(f(l,n+1),n+1)
zu1*g(f(l,n+1),n+1)
, ändern Sie ihn auf+g(f(l,n+1),n+1)
h=
Bytes nicht zählen