Créer une solution Sudoku CHECKER
Il y a des tas de SOLUTIONS Sudoku ici, mais je veux que vous créiez une solution CHECKER aussi petite que possible (code-golf).
Une entrée valide pourra soit prendre un tableau 9x9 comme argument (passé par référence, sérialisé sur la ligne de commande, ou comme vous voulez le prendre), soit accepter un fichier d'entrée composé de neuf lignes de neuf chiffres pour la grille finale . Voir des exemples de saisie ci-dessous.
Les entrées valides doivent être des nombres en base 10 (1-9)
Les positions manquantes, vides, supplémentaires, non numériques ou les positions avec des nombres en dehors de 1-9 doivent être rejetées en tant qu'entrée non valide en renvoyant un résultat différent de zéro, en imprimant une erreur ou les deux.
Votre programme doit tester si chaque numéro apparaît une fois par colonne, une fois par ligne et une fois par sous-grille 3x3. S'il passe, retournez "0" et sinon, retournez un résultat différent de zéro.
L'utilisation de ressources externes (sites Web, etc.) doit être évitée.
Si votre solution est un programme autonome, la sortie avec un état de sortie de, ou l'impression, "0" ou différent de zéro pour "Pass" ou "Fail", respectivement, est correcte.
Laissez gagner la plus petite réponse!
Exemples d'entrée:
tableau c:
int input[9][9]={{1,2,3,4,5,6,7,8,9},
{4,5,6,7,8,9,1,2,3},
{7,8,9,1,2,3,4,5,6},
{2,3,1,5,6,4,8,9,7},
{5,6,4,8,9,7,2,3,1},
{8,9,7,2,3,1,5,6,4},
{3,1,2,6,4,5,9,7,8},
{6,4,5,9,7,8,3,1,2},
{9,7,8,3,1,2,6,4,5}
};
fichier:
123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645
Les 9 sous-grilles:
+---+---+---+
|123|456|789|
|456|789|123|
|789|123|456|
+---+---+---+
|231|564|897|
|564|897|231|
|897|231|564|
+---+---+---+
|312|645|978|
|645|978|312|
|978|312|645|
+---+---+---+
la source
1
ou-1
Python, 103
Je déteste le sudoku.
Comment ça marche: chaque ligne, colonne et bloc doit avoir chaque numéro de 1 à 9. Donc pour chacun
0 <= i, j < 9
, la cellulei,j
est en bloc3*floor(i/3) + floor(j/3)
. Il y a donc 243 exigences à satisfaire. Je fais de chaque exigence un tuple((item index,item type number),symbol)
oùitem index
est un nombre compris entre 0 et 8 (inclus),item type number
0,1 ou 2 pour désigner respectivement une ligne, une colonne ou un bloc, etsymbol
est l'entréeb[i][j]
.Edit: par erreur, je n'ai pas vérifié les entrées valides. Maintenant oui.
la source
0
si la solution passe, pasTrue
APL (46)
Cela prend une matrice 9 par 9. L'exemple peut être entré sur TryAPL comme ceci:
Explication:
↓⍉⍵
: récupère les colonnes de⍵
,↓⍵
: récupère les rangées de⍵
,3/3⌿3 3⍴Z←⍳9
: créer une matrice 3 x 3 contenant les nombres1
à9
, puis tripler chaque nombre dans les deux sens, en donnant une matrice 9 x 9 avec les nombres1
pour9
indiquer chaque groupe,Z∘.=
: pour chaque nombre1
à9
, faites un masque pour le groupe donné,/∘(,⍵)¨
: et masquer⍵
avec chacun, donnant les groupes de⍵
.∊∘Z¨
: pour chaque sous-tableau, voyez s'il contient les nombres1
à9
,∧/,↑
: prenez la logiqueand
de tous ces nombres ensemble.la source
↓9 9⍴1 3 2⍉3 3 9⍴⍵
équivaut à/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9
mais est assez court. Je suis sûr qu'il existe des formules encore plus courtes.⍪
et effectuer une seule division à la fin:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
∊∘Z¨
teste si chaque sous-tableau (ligne, colonne ou bloc) est uniquement composé des nombres 1 à 9. Il ne teste pas si tous les nombres sont représentés. Vous devez faire quelque chose commeZ∘.∊
qui teste que chaque numéro de Z est contenu dans chaque sous-tableau.∧/,↑
peut être raccourci∧/∊
. J'ai fini, j'ai fini! ;-)If it passes, return "0" and if not, return a non-zero result.
Java / C # -
183/180181/178173/170 octets(Remplacer
boolean
parbool
pour C #)Formaté:
La méthode crée un tableau
u
avec 27 masques de bits, représentant les chiffres trouvés dans les neuf lignes, colonnes et carrés.Il itère ensuite sur toutes les cellules, effectuant l'opération
1 << a[x][y]
pour créer un masque binaire représentant le chiffre et OR avec sa colonne, sa ligne et son masque binaire carré avec lui.Il itère ensuite sur les 27 masques de bits, en veillant à ce qu'ils totalisent tous jusqu'à 27594 (1022 * 9, 1022 étant le masque de bits pour tous les chiffres 1 à 9 présents). (Notez que
y
se termine par 27603 car il contient déjà 9 après la double boucle.)Edit: accidentellement laissé dans un
%3
qui n'est plus nécessaire.Edit 2: Inspiré par le commentaire de Bryce Wagner, le code a été compressé un peu plus.
la source
python = 196
Pas le plus golfé, mais l'idée est là. Les ensembles sont assez utiles.
Planche:
Programme:
la source
n={*range(1,10)}
, mais c'est plus récent que le défi. Utilisez plutôtset(range(1,10))
MatrixFrog.Java -
385 306 328260 caractèresEdit: j'ai bêtement mal lu les instructions que la réponse devait être un programme complet. Comme il peut s'agir simplement d'une fonction valide, j'ai réécrit et minimisé pour être une fonction, et j'ai réécrit l'introduction de ma solution en gardant cela à l'esprit.
Donc, comme un défi pour moi, j'ai pensé que j'essaierais de faire le plus petit vérificateur de solutions Java.
Pour y parvenir, je suppose que le puzzle sudoku sera transmis sous forme de tableau multidimensionnel java, comme suit:
Ensuite, nous avons le solveur réel, qui renvoie "0" si la solution est valide, "1" sinon.
Entièrement golfé:
Lisible:
Alors, comment ça marche? Je crée simplement ma propre base de nombres avec une résolution suffisante dans chaque chiffre que je n'ai qu'à faire trois comparaisons numériques après avoir traversé le puzzle une fois pour savoir s'il est valide. J'ai choisi la base 49 pour ce problème, mais toute base supérieure à 45 serait suffisante.
Un exemple (espérons-le) clair: imaginez que chaque "ligne" dans le puzzle sudoku est un seul chiffre dans un nombre de base 49. Nous représenterons chaque chiffre du nombre en base 49 comme un nombre en base 10 dans un vecteur pour plus de simplicité. Donc, si toutes les lignes sont "correctes", nous nous attendons au nombre de base 49 suivant (en tant que vecteur de base 10):
ou converti en un seul numéro base-10:
1526637748041045
Suivez une logique similaire pour toutes les colonnes, et la même pour les "sous-grilles". Toute valeur rencontrée dans l'analyse finale qui n'est pas égale à ce "nombre idéal" signifie que la solution du puzzle n'est pas valide.
Modifier pour résoudre la vulnérabilité des all-5 et d'autres problèmes connexes: j'ajoute un quatrième nombre de base 49, basé sur l'idée qu'il devrait y avoir 9 de chaque nombre dans chaque puzzle. Donc, j'ajoute 5 à chaque chiffre du nombre de base 49 pour chaque occurrence du nombre de base 10 qui représente l'index du chiffre. Par exemple, s'il y a 10 9 et 9 8, 9 7, 8 6 et 9 de tous les autres, vous obtiendrez un nombre de base 49 (en tant que vecteur de base 10 de taille 10 pour faire face au débordement):
Ce qui échouera par rapport à notre nombre "idéal" de base 49.
Ma solution profite de cette solution mathématique, pour éviter autant que possible le bouclage et la comparaison. J'utilise simplement une
long
valeur pour stocker chaque numéro de base 49 en tant que numéro de base 10 et j'utilise un tableau de recherche pour obtenir les «facteurs» pour chaque chiffre de base 49 lors du calcul de la valeur de contrôle de colonne / ligne / sous-grille.Comme Java n'est pas conçu pour être concis, être prudent dans la construction mathématique était la seule façon dont je pensais pouvoir construire un vérificateur concis.
Laissez-moi savoir ce que vous pensez.
la source
R 145
Le code dé-golfé (plus ou moins) peut être trouvé ici /programming//a/21691541/1201032 .
la source
Haskell (Lambdabot), 65 octets
la source
Perl, 193 octets
L'entrée est attendue sous forme de tableau:
Le code de sortie est 0, si
@a
c'est une solution, sinon il1
est retourné.Version non golfée:
Chacune des 9 lignes, 9 colonnes et 9 sous-tableaux est placée dans un tableau trié et vérifiée, si elle correspond au tableau
(1..9)
. Le nombre$r
est incrémenté pour chaque correspondance réussie qui doit totaliser 27 pour une solution valide.la source
J
5254Prend son argument collé sur la ligne de commande, terminé par a) comme:
Renvoie 1 si passé, 0 sinon.
En interne, il convertit la grille 9x9 en une grille 3x3x3x3, et effectue quelques permutations sur les axes pour obtenir l'unité souhaitée (lignes, lignes et boîtes) dans les 2 dernières dimensions.
Après cela, il est vérifié que chaque unité a 9 valeurs uniques.
Probablement loin d'être parfait, mais bat déjà la majorité ;-)
la source
Mathematica,
8479 caractèresExemples:
la source
3
indique toujours une entrée non valide, ou est-ce parfois une réponse à une solution qui a échoué?Javascript ES6, 150 caractères
Prend l'entrée sous la forme d'une chaîne de 81 caractères sans aucun délimiteur.
La fonction renvoie
null
comme réponse négative et un tableau avec la chaîne d'origine dans le premier élément comme positif. Peut changer en bool en ajoutant!!
à la fonction au début.Test (voir défi connexe pour plus de détails):
la source
R,
6350 octetsSuppose que l'entrée
m
est une matrice de nombres 9x9.J'avais raison de dire que le golf était possible.
Explication:
Prenez
m
, et pour chaque ligne, appliquez lamatch
fonction. Nous spécifions un autre argumentx=1:9
à transmettre àmatch
.x
est le premier argument de position par défaut, et donc chaque ligne est placée dans la deuxième position d'argument, qui esttable
. La fonctionmatch
recherche les instances dex
intable
. Dans ce cas, alors, il recherche1:9
(les numéros 1 à 9) dans chaque ligne. Pour chacun1:9
, il retourneraTRUE
(ouFALSE
) si ce nombre est trouvé (ou non).Ainsi, cela donne une série de 81 valeurs booléennes.
Répétez ce qui précède pour chaque colonne de l'entrée.
Enfin,
all
vérifie si chaque élément de la liste des booléens l'estTRUE
. Ce sera le cas si et seulement si la solution est correcte (c'est-à-dire que chaque numéro1:9
n'est présent qu'une seule fois dans chaque colonne et chaque ligne).Ancienne approche:Il prend chaque ligne, la trie, puis la compare à[1, 2, ... 9]
. Une ligne correcte doit correspondre exactement. Ensuite, il fait de même pour chaque colonne. Au total, nous devrions avoir 162 correspondances exactes, ce que vérifie la dernière portion. Il y a probablement de la place pour continuer à jouer au golf ici ...la source
Haskell - 175
La fonction
v
est celle à appeler. Il fonctionne en obtenant la différence de chaque ligne, colonne et bloc par rapport à la liste[1..9]
et en additionnant les longueurs de ces listes de différence.Démo utilisant l'exemple Sudoku:
la source
Javascript - 149 caractères
S'attend à ce qu'un tableau
a
existe et crée une variableo
de sortie qui0
réussit et non nulle sinon.Fonctionne en vérifiant que la somme de la position à laquelle chaque valeur se produit pour chaque ligne, colonne et grille 3 * 3 est égale à 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8).
Essai
Donne 'o = 0'
(2 derniers chiffres échangés)
Donne
o=-1
Donne
o=-284
la source
Haskell,
121130127 octets (87 Lambdabot)les usages:
Lambdabot charge Data.List et Data.List.Split par défaut (je ne pense pas que la solution de BlackCap coche les cases).
Idées d'amélioration bienvenue
// Edit: j'ai foiré :)
// Edit: 3 octets enregistrés par BlackCap
la source
(map sort)
par(sort<$>)
.c$(sort<$>)<$>
avec$(sort<$>)=<<
05AB1E , 36 octets | Concurrence NoN |
Essayez-le en ligne!
1 est vrai, tout le reste est faux.
la source
Clojure, 151 octets
Assez long, mais d'autres semblent l'être aussi. Aussi ennuyeux que l'union des ensembles nécessite un
require
, j'ai donc utilisé une concaténation de vecteurs à la place.Itère sur chaque ligne et colonne et si la valeur est comprise entre 1 et 9, elle émet trois vecteurs, un pour la ligne, la colonne et la cellule 3x3. Retourne 0 en cas de succès et
nil
sinon, avec deux caractères supplémentaires pourrait retourner 1 en cas d'échec. Gère les nombres en dehors de 1 à 9 en retournantnil
mais plantera sur d'autres anomalies telles que les valeurs non entières. Les quotients sont compris entre 0 et 2, il est donc sûr d'utiliser des valeurs8
et9
de différencier les valeurs des cellules des lignes et des colonnes.L'entrée est un vecteur imbriqué de vecteurs (pour que ça
nth
marche):Non golfé:
la source
PHP,
196190 octetsLe programme prend 9 arguments de ligne de commande distincts (une chaîne de chiffres pour chaque ligne de la grille);
quitte avec
1
(erreur) pour invalide,0
(ok) pour valide.Courez avec
php -nr '<code>' <row1> <row2> ...
.panne
explication
count_chars
compte les caractères dans une chaîne et crée généralement un tableau avec des codes ascii comme clés et le nombre de caractères comme valeurs; mais avec3
comme paramètre mode, il crée une chaîne triée à partir des caractères; et cela peut facilement être comparé au nombre avec les chiffres voulus.La comparaison vérifie non seulement les doublons, mais inclut également la vérification des caractères non valides. Et il faut que
<
, non!=
, parce que c'est comparaison numérique: PHP interprétera la chaîne comme un nombre aussi loin que possible.123e56789
,0x3456789
ou similaire ne peut pas apparaître, car les caractères sont triés; et tout entier pur avec un chiffre manquant est plus petit que123456789
... et.23456789
aussi, bien sûr.$a=$argv
enregistre un octet,$d=123456789
neuf et$u=count_chars
13.la source
C # -
306298288 caractèresLe programme de console suivant a été utilisé pour appeler la fonction de vérification;
Il suffit d'initialiser le tableau et de le passer dans la fonction de vérification P.
La fonction de vérification est comme ci-dessous (sous forme Golfed);
Ou sous une forme entièrement présentée;
Cela utilise l'idée que toutes les colonnes, lignes et sous-grilles doivent totaliser jusqu'à 45. Cela fonctionne à travers le tableau d'entrée et soustrait la valeur de chaque position de sa ligne, colonne et sous-grille. Une fois terminé, il vérifie qu'aucune des lignes, colonnes ou sous-grilles n'a encore de valeur.
Comme demandé, renvoie un 0 si le tableau est une solution Sudoku valide et non nul (1) où il ne l'est pas.
la source
private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];
place. (Notez la suppression de l'espace après le crochet carré]
.) De plus, je ne suis pas sûr, mais je pense que vous pouvez vous débarrasser de laprivate static
.for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}
-à- dire que vous ne savez pas si cela fonctionne en C #. (Je ne connais pas vraiment C #)