CJam, 33 32 20 19 17 octets
Version révisée, avec le support massif de @ Sp3000 et @ MartinBüttner:
qN/_z]{:e`z,3<}/|
Essayez-le en ligne
Contributions
- @ Sp3000 a suggéré une simplification critique de mon algorithme d'origine.
- @ MartinBüttner a appliqué ses compétences de golfeur fou à l'approche révisée, ce qui a certainement abouti à un code plus court que celui que j'aurais proposé même après avoir envisagé la simplification.
Algorithme et Preuve
Ce qui suit explique les critères pour le puzzle se séparant horizontalement. Le cas vertical peut être déterminé en regardant les colonnes au lieu de lignes, ou en transposant la matrice de caractères et en regardant à nouveau les lignes.
Je vais utiliser le terme "stretch" pour une séquence maximale des mêmes lettres. Par exemple, les lignes suivantes ont respectivement 1, 2 et 3 tronçons:
AAAAAAAA
BBBAAAAA
AABBBAAA
Je vais aussi utiliser le terme "imbriqué" pour une ligne / puzzle qui ne peut pas se séparer.
L'observation clé est que le puzzle peut se séparer si et seulement si toutes les lignes ont au plus 2 étendues . Ou inversé, il est imbriqué si et seulement s'il y a une ligne avec plus de 2 tronçons .
Ce qui suit n’est peut-être pas considéré comme une preuve mathématique stricte, mais j’estime que cela fournit une explication convaincante de la nécessité de cela.
Il est facile de voir que le puzzle est imbriqué s’il a des rangées de plus de 2 tronçons. En regardant une rangée avec 3 étendues:
BBBAAB
il est clair que cela empêche le puzzle de se séparer car l' A
étirement est bloqué entre les B
étirements. Cela signifie que la ligne est imbriquée, ce qui rend le puzzle entier imbriqué.
Le sens opposé de la preuve n’est pas aussi évident. Nous devons montrer qu’il n’existe pas de casse-tête entremêlés dans lesquels toutes les lignes ne comportent qu’un ou deux tronçons. À partir de quelques observations:
- Les rangées avec un seul étirement ne contribuent pas à l'enchevêtrement des puzzles, car elles peuvent glisser dans les deux sens sans collision.
- Si toutes les lignes avec 2 étendues ont le même ordre de
A
et B
, le puzzle n'est clairement pas emboîté. Dans ce cas, toutes les A
cellules sont laissées de toutes les B
cellules, ou inversement, et il n'y a pas de collision lors du glissement des deux pièces.
Le seul cas délicat serait des énigmes où nous avons des rangées avec 2 tronçons d’ordre différent. Je vais montrer que de tels casse - tête n'existent pas dans les spécifications données. Pour montrer cela, regardons un puzzle partiel qui a cette configuration, où .
sont des caractères génériques:
.......
AAABBBB
.......
BBAAAAA
.......
Maintenant, la spécification indique que les cellules A
et B
sont simplement connectées dans tous les casse-têtes valides. Pour rendre les A
cellules connectées dans le puzzle partiel ci-dessus, nous avons deux options:
Nous passons en boucle sur l’un des tronçons de B
, par exemple:
..AAAAAA
AAABBBBA
.......A
BBAAAAAA
........
Pour ce faire, nous étendons inévitablement l’une des rangées afin d’avoir 3 étendues. Cela ne nous donnera donc jamais un puzzle valide dans lequel toutes les lignes ont au plus 2 étendues.
Nous les connectons sur un chemin direct:
.......
AAABBBB
..A....
BBAAAAA
.......
Les A
cellules sont maintenant simplement connectées et il n'y a toujours pas de lignes de plus de 2 étendues. Cependant, les B
cellules doivent également être simplement connectées. Le chemin direct est maintenant bloqué par les A
cellules connectées et le seul moyen de connecter les B
cellules consiste à effectuer une boucle autour de l'un des segments de A
cellules. Cela nous ramène au cas 1, où nous ne pouvons pas faire cela sans créer des rangées de 3 étendues.
Pour compter les tronçons, l'implémentation utilise l'opérateur CJam RLE.
Explication du code
qN/ Get input and split at newlines.
_z Make a transposed copy.
] Wrap the original and transposed puzzle in an array so that we can
loop over the two.
{ Start of loop over original and transposed puzzle.
:e` Apply RLE to all rows.
z, Transpose the matrix with the RLE rows, and take the element count of the
result. Or in other words, take the column count. This will be the length
of the longest row after RLE.
3< Check the length for less than 3.
}/ End of loop over original and transposed puzzle.
| Or the results of the two.