Contexte
Dans les jeux Bejeweled et similaires, le joueur doit échanger deux gemmes adjacentes (pas de diagonales) dans une grille de gemmes 8x8 afin de faire correspondre trois de la même couleur d'affilée. Les gemmes peuvent être assorties horizontalement ou verticalement. Le gameplay se poursuit jusqu'à ce qu'il n'y ait aucun mouvement qui puisse être effectué, résultant en trois de suite, à quel point le jeu est terminé.
Tâche
Le but est d'écrire un programme qui détermine si une partie de Bejeweled n'est pas encore terminée. En d'autres termes, il doit vérifier s'il y a un mouvement possible qui en fait au moins trois d'affilée. Il peut y avoir plus de trois gemmes d'affilée et c'est toujours un mouvement valide.
Contribution
Votre programme doit accepter via une entrée standard une représentation 8x8 d'une grille Bejeweled. Chacune des sept couleurs de gemmes sera représentée par un chiffre de 1 à 7. Chaque ligne contiendra une ligne et 8 lignes, chacune composée de 8 chiffres, seront entrées. Voir les exemples. Vous pouvez supposer que l'entrée suivra toujours ce format et n'en contiendra jamais trois de suite.
Production
Le programme doit ensuite sortir (vers la sortie standard) yes
ou no
selon qu'il existe ou non au moins un mouvement valide qui entraînerait trois gemmes ou plus d'affilée. Votre programme ne doit rien produire d'autre qu'une seule instance de yes
ou no
.
Règles
Votre programme ne doit pas utiliser de fichiers ou de ressources externes, d'arguments de ligne de commande ou exiger un certain nom de fichier. Le programme avec le moins d'octets dans son code source gagne.
Exemples
Contribution:
12314131
13224145
54762673
61716653
61341144
23453774
27645426
75575656
Production: yes
Contribution:
35261546
76421754
15743271
62135642
35617653
64565476
54427254
15635465
Production: no
Voir la réponse de MT0 ci-dessous pour des cas de test supplémentaires.
Réponses:
Solution originale: JavaScript -
261255228227179153 caractèresEn supposant que la chaîne à tester se trouve dans la variable
s
(pour en faire une fonction,f
ajoutez-laf=s=>
au début du code ou, sinon, prenez l'entrée d'une invite, puis remplacez-las
parprompt()
).Les sorties sont vers la console.
3 e solution: JavaScript (ECMAScript 6) - 178 caractères
J'ai pris la 2 e solution ci-dessous (qui utilise des expressions régulières pour vérifier les caractères dans certaines configurations) et l' ai retravaillée pour simplement vérifier la chaîne pour des caractères identiques dans les mêmes configurations sans utiliser d'expressions régulières.
La chaîne Base-36
"2313ab1b8a2a78188h9haj9j8iaiir9r"
donne des paires de décalages à vérifier - c'est-à-dire que la paire23
entraîne la vérification si le i ème caractère est identique au (i + 2) ème caractère et au (i + 3) ème caractère (l'équivalent de l'expression régulière(.).\1\1
- avec quelques vérifications supplémentaires pour s'assurer que le caractère non identique n'est pas une nouvelle ligne).2 e solution: JavaScript (ECMAScript 6) - 204 caractères
Construit plusieurs expressions régulières (voir ci-dessous pour plus de détails) à l'aide de paires de valeurs tirées de la chaîne Base-18
10907160789879h8
et effectueOR
tous les tests. Pour le réduire davantage, vous pouvez noter que les expressions régulières viennent par paires où l'une est le «contraire» de l'autre (en ignorant les expressions régulières pour 3-in-a-row horizontalement et verticalement car l'OP indique qu'elles ne seront jamais présentes - si vous souhaitez ajouter ces tests dans l'annexe0088
à la chaîne Base-18).Explication
Commencez avec 16 expressions régulières couvrant toutes les configurations possibles de mouvements valides:
( Remarque: les expressions rationnelles pour 3 rangées horizontalement (0 e ) et verticalement (partie du 9 e ) ne sont pas pertinentes car l'OP indique que les entrées correspondant à celles-ci ne seront jamais présentes. )
Tester chacun de ceux-ci par rapport à l'entrée déterminera si un déplacement valide de cette configuration peut être trouvé.
Cependant, les expressions régulières peuvent être combinées pour donner ces 6:
Ceux-ci peuvent ensuite être combinés en une seule expression régulière:
Ce qui doit juste être testé par rapport à l'entrée.
Cas de test
Certains cas de test que d'autres personnes pourraient trouver utiles (ne sont pas conformes au format d'entrée consistant à n'utiliser que les chiffres 1 à 7, mais cela est facilement corrigé et ne constitue qu'une grille 8x4 - car c'est le minimum requis pour un test de toutes les entrées valides ).
Au format d'une carte de la chaîne d'entrée à laquelle des 16 expressions régulières ci-dessus elle correspond.
Modifier 1
Remplacer
\d
s par.
- enregistre 6 caractères.Modifier 2
Remplacer
(?:.|\n)
par[\s\S]
et groupes non enlevés de capture supplémentaires et des références arrières mises à jour (comme suggéré par m-Buettner ) et ajouté dans oui / non sortie.Modifier 3
Modifier 4
Ajout d'une autre solution (plus courte) et de deux autres cas de tests non correspondants.
Modifier 5
Modifier 6
la source
?'yes':'no'
dans votre nombre de caractères pour l'équité, car il est dans les exigences et tout le monde l'utilise..
correspondre à n'importe quel caractère, y compris la nouvelle ligne? Avec Perl, l'expression rationnelle combinée n'est qu'une chaîne de 129 octets (que, étant paresseux, j'ai compilé avec Regexp :: Assemble ), donc le programme Perl entier fait environ 150 octets..{8}|.{9}
par.{8,9}
et.{7}|.{8}
avec.{7,8}
Python 383
Une seule * ligne de Python!
* Eh bien, avec des points-virgules, mais ce n'est toujours pas trivial en python (les lignes simples en python sont amusantes! )
la source
Node.js - Solution naïve - 905 octets
Eh bien, pas encore de réponses donc je vais publier une solution vraiment naïve dans Node.js
Il passe par chaque mouvement possible et teste ensuite le tableau résultant pour voir s'il y a 3 d'affilée.
Golfé (avec compilateur de fermeture Google) (quelques trucs hacky comme! 0 et! 1; je ne suis même pas sûr de ce qu'il a fait avec mon échange XOR)
Notez que j'ai écrit ce tout sur mon portable et ne pas avoir le temps de le tester ou quoi que ce soit. Commentez si vous voyez des bugs, je le vérifierai moi-même plus tard.
La version lisible par l'homme avant le golf
la source
Perl,
11496959392878685 octetsComprend + pour
-a0p
Exécutez avec l'entrée sur STDIN:
bejeweled.pl
:Ceci combine une solution regex horizontale unidirectionnelle avec des rotations
Explication:
Dans cette solution, je vais tourner à plusieurs reprises et effectuer les 4 tests suivants:
Où
\C
est "n'importe quel caractère" (contrairement à.
cela inclut la nouvelle ligne). Sauf que cela\C
est obsolète et conduit à des avertissements, j'utilise donc\H
(espace non horizontal) à la place, ce qui est assez bon pour capturer tous les chiffres et la nouvelle ligne.Après 4 rotations, cela aura effectué les 16 tests nécessaires
la source
Python3, 314B
Modifiez le 8, le 5 sur la ligne 6 et les 8 sur la ligne 9 pour gérer des tailles d'entrée arbitrairement grandes; ne se soucie pas non plus de la valeur de chaque valeur, vous pouvez donc la nourrir:
et il reviendra
yes
.Annotations
la source
GNU sed 255 + 2 = 257B
Je pensais que cela n'allait pas être aussi bon que python, mais c'est maintenant: - / Je n'ai pas accès à Internet aujourd'hui, donc je me suis occupé de résoudre ce problème dans sed :). Doit être appelé avec le drapeau -r, c'est-à-dire
sed -rf command.sed < input
que j'ai donc ajouté 2 à mon score.Comment ça fonctionne:
la source
Rubis, 201 octets
J'ai été déçu de ne pas voir de solutions à ce grand défi qui n'utilisent pas d'expression régulière ou de force brute (bien que celles-ci soient excellentes), alors j'en ai écrit une. Il prend une entrée sur STDIN.
L'algorithme arithmétique au niveau du bit est dérivé de cette réponse fantastique sur Game Development Stack Exchange par @leander.
Ruby lambda, 181 octets
Ici, c'est comme un lambda qui prend une chaîne et retourne
true
oufalse
:Voir sur repl.it: https://repl.it/ColJ/2
Non golfé & explication
Le code itère sur les chiffres "1" à "9." Chaque itération comporte deux étapes distinctes:
La première étape est la transformation du plateau, que vous pouvez voir dans le
s.scan(n)
bloc dans le code non golfé. Il transforme la carte en un tableau de 8 entiers, un pour chaque ligne, en traitant les chiffres correspondants comme des 1 et tous les autres comme des 0 dans une chaîne binaire. Par exemple, prenez la ligne12231123
. Dans la première itération, cela deviendra la chaîne binaire10001100
(tous les 1 deviennent - euh, reste - 1 et tous les autres chiffres deviennent 0), ce qui est le nombre décimal 140. Dans la deuxième itération, la même ligne devient01100010
(tous les 2 deviennent 2 et tous les autres chiffres deviennent 0) ou 98 décimaux.Il effectue simultanément une deuxième transformation, qui est la même que la première mais avec la planche tournée de 90 degrés. Cela nous permet d'utiliser la même logique pour faire des correspondances horizontales que verticales. Pour plus de simplicité, il concatène les deux planches en une seule longue avec un zéro au début, au milieu (pour séparer les deux planches) et à la fin pour le rembourrage.
La deuxième étape consiste à rechercher des correspondances possibles, que vous pouvez voir dans le
each_cons(3).any?
bloc. Les lignes transformées (qui sont maintenant des entiers 8 bits) sont archivées (se chevauchant) en groupes de trois lignes ( x , y , z ) en utilisant une arithmétique au niveau du bit. Chaque groupe est vérifié pour voir si une correspondance peut être faite dans la rangée y , soit en décalant un morceau dans la rangée y, soit en décalant un morceau en y de x ou z . Puisqu'il y a une "rangée" nulle avant et après les rangées des planches originales et tournées, nous n'avons pas à vérifier si nous sommes sur la première ou la dernière rangée d'une planche.Si aucune correspondance n'a été trouvée, elle continue jusqu'à l'itération suivante.
la source