introduction
Depuis plusieurs siècles, il y a une certaine rivière qui n'a jamais été cartographiée. La Guilde des Cartographes veut produire une carte de la rivière, cependant, ils n'ont jamais réussi à réussir - pour une raison quelconque, tous les cartographes qu'ils ont envoyés pour cartographier la rivière ont été mangés par des animaux sauvages de la région. Une approche différente est requise.
Description de l'entrée
La zone est une grille rectangulaire de cellules de longueur m
et de largeur n
. La cellule en bas à gauche serait 0,0
, et la cellule en haut à droite serait m-1,n-1
. m
et n
sont fournis dans l'entrée comme un tuple m,n
.
En utilisant des techniques de sondage géographique à longue distance, l'emplacement des îles autour du fleuve a été identifié. La taille des îles (c'est-à-dire le nombre de cellules occupées par l'île) a également été identifiée, mais pas la forme. Nous fournissons ces informations dans un tuple s,x,y
où s
est la taille de l'île et x
et y
sont les positions x et y d'une cellule particulière de cette île. Chaque tuple de l'entrée est séparé par des espaces, voici donc un exemple d'entrée:
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
Pour illustrer plus clairement, voici l'entrée sur un graphique:
y 6|8 1 3
5|
4| 2
3| 2
2|
1| 2 2
0|2
=======
0123456
x
Description de la sortie
Générez une carte en utilisant des caractères ASCII pour représenter des parties de la zone. Chaque cellule sera soit #
(terre) soit .
(eau). La carte doit suivre ces règles:
- Définition. Une île est un groupe de cellules terrestres contiguës orthogonalement qui est entièrement délimité par des cellules fluviales et / ou la frontière de la zone.
- Définition. Une rivière est un groupe de cellules d'eau contiguës orthogonalement qui est entièrement délimité par des cellules terrestres et / ou la frontière de la zone, et ne contient pas de «lacs» (2x2 zones de cellules d'eau).
- Règle . La carte doit contenir exactement une rivière.
- Règle . Chaque cellule numérotée dans l'entrée doit faire partie d'un îlot contenant exactement des
s
cellules. - Règle . Chaque île de la carte doit contenir exactement une des cellules numérotées dans l'entrée.
- Règle . Il existe une seule carte unique pour chaque entrée.
Voici la sortie de l'exemple d'entrée:
#.#.##.
#....#.
#.##...
##..##.
###....
...##.#
##....#
Voici une autre entrée et sortie.
Contribution:
5,5 3,0,1 1,4,1 2,0,4 2,2,4 2,4,4
Production:
#.#.#
#.#.#
.....
###.#
.....
la source
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)
Réponses:
C + PicoSAT ,
2345995952 octetsEssayez-le en ligne!
(Attention: ce lien TIO est une URL de 30 kilo-octets qui contient une copie minifiée de PicoSAT 965, donc vous ne pourrez peut-être pas le charger dans certains navigateurs, mais il se charge au moins dans Firefox et Chrome.)
Comment ça fonctionne
Nous initialisons le solveur SAT avec une variable pour chaque cellule (terre ou eau), et uniquement les contraintes suivantes:
Les autres contraintes sont difficiles à encoder directement dans SAT, nous exécutons donc le solveur pour obtenir un modèle, exécutons une séquence de recherches en profondeur d'abord pour trouver les régions connectées de ce modèle et ajoutons des contraintes supplémentaires comme suit:
Profitant de l'interface incrémentielle de la bibliothèque PicoSAT, nous pouvons immédiatement réexécuter le solveur, y compris les contraintes ajoutées, en préservant toutes les inférences précédentes faites par le solveur. PicoSAT nous donne un nouveau modèle, et nous continuons à répéter les étapes ci-dessus jusqu'à ce que la solution soit valide.
C'est remarquablement efficace; il résout 15 × 15 et 20 × 20 instances en une infime fraction de seconde.
(Merci à Lopsy d' avoir suggéré cette idée de contraindre de manière interactive les régions connectées dans un solveur SAT incrémentiel, il y a quelque temps.)
Quelques cas de test plus grands de puzzle-nurikabe.com
Une page aléatoire de 15 × 15 puzzles durs ( 5057541 , 5122197 , 5383030 , 6275294 , 6646970 , 6944232 ):
Une page aléatoire de 20 × 20 puzzles normaux ( 536628 , 3757659 ):
la source
GLPK , (non concurrent) 2197 octets
Il s'agit d'une entrée non concurrente, comme
Je vais enregistrer ici une version encore non golfée, mais fonctionnelle. Selon les commentaires, je pourrais essayer de le raccourcir + ajouter une explication s'il y a un intérêt. Jusqu'à présent, les noms de contraintes servent de documents sur place.
L'idée principale est de coder la contrainte des "îles contiguës" en introduisant une variable de flux préservée qui a une source prédéfinie à l'emplacement de l'indice. La variable de décision
is_island
joue alors le rôle de puits placables. En minimisant la somme totale de ce flux, les îles sont obligées de rester connectées dans l'optimum. Les autres contraintes mettent en œuvre plutôt directement les différentes règles. Ce qui me laisse perplexe dont j'ai toujours l'air d'avoir besoinisland_fields_have_at_least_one_neighbor
.Cependant, les performances de cette formulation ne sont pas excellentes. En mangeant directement toute la complexité avec une grande quantité de contraintes, le solveur prend près de 15 secondes pour l'exemple 15 x 15.
Code (toujours non golfé)
Données de problème
5 x 5
7 x 7
15 x 15
Usage
Avoir
glpsol
installé, modéliser en un seul fichier (par exempleriver.mod
), saisir les données dans des fichiers séparés (par exemple7x7.mod
). Alors:Cela, plus de patience, imprimera la solution dans le format de sortie spécifié (avec "quelques" sorties de diagnostic).
la source
Python 3 , 1295 octets
Il s'agit d'une solution python uniquement. Il n'utilise aucune bibliothèque et charge la carte via une entrée standard. Plus d'explications à venir. C'est ma première tentative sur un si grand golf. Il y a un lien vers le code commenté et non golfé en bas.
Essayez-le en ligne!
Regardez le code non golfé .
la source