Il existe une variante du problème bien connu des N-reines qui implique des reines et des chevaliers et serait "beaucoup plus difficile" 1 . L'énoncé du problème est le suivant:
Vous devez placer un nombre égal de chevaliers ♞ et de reines ♛ sur un échiquier de sorte qu'aucune pièce n'attaque aucune autre pièce. Quel est le nombre maximum de pièces que vous pouvez placer sur le plateau et combien de façons différentes pouvez-vous le faire?
Dans ce défi de code-golf , vous recevrez une entrée n comprise entre 3 et 32 (de la manière la plus adaptée à votre langue). Pour un n donné , il peut y avoir zéro ou plusieurs solutions au problème ci-dessus. Dans le cas où il n'y a pas de solution, vous ne devez rien produire / renvoyer ( nil , chaîne vide , false , ...). Sinon, vous devez donner deux résultats:
- Un plateau de solution (voir ci-dessous) pour la taille n où il n'est pas possible d'ajouter une pièce d'échecs reine ou chevalier sans qu'aucune pièce ne soit attaquée. Il doit y avoir un nombre égal de reines et de chevaliers .
- La source d'un programme à exécuter qui n'accepte aucune entrée et donne (i) une autre solution (ou rien ) pour la même taille n , dans le même format, ainsi que (ii) un autre programme pour la solution suivante (et ainsi de suite) ...).
Notez que:
- La séquence de programmes ne doit jamais renvoyer la même carte deux fois, doit couvrir toutes les solutions possibles au problème de taille n et doit finalement se terminer (ne produire aucune sortie).
- Vous pouvez soit renvoyer deux valeurs, renvoyer l'une et imprimer l'autre, soit imprimer les deux valeurs de retour.
- Cependant , si vous imprimez à la fois la carte et le programme suivant, la carte ne doit pas être considérée comme faisant partie du programme suivant (je recommanderais d'imprimer la carte en commentaire ou d'utiliser à la fois la sortie standard et les flux d'erreur).
- Le programme en tant que valeur de retour doit être une chaîne et non une fermeture.
Format du conseil
- Une planche est un carré de taille n .
- Une cellule de conseil peut être vide, une reine ou un chevalier.
- Vous devez choisir des valeurs distinctes pour chaque type de cellules (c'est-à-dire que vous pouvez utiliser d'autres symboles que Q, N lors de l'impression du tableau).
- Si vous retournez un tableau non-string, il doit s'agir d'une collection ordonnée des n 2 valeurs du tableau (par exemple, matrice, vecteur ou liste dans l'ordre principal ligne / colonne, ...).
Si vous imprimez le tableau, vous pouvez l'imprimer au carré ou en ligne. Par exemple, une carte de solution de taille 4 peut être imprimée comme suit (espaces non requis; symboles à votre discrétion):
Q - - - - - - - - - - - - - N -
Si vous le sentez, vous pouvez également générer:
♛ · · · · · · · · · · · · · ♞ ·
... mais cela suffit:
Q-------------N-
Peu importe si vous parcourez les cellules dans un ordre de ligne ou de colonne, car il existe des solutions symétriques. Par exemple, les solutions pour n = 4 sont:
Q------N-------- Q----------N---- Q------------N-- Q-------------N- -Q----------N--- -Q------------N- -Q-------------N --Q---------N--- --Q----------N-- --Q------------N ---QN----------- ---Q----N------- ---Q---------N-- ---Q----------N- ---NQ----------- ----Q------N---- ----Q----------N N------Q-------- -------QN------- -------Q----N--- ---N----Q------- -------NQ------- --------Q------N N----------Q---- ----N------Q---- -----------QN--- -N----------Q--- --N---------Q--- -------N----Q--- -----------NQ--- N------------Q-- --N----------Q-- ---N---------Q-- N-------------Q- -N------------Q- ---N----------Q- -N-------------Q --N------------Q ----N----------Q --------N------Q
Vous pouvez également regarder les solutions pour n = 5 sous forme de matrices ; les planches contient #
, q
et des n
symboles qui sont des cellules vides de différents types (voir ma réponse ci - dessous). Je compte 2836 cartes pour n = 6 , comme dans la réponse de Sleafar (j'ai introduit un bug lors de la réduction du nombre d'octets, mais il est maintenant corrigé).
Un grand merci à Sleafar pour avoir trouvé non pas un mais deux bugs dans mon code.
But
Le code le plus court en octets gagne.
Nous mesurons la taille du premier programme, celui qui accepte n .
1 . Queens and Knights , par Roger KW Hui (attention! Contient une solution)
-------------------------N--------Q-
n'est pas valide car plus de morceaux peuvent être ajoutés :)Q--------N---------------N--------Q-
.Réponses:
Groovy, 515 octets
Essai
Fournissez n comme argument de ligne de commande:
La première ligne de la sortie est toujours une solution sous forme de commentaire (0 = vide, 1 = reine, 2 = chevalier), suivie du code de la deuxième ligne:
Le script suivant peut être utilisé pour des tests automatisés (fournissez à nouveau n comme argument):
Parce que j'ai essayé de rendre la solution aussi petite que possible, elle est très lente (voir ci-dessous pour plus de détails). J'ai testé seulement n = 4 avec cette version pour voir si la quineification fonctionne.
Résultats
n = 4: 40 solutions ( format converti )
n = 5: 172 solutions ( format converti )
n = 6: 2836 solutions ( format converti )
Algorithme
Il s'agit d'une version non quine légèrement non golfée de la solution:
Quineification
J'ai utilisé une approche très simple ici pour garder la taille du code faible.
La variable X contient l'index de la solution à imprimer ensuite. Y contient une copie modifiée de l'algorithme ci-dessus, qui est utilisée pour calculer toutes les solutions, puis sélectionner une seule d'entre elles, ce qui est la raison de sa lenteur. L'avantage de cette solution est qu'elle ne nécessite pas beaucoup de code supplémentaire. Le code stocké dans Y est exécuté à l'aide de la classe Eval (un vrai quine n'est pas requis).
Le code modifié imprime la solution pointée par X , augmente X et ajoute une copie de lui-même:
J'ai également essayé de sortir toutes les solutions sous forme de code pour la deuxième étape, mais pour n = 6, cela produisait trop de code pour Groovy.
la source
Lisp commun, 737
auto-réponse
Exemple
Collez ce qui précède dans le REPL, qui renvoie un objet fonction:
Appelez-le (l'étoile est liée à la dernière valeur renvoyée):
Cela imprime les éléments suivants sur la sortie standard:
De plus, la valeur renvoyée par cette fonction est:
... qui est un littéral de tableau. Le numéro 5 représente les reines, 6 pour les chevaliers et tout le reste représente une cellule vide, sauf qu'il y a plus d'informations stockées en interne. Si nous copions-collons la fonction retournée dans la repl, nous obtenons une nouvelle fonction.
Et nous pouvons l'appeler sans arguments:
Cet appel renvoie une nouvelle solution
#(5 0 0 0 0 0 0 2 0 0 0 6 0 0 2 0)
et la source d'une autre fonction (non représentée ici). Si la fonction d'origine ou la dernière générée ne trouve pas de solution, rien n'est imprimé et rien n'est retourné.Valeurs internes
J'avais l'habitude de générer trop peu de solutions. Maintenant, je propage quelle cellule est sans danger pour une reine et pour un chevalier, indépendamment. Par exemple, voici une sortie pour n = 5 avec une jolie impression:
Lorsque nous avons placé la reine
Q
, les positions éloignées de cette reine sont toujours sans danger pour les reines et désignéesq
. De même, les chevaliers qui ne sont accessibles que par les reines sont sans danger pour les autres chevaliers. Les valeurs sont binaires et -ed pour représenter les mouvements possibles et certaines cellules sont accessibles par aucun type de pièce.Plus précisément, voici la séquence de cartes menant à la solution suivante (de gauche à droite), où les cellules libres sont progressivement contraintes avec différentes valeurs:
Approche non quine
Version non golfée, commentée
Doublons et bogues
Ma toute première solution a généré des solutions en double. Afin de le résoudre, j'ai introduit deux compteurs pour les reines et les chevaliers. Le compteur pour les reines (resp. Chevaliers) garde une trace de la première position dans le tableau où une reine (resp. Chevalier) existe: j'ajoute une reine (resp. Un chevalier) uniquement aux positions qui suivent cette position minimale.
Cette méthode m'empêche de revoir les solutions qui ont déjà été trouvées dans les itérations précédentes, car j'itère avec une position de reine (resp. Chevalier) croissante.
Cependant, Sleafar a remarqué qu'il y avait des solutions pour lesquelles il pourrait y avoir de la place pour les reines et les chevaliers, ce qui est contraire aux règles. Pendant un certain temps, j'ai pensé que je devais revenir à une recherche normale et stocker toutes les solutions connues pour éviter les doublons, qui semblaient trop coûteux (à la fois en termes d'octets et d'utilisation de la mémoire).
Au lieu de cela, voici ce que je fais maintenant: quand une carte de solution potentielle est trouvée, j'essaie d'ajouter exactement une reine et un chevalier, sans prendre en compte les compteurs (c'est-à-dire pour toutes les cellules sur la carte). Si cela est possible, la carte actuelle est une copie de la précédente et je rejette la solution.
Les tests
Quine-ification
J'ai eu différentes idées pour faire des quines successifs. Le plus simple est probablement de générer d'abord toutes les solutions sous forme de liste de chaînes et d'écrire des quines séquentielles qui apparaissent à partir de cette liste à chaque génération. Cependant, cela ne semble pas être plus court que l'approche actuelle. Alternativement, j'ai essayé de réécrire le code récursif avec une pile personnalisée et de vider toutes les variables d'état chaque fois que je trouve une solution; l'objectif est que l'étape suivante puisse être traitée comme une continuation de l'étape actuelle. Peut-être que ce serait mieux adapté à un langage basé sur la pile. La version actuelle est assez simple et repose sur des variables de lecteur Common Lisp, qui sont toujours amusantes à utiliser.
la source