Hashiwokakero ("construire des ponts" en japonais) est un casse-tête dans lequel vous êtes chargé de connecter un groupe d'îles avec des ponts. Les règles sont les suivantes:
- Les ponts doivent être exécutés verticalement ou horizontalement entre deux îles.
- Les ponts ne peuvent pas se croiser.
- Une paire d'îles peut être reliée par au plus deux ponts parallèles.
- Chaque île est marquée d'un numéro compris entre 1 et 8 inclus. Le nombre de ponts connectés à une île doit correspondre au nombre sur cette île.
- Les ponts doivent relier les îles en un seul groupe connecté.
Votre tâche consiste à écrire un programme qui résoudra les puzzles Hashiwokakero.
Vous pouvez supposer qu'un puzzle donné est résoluble et qu'il n'y a qu'une seule solution.
Le programme doit être raisonnablement efficace. Par exemple, la résolution du casse-tête 25x25 ci-dessous ne devrait pas prendre plus de 10 minutes sur un PC moyen et ne devrait pas utiliser plus d'un gigaoctet de mémoire. La résolution d'énigmes plus petites comme celle de 7x7 devrait prendre quelques secondes.
Contribution:
Le casse - tête sera donné comme une carte 2D de caractères, les chiffres 1
à 8
îles représentant, et des espaces représentant l' eau. Les lignes seront rembourrées avec des espaces si nécessaire pour les rendre toutes de la même longueur.
Les îles seront toujours séparées horizontalement et verticalement par au moins un carré d'eau afin qu'il y ait de la place pour placer le pont potentiel entre elles. Il y aura toujours au moins deux îles dans un puzzle.
Votre programme doit de préférence lire la carte du puzzle à partir de l'entrée standard, mais vous pouvez spécifier une autre méthode d'entrée si votre langage de programmation l'exige.
Production:
La sortie doit être similaire à l'entrée, sauf avec des espaces remplacés par des ponts si nécessaire. Les ponts doivent être dessinés en utilisant les caractères de dessin de boîte Unicode ─
(U + 2500), │
(U + 2502), ═
(U + 2550) et ║
(U + 2551) pour représenter les ponts simples et doubles horizontaux et verticaux.
Si les caractères Unicode sont un problème, vous pouvez utiliser les caractères ASCII -
, |
, =
et au H
lieu.
Critères gagnants:
C'est le golf de code. La solution la plus courte, correcte et raisonnablement efficace l'emporte.
Exemples:
Puzzle (7x7):
2 2 1
1 4 3
3 2
4
3 2 3
1
3 4 2
Solution:
2─2──1
│1──4─3
3──2║ ║
│ │4 ║
│3─2║ 3
1║ ║ │
3──4─2
Puzzle (25x25):
2 2 2 2 1 1 2 2 2 2 2
1 3 5 4 4 2
2 2 4 5 5 4 2 2 1 3
2 1 1 3 3 2 2
3 4 4 4 4 5 4 3 2 3
2 4 5 4 2 3
2 1 4 2 4 3 1 1 2
2 1 3 1 1 6 4 2
3 2 4 3 6 3 2
2 2 3 3 2 5 2 4 3
2 1 1 2
1 3 3 3 3 5 8 7 6 5 4
2 3 1 1 2
1 1 5 1 4 5 6 3 1 2
1 1 2 2 3 4
3 5 4 4 3 3 8 7 5 1 2
2 3 1 2 2 1 1
2 2 2 2 5 7 6 3 3
3 3 6 3 5 3 2 2 2 3
2 1 2 3 2 2
3 4 6 4 5 5 3 3 5 1
2 1 2 2 1 1 3
2 1 1 2 3 6 5 2 2
2 3 4 4 4 2 1
2 2 2 2 2 2 2 1 1 3 2
Solution:
2─2─2──2 1 1─2─2──2──2─2
│ │ │1─3═5══4══4─2│
2 2─4─5══5═4═2│2──1 │ │3
│ 2│ ║1│ 1─3═3─2│ │ 2║
│ ║3═4│4══4─4═5─4─3──2 │3
2 4═5─4│ │ │ ║ │ │2───3│
│2─1║ ║4─2│ 4─3 │ 1│ 1 │2
2│1─3 ║║ │1 ║1──6══4 │ 2│
│3─2──4║ 3══6─3 ║ │ │ │2
2│2═3 │3──2 │ ║ 5─2│ 4─3│
│2─1│ │ │ │ ║ ║ │1 ║ │2
│ 1─3─3─3─3─5═8═7═6──5═4│
2──3───1│1─2│ ║ │ ║ ││
1 │ 1──5─1││ 4─5─6─3─1│2
1│ │1──2║ │2 │ ║ ║ │3═4│
│3─5═4 │4──3│ 3═8═7═5│1│2
2│ │ ║ 3│ 1│2──2║ │ ║1│1│
│2 │ ║ ║2 │2──2│5═7═6─3─3
3│ 3─6─3│ 5═3 │2│ ║2│2─3│
║2 │ ║ │ ║ │ 1│2─3║2│ ║2
3│ 4═6──4─5─5──3─3─5││1║│
│2 │ │1 │ │2║2──1│ ║1││3│
2│ │ 1│ │ 1║2│3══6═5─2││2
│2─3──4═4──4─2│ │ │1│
2─2──2─2──2─2─2 1 1─3─2
1 1
saisie?1 1
, qui est un casse-tête valide et qu'il doit être géré correctement.Réponses:
Haskell, 1074 caractères
À l'origine, je l'avais encore plus purement japonais en implémentant également les fonctions primitives en termes de correspondance de modèle simple et de combinaisons de listes:
Haskell, 1192
fonctionne en ≈3 minutes sur mon i5 .
Version commentée:
la source
Python, 1079 caractères
Le code effectue une recherche exhaustive assez simple dans
S
, en utilisant une certaine propagation de contraintes pour le faire fonctionner dans un délai raisonnable.E
représente l'ensemble actuel d'arêtes, au format [de, à, delta, poids possibles] . from et to sont des identifiants d'îlot et delta est soit 1 pour les bords horizontaux, soit W (= largeur des lignes) pour les bords verticaux. les poids possibles est une sous-liste de [0,1,2] codant l'état connu actuel de ce bord (0 = pas de pont, 1 = pont simple, 2 = pont double).S
fait trois choses. Tout d'abord, il propage des informations, comme si un bord n'a plus la possibilité d'avoir un poids 0, puis tous les bords qui le traversent sont éliminés (leurs poids possibles sont définis sur [0]). De même, si la somme du poids minimum pour les bords incidents sur une île est égale au poids de l'île, alors tous ces bords sont définis à leur minimum.Deuxièmement,
S
vérifie que le graphe est toujours connecté en utilisant des arêtes non [0] (leQ
calcul).Enfin,
S
sélectionne un bord qui n'est pas encore entièrement déterminé et s'appelle récursivement, en définissant ce bord sur l'une de ses possibilités restantes.Prend environ 2 minutes pour le plus grand exemple.
la source
print(B);sys.exit(0)
C # -
660156612225Pas particulièrement bien golfé. Utilise la bibliothèque de programmation de contraintes de google or-tools. Crée des contraintes pour le nombre total de bords et pour éliminer les ponts qui traversent, mais il est un peu plus difficile de définir des contraintes pour s'assurer qu'elles sont toutes connectées. J'ai ajouté de la logique pour tailler les composants 2 = 2 et 1-1, mais je dois encore parcourir la liste finale (39 sur la grande) et éliminer ceux qui ne sont pas entièrement connectés. Fonctionne assez rapidement. Ne prend que quelques secondes sur le plus grand exemple. Non golfé:
la source