Contexte
Nonogram , également connu sous le nom de Picross ou Griddlers, est un casse-tête dont l'objectif est de déterminer si chaque cellule de la grille 2D doit être colorée ou laissée en blanc, en utilisant le nombre de cellules colorées consécutives sur chaque ligne.
Ce qui suit est un exemple de puzzle Nonogram avec solution.
Le problème est que certains jeux / applications mobiles Nonogram commerciaux ont des puzzles qui ne peuvent pas être résolus à la main (par exemple, ont plusieurs solutions ou nécessitent un retour en arrière profond). Cependant, ils offrent également des vies au joueur, où une vie est perdue lorsque vous essayez de colorer une cellule dont la bonne réponse est vide . Alors maintenant, il est temps de forcer ces "énigmes" méchantes!
Afin de simplifier la tâche, imaginez une seule ligne avec son indice et rien d'autre:
3 7 | _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Le [3,7]
sont les indices, et la longueur de ligne est de 15 cellules. Puisqu'il a plusieurs solutions possibles, nous devons risquer des vies afin de résoudre complètement cette ligne (c'est-à-dire déterminer toutes les cellules colorées).
Défi
Étant donné une ligne avec des indices (une liste d'entiers positifs) et la longueur de la ligne, trouvez le nombre maximum de vies que vous perdrez, en supposant que vous forcez la ligne avec une stratégie optimale.
Notez que vous devinez toujours les cellules colorées . Dans les jeux réels, deviner les cellules vides (bonnes ou mauvaises) n'a aucun effet sur votre vie, vous ne pouvez donc pas "résoudre" le puzzle de cette façon.
En outre, vous pouvez supposer que l'entrée représente toujours une ligne de Nonogram valide, vous n'avez donc pas à vous soucier de quelque chose comme [6], 5
.
Explication
Voyons d'abord quelques exemples plus simples.
[1,2], 5
Il y a exactement trois possibilités pour cette ligne ( O
est une cellule colorée, .
est une cellule vide):
O . O O .
O . . O O
. O . O O
Si nous essayons de colorer la cellule 0 (index basé sur 0 à partir de la gauche), l'une des situations suivantes se produit:
- La cellule est correctement colorée. Nous avons maintenant deux possibilités, et nous pouvons choisir entre la cellule 2 et la cellule 4 afin de résoudre complètement la ligne. Dans les deux cas, nous perdrons une vie dans le pire des cas.
- La cellule est vide et nous perdons une vie. Dans ce cas, nous avons déjà identifié la solution unique à cette ligne, nous avons donc terminé avec 1 vie perdue.
Par conséquent, la réponse [1,2], 5
est 1.
[5], 10
Recherche binaire? Nan.
Le premier choix le plus évident est 4 ou 5, ce qui révélera une possibilité s'il est vide (au coût de 1 vie). Disons que nous avons choisi 4 en premier. Si la cellule 4 est en effet colorée, nous l'étendons vers la gauche, c'est-à-dire essayons 3, 2, 1 et 0 jusqu'à ce qu'une vie soit perdue (ou la cellule 0 est colorée, alors nous finissons par ne pas vivre du tout). Chaque fois qu'une vie est perdue, nous pouvons déterminer de manière unique la solution, par exemple si nous voyons quelque chose comme ceci:
_ _ X O O _ _ _ _ _
alors nous savons déjà que la réponse est la suivante:
. . . O O O O O . .
Par conséquent, la réponse pour [5], 10
est également 1.
[3,7], 15
Commencez par la cellule 11 qui, si elle est vide, révélera immédiatement la solution suivante.
O O O . O O O O O O O X . . .
Essayez ensuite 12, ce qui, s'il est vide, donne deux possibilités qui peuvent être résolues au prix d'une vie supplémentaire.
O O O . . O O O O O O O X . .
. O O O . O O O O O O O X . .
Essayez maintenant 2. S'il est vide, cela conduit à trois possibilités qui peuvent être résolues de manière similaire à l' [1,2], 5
exemple.
. . 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
Si vous continuez à minimiser le risque de cette manière, vous pouvez atteindre n'importe quelle solution avec max. 2 vies passées.
Cas de test
[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
Pour les deux derniers cas, la stratégie optimale ne passe pas par les blancs minimum, mais simplement de gauche à droite (ou de droite à gauche). Merci à @crashoz de l'avoir signalé.
Règles
Les règles de code-golf standard s'appliquent. La soumission valide la plus courte en octets l'emporte.
Prime
Si quelqu'un propose un algorithme à temps polynomial (avec la preuve d'exactitude), j'accorderai une prime de +100 à une telle solution.
la source
[6], 5
?Réponses:
Rubis , 85 octets
Essayez-le en ligne!
Explication
Voici un exemple
_
inconnu,X
un espace connu,O
une cellule colorée connue et uneL
vie perdueDéfinissons une fonction de coûth
Chaque pas que nous diminuonsn d'au moins 3 et il y a maintenant un seul appel récursif, la complexité est O (n)
la source
Python,
303289 octetsPremier golf depuis longtemps, donc il peut y avoir beaucoup d'excès de graisse. (Merci à Jo King d' avoir trouvé 14 octets.)
La fonction f génère tous les arrangements possibles (bien que toujours avec un blanc comme premier caractère, mais c'est bien tant que nous incrémentons la longueur de 1 avant de l'appeler). La fonction g sélectionne la position avec le moins de blancs et de répétitions. La fonction h les rassemble.
Les exemples fonctionnent tous bien:
la source
False
pour0
? Si oui, vous pouvez passer(len(q)>1)*1and
àlen(q)>1and
. Si vous n'êtes pas autorisé à revenirFalse
pour0
, puis le faire, mais le changementg(f(l,n+1),n+1)
à1*g(f(l,n+1),n+1)
et il sera toujours sauver un octetFalse
n'est pas autorisé0
, au lieu de changerg(f(l,n+1),n+1)
pour1*g(f(l,n+1),n+1)
, changez-le en+g(f(l,n+1),n+1)
h=
nombre d'octets