Chez nos amis de Puzzling.SE , le puzzle suivant a été posté: Ce puzzle chromatique est-il toujours résoluble? par Edgar G. Vous pouvez y jouer ici .
Explication de puzzle
m x n
Avec une grille avec des carreaux de trois couleurs différentes, vous pouvez sélectionner deux carreaux adjacents , si leurs couleurs sont différentes . Ces deux carreaux sont ensuite convertis en la troisième couleur, à savoir la couleur non représentée par ces deux carreaux. Le casse-tête est résolu si toutes les tuiles ont la même couleur . Apparemment, on peut prouver que ce puzzle est toujours soluble, si m
ni n
est divisible par 3.
Bien sûr, cela demande un algorithme de résolution. Vous allez écrire une fonction ou un programme qui résout ce casse-tête. Notez que les fonctions avec des «effets secondaires» (c'est-à-dire que la sortie est activée stdout
plutôt que dans une valeur de retour de type de données peu pratique) sont explicitement autorisées.
Entrée sortie
L'entrée sera une m x n
matrice consistant en les nombres entiers 1
, 2
et 3
(ou 0
, 1
, 2
si cela convient). Vous pouvez prendre cette entrée dans n'importe quel format sain. Les deux m
et ne n
sont >1
pas divisibles par 3. Vous pouvez supposer que le casse-tête n’a pas été résolu
Vous allez ensuite résoudre le puzzle. Cela impliquera une sélection répétée de deux tuiles adjacentes à «convertir» (voir ci-dessus). Vous allez générer les deux coordonnées de ces tuiles pour chaque étape prise par votre algorithme de résolution. Cela peut aussi être dans n'importe quel format de sortie sain. Vous êtes libre de choisir entre l'indexation de vos coordonnées basée sur 0 et celle basée sur 1, et d'indiquer si les lignes ou les colonnes sont indexées en premier. Veuillez toutefois mentionner cela dans votre réponse.
Votre algorithme doit s'exécuter dans un délai raisonnable sur le boîtier 8x8 d'origine. Le brusquement forcé est explicitement interdit, c'est-à-dire que votre algorithme doit s'exécuter O(k^[m*(n-1)+(m-1)*n])
avec k
le nombre d'étapes nécessaire à la solution. La solution n’est cependant pas obligée d’être optimale. La preuve donnée dans la question liée peut vous donner une idée de la procédure à suivre (par exemple, commencez par faire toutes les colonnes en n'utilisant que des tuiles adjacentes verticalement, puis toutes les lignes).
Cas de test
Dans ces cas de test, les coordonnées sont basées sur 1 et les lignes sont indexées en premier (comme MATLAB / Octave et probablement beaucoup d'autres).
Input:
[1 2]
Output: (result: all 3's)
[1 1],[1,2]
Input:
[ 1 2
3 1 ]
Output: (result: all 1's)
[1 1],[2 1] (turn left column into 2's)
[2 1],[2 2] (turn right column into 3's)
[1 1],[1 2] (turn top row into 1's)
[2 1],[2 2] (turn bottom row into 1's)
Input:
[1 2 3 2
3 2 1 1]
Output: (result: all 3's)
[1 1],[1 2]
[1 3],[1 4]
[1 2],[1 3]
[1 1],[1 2]
[1 2],[1 3]
[1 1],[1 2]
[1 3],[1 4]
[2 1],[2 2]
[1 1],[2 1]
[1 2],[2 2]
[1 3],[2 3]
[1 4],[2 4]
Si vous le souhaitez, je peux poster une pâte contenant des cas de test plus volumineux, mais je pense que cela devrait suffire.
la source
Réponses:
Ruby, 266 octets
Plus ou moins juste un port de la solution Octave, sauf qu'il résout d'abord les lignes au lieu des colonnes. L'entrée est un tableau de tableaux, les tableaux intérieurs étant les rangées. Les mouvements de sortie sont
[row, column, row, column]
. Suite de testsUngolfed avec explication
la source
intersect
c'est un mot-clé aussi volumineux)intersect
, je ne sais pas si vous pouvez régler le problème de la façon dont fonctionne le mien parce que Rubyfind
fonctionne essentiellement sur des fonctions et que votrefunction
mot clé est tout aussi volumineux.find
- merci! Pourtant, nulle part près de vous battre ...Octave,
334313 octetsPuisque le défi peut sembler un peu intimidant, je présente ma propre solution. Je n'ai pas prouvé formellement que cette méthode fonctionne (je suppose que cela reviendra à prouver que l'algorithme ne restera jamais bloqué dans une boucle), mais jusqu'à présent, cela fonctionne parfaitement, en effectuant 100x100 tests en 15 secondes. Notez que j'ai choisi d'utiliser une fonction avec des effets secondaires plutôt que celle qui renvoie toutes les coordonnées, car cela m'a sauvé quelques octets. Les coordonnées sont les lignes principales, les bases 1 et le format
row1 col1 row2 col2
. Couleurs d'entrée sont plus0,1,2
que cela fonctionne mieux avecmod
, au prix d'avoir à utilisernumel
plutôt quennz
. Version golfée: Édition: sauvegardé quelques octets supplémentaires en utilisant une technique de la réponse de Kevin Lau.Exemple GIF de l'algorithme de résolution:
Version non-golfée:
la source
Lua,
594575559 octetsAttention Il reste encore beaucoup de travail avant que je ne termine ce golf! Je devrais pouvoir prendre moins de 500 octets, à tout le moins. Pour le moment, c'est la première solution qui a fonctionné, et j'y travaille encore.
Je vais fournir une explication complète une fois que j'ai terminé.
la source
Rouille,
496495 octetsMalheureusement, je ne peux pas battre OP, mais pour une réponse de Rust, je suis assez satisfait du décompte.
Entrée: un vecteur de nombres ainsi que le nombre de colonnes. Par exemple
les sorties
à la ligne de commande.
Je résous d'abord toutes les lignes, puis la colonne résultante une seule fois, mais j'imprime les étapes pour toutes les colonnes. Donc c'est en fait assez efficace :-P.
Avec formater:
Edit: renvoie maintenant la couleur de la solution qui me permet d'économiser un point-virgule ^^
la source
Befunge ,
197368696754 octets(oui, je fais du golf inversé, plus il y a d'octets, mieux c'est)
Je pensais que cela pourrait être un défi d'écrire cet algorithme dans Befunge et que ça pourrait être amusant
Je voudrais que ce soit un programme communautaire, alors si quelqu'un veut y travailler, je vous en prie, faites-le.À la fin, j'ai tout fait seul jusqu'à présent, alors je vais finir tout seul (c'est presque fini)
Ce qui est encore fait: un code en forme de troll
(oui, c'est un troll, crois-moi)
Fondamentalement, il lit un tableau et calcule le mouvement à faire pour résoudre les lignes, en prenant une entrée comme
(tout le tableau est passé sous forme de liste [rangée1, rangée2, rangée3,…])
la sortie est
les lignes et les colonnes commencent à 0.
Maintenant que les lignes sont résolues, c'est presque terminé! Hourra!
Explication: (sera mis à jour plus tard)
Donc, il y a 5 parties principales:
Les parties grises sont des initialisations
Voici une explication plus détaillée du module qui trouve les cases à combiner (codé ici, au fait)
La partie CALL est lorsque le pointeur d’instruction se dirige vers un autre module, à combiner à des cases. Il revient à ce module via l'entrée 'B'
Voici un pseudo-code: (currentx est lié à la lecture du tableau) Pour:
Notez que si vous voulez le tester, vous devrez mettre un espace de fin et de nouvelles lignes afin qu'il y ait suffisamment d'espace pour stocker le tableau, si vous souhaitez utiliser le lien d' interprétation que j'ai lié. 22 + le nombre de lignes en entrée en tant que lignes de fin et 34 + le nombre de colonnes en tant qu'espaces de fin sur une ligne devraient être corrects.
la source
\r\n
au lieu de\n
seulement?)C, 404 octets
Mon premier code de golf, je suis assez content de la façon dont cela s'est passé. A pris beaucoup trop de temps, cependant. Ce n'est pas complètement C standard, juste ce que compilera sous gcc sans drapeaux spéciaux (et ignorant les avertissements). Donc, il y a une fonction imbriquée là-dedans. La fonction
f
prend les dimensionsm
et enn
tant que son premier argument, et comme son troisième argument prend prend un (pointeur int) vers un tableau de taillem
×n
(indexé par les premières lignes). Les autres arguments sont des arguments factices, vous n'avez pas besoin de les transmettre, ils sont juste là pour économiser des octets lors de la déclaration de variables. Il écrit chaque paire modifiée dans STDOUT au formatrow1,col1:row1,col1;
, le point-virgule séparant les paires. Utilise l'indexation basée sur 0.J'ai utilisé un algorithme légèrement différent de l'OP pour résoudre des lignes / colonnes individuelles. Cela ressemble à ceci (pseudocode):
La
for(;~b;b--)
boucle s'exécute exactement deux fois. Au deuxième passage, elle résout des colonnes au lieu de lignes. Ceci est effectué en échangeantn
et enm
modifiant les valeurs deo
etp
qui sont utilisées dans l'arithmétique de pointeur pour adresser le tableau.Voici une version non golfée, avec un test principal, et imprime le tableau entier après chaque coup (appuyez sur enter pour l'étape 1 tour):
la source