Einführung
Seit vielen Jahrhunderten gibt es einen bestimmten Fluss, der nie kartiert wurde. Die Gilde der Kartographen möchte eine Karte des Flusses erstellen, es ist ihnen jedoch nie gelungen - aus irgendeinem Grund wurden alle Kartographen, die sie zur Kartierung des Flusses geschickt haben, von wilden Tieren in der Gegend gefressen. Ein anderer Ansatz ist erforderlich.
Eingabebeschreibung
Die Fläche ist ein rechteckiges Gitter aus Zellen mit Länge m
und Breite n
. Die Zelle links unten 0,0
und die Zelle rechts oben wäre m-1,n-1
. m
und n
werden in der Eingabe als Tupel bereitgestellt m,n
.
Mit Hilfe von geografischen Fernerkundungstechniken wurde der Standort von Inseln am Fluss identifiziert. Die Größe der Inseln (dh wie viele Zellen die Insel belegt) wurde ebenfalls identifiziert, die Form jedoch nicht. Wir liefern diese Informationen in einem Tupel, s,x,y
in dem s
die Größe der Insel x
und y
die x- und y-Position einer bestimmten Zelle dieser Insel angegeben sind. Jedes Tupel in der Eingabe ist durch Leerzeichen getrennt. Hier ist ein Beispiel für eine Eingabe:
7,7 2,0,0 2,3,1 2,6,1 2,4,3 2,2,4 8,0,6 1,2,6 3,4,6
Zur besseren Veranschaulichung sehen Sie hier die Eingabe in einem Diagramm:
y 6|8 1 3
5|
4| 2
3| 2
2|
1| 2 2
0|2
=======
0123456
x
Ausgabebeschreibung
Geben Sie eine Karte mit ASCII-Zeichen aus, um Teile des Bereichs darzustellen. Jede Zelle wird entweder #
(Land) oder .
(Wasser) sein. Die Karte sollte diese Regeln befolgen:
- Definition. Eine Insel ist eine orthogonal zusammenhängende Gruppe von Landzellen, die vollständig von Flusszellen und / oder der Grenze des Gebiets begrenzt wird.
- Definition. Ein Fluss ist eine orthogonal zusammenhängende Gruppe von Wasserzellen, die vollständig von Landzellen und / oder der Grenze des Gebiets begrenzt ist und keine "Seen" enthält (2x2 Gebiete von Wasserzellen).
- Regel . Die Karte muss genau einen Fluss enthalten.
- Regel . Jede nummerierte Zelle in der Eingabe muss Teil einer Insel sein, die genau
s
Zellen enthält. - Regel . Jede Insel in der Karte muss genau eine der nummerierten Zellen in der Eingabe enthalten.
- Regel . Für jede Eingabe gibt es eine einzige eindeutige Zuordnung.
Hier ist die Ausgabe der Beispieleingabe:
#.#.##.
#....#.
#.##...
##..##.
###....
...##.#
##....#
Hier ist ein weiterer Ein- und Ausgang.
Eingang:
5,5 3,0,1 1,4,1 2,0,4 2,2,4 2,4,4
Ausgabe:
#.#.#
#.#.#
.....
###.#
.....
quelle
javascript:(_=>{var t=Game.nurikabe().task,m=t.length,n=t[0].length,s=[m,n];for(var i=0;i<m;i++)for(var j=0;j<n;j++)if(t[i][j]>=0)s+=' '+[t[i][j],i,j];puzzleContainerDiv.insertAdjacentHTML('beforeend','<hr><tt style=color:red>'+s+'</tt><hr>')})();void(0)
Antworten:
C + PicoSAT ,
2345995952 BytesProbieren Sie es online!
(Warnung: Bei diesem TIO-Link handelt es sich um eine 30-Kilobyte-URL, die eine verkleinerte Kopie von PicoSAT 965 enthält. Daher können Sie diese möglicherweise in einigen Browsern nicht laden, sie wird jedoch in mindestens Firefox und Chrome geladen.)
Wie es funktioniert
Wir initialisieren den SAT-Löser mit einer Variablen für jede Zelle (Land oder Wasser) und nur den folgenden Einschränkungen:
Die restlichen Einschränkungen lassen sich nur schwer direkt in SAT codieren. Stattdessen führen wir den Solver aus, um ein Modell zu erhalten, führen eine Folge von Tiefensuchen durch, um die verbundenen Bereiche dieses Modells zu finden, und fügen zusätzliche Einschränkungen wie folgt hinzu:
Dank der inkrementellen Schnittstelle zur PicoSAT-Bibliothek können wir den Solver einschließlich der hinzugefügten Einschränkungen sofort erneut ausführen, wobei alle vorherigen Schlussfolgerungen des Solvers erhalten bleiben. PicoSAT gibt uns ein neues Modell und wir wiederholen die obigen Schritte, bis die Lösung gültig ist.
Das ist bemerkenswert effektiv; Es löst 15 × 15 und 20 × 20 Instanzen in einem winzigen Sekundenbruchteil.
(Vielen Dank an Lopsy , der diese Idee vorgeschlagen hat, verbundene Bereiche in einem inkrementellen SAT-Solver vor einiger Zeit interaktiv einzuschränken .)
Einige größere Testfälle von puzzle-nurikabe.com
Eine zufällige Seite mit 15 × 15 Puzzles ( 5057541 , 5122197 , 5383030 , 6275294 , 6646970 , 6944232 ):
Eine zufällige Seite mit 20 × 20 normalen Puzzles ( 536628 , 3757659 ):
quelle
GLPK , (nicht konkurrierend) 2197 Bytes
Dies ist ein nicht konkurrierender Eintrag
Ich werde hier eine noch unbespielte, aber funktionierende Version retten. Je nach Feedback kann ich versuchen, es zu verkürzen und eine Erklärung hinzuzufügen, wenn Interesse besteht. Bisher dienen die Einschränkungsnamen als In-Place-Dokumente.
Die Hauptidee besteht darin, die Einschränkung "zusammenhängende Inseln" zu codieren, indem eine beibehaltene Flussvariable eingeführt wird, die eine vordefinierte Quelle an der Hinweisposition hat. Die Entscheidungsvariable
is_island
spielt dann die Rolle von platzierbaren Senken. Durch die Minimierung der Gesamtsumme dieses Flusses werden die Inseln gezwungen, im Optimum verbunden zu bleiben. Die anderen Einschränkungen implementieren die verschiedenen Regeln eher direkt. Was mich verwirrt, dass ich noch zu brauchen scheineisland_fields_have_at_least_one_neighbor
.Die Leistung dieser Formulierung ist jedoch nicht großartig. Wenn Sie die gesamte Komplexität mit einer großen Anzahl von Einschränkungen direkt verarbeiten, benötigt der Solver für das 15 x 15-Beispiel fast 15 Sekunden.
Code (noch nicht bespielt)
Problemdaten
5 x 5
7 x 7
15 x 15
Verwendung
Haben
glpsol
installiert, Modell als eine Datei (zBriver.mod
), Eingangsdaten in separater Datei (en) (zB7x7.mod
). Dann:Dies und etwas Geduld werden die Lösung im angegebenen Ausgabeformat (zusammen mit "einigen" Diagnoseausgaben) ausgeben.
quelle
Python 3 , 1295 Bytes
Dies ist eine reine Python-Lösung. Es verwendet keine Bibliotheken und lädt die Karte über die Standardeingabe. Weitere Erklärung zu kommen. Dies ist mein erster Versuch, einen so großen Golf zu spielen. Unten befindet sich ein Link zum kommentierten und nicht golfenen Code.
Probieren Sie es online!
Schauen Sie sich den Code ohne Golf an .
quelle