Créer une solution sudoku CHECKER


21

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|
+---+---+---+

Réponses:


5

GolfScript, 39 caractères

.zip.{3/}%zip{~}%3/{[]*}%++{$10,1>=!},,

Il prend un tableau de tableaux en entrée (voir l' exemple en ligne ) et sort 0s'il s'agit d'une grille valide.

Brève explication du code

.zip         # Copy the input array and transpose it
.{3/}%       # Split each line into 3 blocks
zip{~}%      # Transpose these blocks
3/{[]*}%     # Do the same for the lines themselves and join again
++           # Make one large list of 27 9-element arrays 
             # (9 for rows, 9 for columns, 9 for blocks)
{$10,1>=!},  # From those 27 select the ones which are not a permutation of [1 2 3 ... 9]
             #   $      -> sort
             #   10,1>  -> [1 2 3 ... 9]
             #   =!     -> not equal
,            # Count after filtering

J'aime que la sortie non nulle de votre code soit plus significative que juste 1ou-1
David Wilkins

J'ai vraiment aimé votre réponse mais au final j'ai choisi de ne pas opter pour une solution golfscript. J'espère vraiment que vous comprenez
David Wilkins

2
@DavidWilkins En fait, je ne comprends pas - vous avez fait les règles (!) Et n'avez déclaré nulle part que GolfScript n'était pas autorisé.
Howard

Votre point est tout à fait valable ... en vérité, je n'ai rien à justifier de ne pas choisir votre réponse. Bien joué
David Wilkins

10

Python, 103

Je déteste le sudoku.

b = [[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]]

e=enumerate;print 243-len(set((a,t)for(i,r)in e(b)for(j,t)in e(r)for a in e([i,j,i/3*3+j/3]*(0<t<10))))

Comment ça marche: chaque ligne, colonne et bloc doit avoir chaque numéro de 1 à 9. Donc pour chacun 0 <= i, j < 9, la cellule i,jest en bloc 3*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)item indexest un nombre compris entre 0 et 8 (inclus), item type number0,1 ou 2 pour désigner respectivement une ligne, une colonne ou un bloc, et symbolest l'entréeb[i][j] .

Edit: par erreur, je n'ai pas vérifié les entrées valides. Maintenant oui.


Votre programme devrait sortir 0si la solution passe, pasTrue
David Wilkins

@DavidWilkins quelle exigence étrange. Fixé.
stand

Vous obtenez mon vote pour la façon dont vous avez commencé votre réponse: D
Teun Pronk

9

APL (46)

{∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵}

Cela prend une matrice 9 par 9. L'exemple peut être entré sur TryAPL comme ceci:

     sudoku ← ↑(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)
     {∧/,↑∊∘Z¨(/∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9),(↓⍵),↓⍉⍵} sudoku
1

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 nombres 1à 9, puis tripler chaque nombre dans les deux sens, en donnant une matrice 9 x 9 avec les nombres 1pour 9indiquer chaque groupe,
  • Z∘.=: pour chaque nombre 1à 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 nombres 1à 9,
  • ∧/,↑: prenez la logique andde tous ces nombres ensemble.

+1 Sympa! Mais les groupes 3 × 3 peuvent encore être joués au golf. Par exemple, cela ↓9 9⍴1 3 2⍉3 3 9⍴⍵équivaut à /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9mais est assez court. Je suis sûr qu'il existe des formules encore plus courtes.
Tobia

En outre, vous pouvez concaténer les matrices par 1ère dimension et effectuer une seule division à la fin:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Tobia

Il y a un bug: ce code ∊∘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 comme Z∘.∊qui teste que chaque numéro de Z est contenu dans chaque sous-tableau.
Tobia

Et cela ∧/,↑peut être raccourci ∧/∊. J'ai fini, j'ai fini! ;-)
Tobia

Très compact, mais vous avez raté un point critique que je peux voir tout de suite:If it passes, return "0" and if not, return a non-zero result.
David Wilkins

5

Java / C # - 183/180 181/178 173/170 octets

boolean s(int[][]a){int x=0,y,j;int[]u=new int[27];for(;x<(y=9);x++)while(y>0){j=1<<a[x][--y];u[x]|=j;u[y+9]|=j;u[x/3+y/3*3+18]|=j;}for(x=0;x<27;)y+=u[x++];return y==27603;}

(Remplacer booleanpar boolpour C #)

Formaté:

boolean s(int[][] a){
    int x=0, y, j;
    int[] u=new int[27];
    for(;x<(y=9);x++)
        while(y>0){
            j=1<<a[x][--y];
            u[x]|=j;
            u[y+9]|=j;
            u[x/3+y/3*3+18]|=j;
        }

    for(x=0;x<27;)
        y+=u[x++];

    return y==27603;
}

La méthode crée un tableau uavec 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 yse termine par 27603 car il contient déjà 9 après la double boucle.)

Edit: accidentellement laissé dans un %3qui n'est plus nécessaire.

Edit 2: Inspiré par le commentaire de Bryce Wagner, le code a été compressé un peu plus.


Presque le même algorithme dans les caractères C # 149 (mais seulement si Linq est autorisé): bool s (int [] a) {int x = 0, y, j; var u = new int [27]; while (x ++ <(y = 9)) tandis que (y> 0) {j = 1 << a [x + 9 * - y]; u [x] | = j; u [y + 9] | = j; u [x / 3 + y / 3 * 3 + 18] | = j;} return u.Sum () == 27594;}
Bryce Wagner

@BryceWagner Linq serait en effet utile. Cependant, ma solution est pour Java avec C # étant une réflexion après coup (pas même mentionnée dans le message d'origine) et donc une priorité inférieure. J'ai également utilisé des tableaux unidimensionnels pour la compacité au début avant de décider contre (car les exemples utilisent des tableaux bidimensionnels). Néanmoins, votre code m'a donné quelques idées sur la façon dont quelques octets supplémentaires pourraient être supprimés. :)
Smallhacker

3

python = 196

Pas le plus golfé, mais l'idée est là. Les ensembles sont assez utiles.

Planche:

b = [[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]]

Programme:

n={1,2,3,4,5,6,7,8,9};z=0
for r in b:
 if set(r)!=n:z=1
for i in zip(*b):
 if set(i)!=n:z=1
for i in (0,3,6):
 for j in (0,3,6):
  k=j+3
  if set(b[i][j:k]+b[i+1][j:k]+b[i+2][j:k])!=n:z=1
print(z)

s / {1,2,3,4,5,6,7,8,9} / set (plage (1,10)) / enregistre 3 caractères.
MatrixFrog

En Python 3.5, vous pouvez utiliser n={*range(1,10)}, mais c'est plus récent que le défi. Utilisez plutôt set(range(1,10))MatrixFrog.
mbomb007

3

Java - 385 306 328 260 caractères

Edit: 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:

s(new int[][] {
    {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}});

Ensuite, nous avons le solveur réel, qui renvoie "0" si la solution est valide, "1" sinon.

Entièrement golfé:

int s(int[][] s){int i=0,j,k=1;long[] f=new long[9];long r=0L,c=r,g=r,z=45L,q=r;for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}for(;i<9;i++){for(j=0;j<9;){k=s[i][j];r+=k*f[i];c+=k*f[j];g+=k*f[j++/3+3*(i/3)];q+=5*f[k-1];}}return (r==z&&c==z&&g==z&&q==z)?0:1;}

Lisible:

    int s(int[][] s) {
        int i=0,j,k=1;
        long[] f=new long[9]; 
        long r=0L,c=r,g=r,z=45L,q=r;
        for(f[0]=1L;k<9;){f[k]=f[k-1]*49;z+=f[k++]*45;}
        for(;i<9;i++) {
            for (j=0;j<9;) {
                k=s[i][j];
                r+=k*f[i];
                c+=k*f[j];
                g+=k*f[j++/3+3*(i/3)];
                q+=5*f[k-1];
            }
        }
        return (r==z&&c==z&&g==z&&q==z)?0:1;
    }

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):

(45,45,45,45,45,45,45,45,45)

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):

(1, 1, 45, 45, 40, 45, 45, 45, 45, 45)

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 longvaleur 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.


1
En fait, cela souffre de la même vulnérabilité mentionnée par @ steve-verrill - tous les 5, ou tout ensemble de nombres qui s'élève à 45, "tromperont" le solveur. Je vais réviser. J'ai une idée de comment battre ça.
ProgrammerDan

J'ai corrigé cette vulnérabilité dans ma dernière mise à jour. Maintenant, ce cas est traité, et tous les autres de son type. Fondamentalement, il s'agissait d'un grave oubli de ne pas traiter les "décomptes" de chaque type de chiffre de base 10. J'effectue maintenant cette vérification directement, mais en utilisant la même approche mathématique (nombre en base 49).
ProgrammerDan

Dan, merci pour la reconnaissance. Je l'ai vu et je me suis demandé pourquoi je n'ai pas été averti, mais je vois que tu as mis un tiret en mon nom. Cela semble avoir confondu le système. Omettez simplement l'espace. J'envisagerai de changer la façon dont mon nom est affiché.
Level River St

Ahha, ça explique ça. Merci @steveverrill - Je m'habitue toujours à la manière de faire les choses avec stackexchange. Cela dit, votre exploit concis du principe de la somme de 45 a été brillamment déclaré. J'ai rallongé ma solution pour la surmonter, mais c'est la vie!
ProgrammeurDan


3

Haskell (Lambdabot), 65 octets

k x=and$(all$([1..9]==).sort)<$>[x,transpose x,join$chunksOf 3 x]

2

Perl, 193 octets

for(@x=1..9){$i=$_-1;@y=();push@y,$a[$i][$_-1]for@x;@y=sort@y;$r+=@y~~@x;@y=();push@y,$a[3*int($i/3)+$_/3][3*($i%3)+$_%3]for 0..8;@y=sort@y;$r+=@y~~@x}for(@a){@y=sort@$_;$r+=@y~~@x}exit($r!=27)

L'entrée est attendue sous forme de tableau:

@a=(
    [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]
);

Le code de sortie est 0, si @ac'est une solution, sinon il 1est retourné.

Version non golfée:

@x = (1..9);
for (@x) {
    $i = $_ - 1;
    # columns
    @y = ();
    for (@x) {
        push @y, $a[$i][$_-1];
    }
    @y = sort @y;
    $r += @y ~~ @x;
    # sub arrays
    @y = ();
    for (0..8) {
        push @y, $a[ 3 * int($i / 3) + $_ / 3 ][ 3 * ($i % 3) + $_ % 3 ];
    }
    @y = sort @y;
    $r += @y ~~ @x
}
# rows
for (@a) {
    @y = sort @$_;
    $r += @y ~~ @x
}
exit ($r != 27);

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 $rest incrémenté pour chaque correspondance réussie qui doit totaliser 27 pour une solution valide.


2

J 52 54

-.*/,(9=#)@~.@,"2(0 3 16 A.i.4)&|:(4#3)($,)".;._2]0 :0

Prend son argument collé sur la ligne de commande, terminé par a) comme:

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
)

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é ;-)


À première vue, vous avez été pris par la même exigence que certains des autres .... Vos retours devraient être inversés ... 0 pour réussir, non nul pour échouer
David Wilkins

0 pour passer est idiot. Il y a une raison pour laquelle Boole a choisi 1 pour vrai et 0 pour faux. Mais tu as raison. Ajoute 2 caractères.
jpjacobs

Considérez-le comme un statut de sortie, pas une valeur booléenne
David Wilkins

Je choisis ta réponse parce que ça marche. Vous avez suivi les règles et votre programme est très court. Merci!
David Wilkins

Eh bien, je me suis trompé ... En vérité, je ne peux pas justifier de ne pas choisir la réponse Golfscript qui est plus courte que la vôtre ... Mais bravo pour la 2e place
David Wilkins

2

Mathematica, 84 79 caractères

f=Tr[Norm[Sort@#-Range@9]&/@Join[#,Thread@#,Flatten/@Join@@#~Partition~{3,3}]]&

Exemples:

f[{{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}}]

0

f[{{2,1,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}}]

2

f[{{0,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}}]

3


Votre troisième exemple de sortie: 3indique toujours une entrée non valide, ou est-ce parfois une réponse à une solution qui a échoué?
David Wilkins

2

Javascript ES6, 150 caractères

Prend l'entrée sous la forme d'une chaîne de 81 caractères sans aucun délimiteur.

s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))

La fonction renvoie nullcomme 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):

f=s=>s.match("^(?=(#.{0,8}#.{9})+$)(?=(#(.{9}){0,8}#.){9})((#.?.?(.{9}){0,2}#...){3}.{18})+$".replace(/#(.*?)#/g,"123456789".replace(/./g,"(?=$$1$&)")))
;`123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298`
.split`
`.every(f)
&&
`519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825`
.split`
`.every(s => !f(s))

C'est un regex ridicule ... Un travail incroyable.
ETHproductions

2

R, 63 50 octets

Suppose que l'entrée mest une matrice de nombres 9x9.

all(apply(m,1,match,x=1:9),apply(m,2,match,x=1:9))

J'avais raison de dire que le golf était possible.

Explication:

    apply(m,1,match,x=1:9),

Prenez m, et pour chaque ligne, appliquez la matchfonction. Nous spécifions un autre argument x=1:9à transmettre àmatch . xest le premier argument de position par défaut, et donc chaque ligne est placée dans la deuxième position d'argument, qui est table. La fonction matchrecherche les instances de xin table. Dans ce cas, alors, il recherche 1:9(les numéros 1 à 9) dans chaque ligne. Pour chacun 1:9, il retournera TRUE(ou FALSE) si ce nombre est trouvé (ou non).

Ainsi, cela donne une série de 81 valeurs booléennes.

                           apply(m,2,match,x=1:9)

Répétez ce qui précède pour chaque colonne de l'entrée.

all(                                             )

Enfin, allvérifie si chaque élément de la liste des booléens l'est TRUE. Ce sera le cas si et seulement si la solution est correcte (c'est-à-dire que chaque numéro 1:9n'est présent qu'une seule fois dans chaque colonne et chaque ligne).

Ancienne approche:

for(i in 1:2)F=F+apply(m,i,function(x)sort(x)==1:9);sum(F)==162

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 ...


On dirait que vous vérifiez les colonnes et les lignes, mais pas les cases ...
JayCe

1

Haskell - 175

import Data.List
c=concat
m=map
q=[1..9]
w=length.c.m (\x->(x\\q)++(q\\x))
b x=c.m(take 3.drop(3*mod x 3)).take 3.drop(3*div x 3)
v i=sum$m(w)[i,transpose i,[b x i|x<-[0..8]]]

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:

*Main> :l so-22443.hs 
[1 of 1] Compiling Main             ( so-22443.hs, interpreted )
Ok, modules loaded: Main.
*Main> v [[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]]
0

1

Javascript - 149 caractères

r=[];c=[];g=[];for(i=9;i;)r[o=--i]=c[i]=g[i]=36;for(x in a)for(y in z=a[x]){r[v=z[y]-1]-=y;c[v]-=x;g[v]-=3*(x/3|0)+y/3|0}for(i in r)o|=r[i]|c[i]|g[i]

S'attend à ce qu'un tableau aexiste et crée une variable ode sortie qui 0ré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

a=[
    [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]
  ];

Donne 'o = 0'

a=[
    [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,5,4]
  ];

(2 derniers chiffres échangés)

Donne o=-1

a=[
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],

    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5],
    [5,5,5, 5,5,5, 5,5,5]
  ];

Donne o=-284


1

Haskell, 121 130 127 octets (87 Lambdabot)

import Data.List
import Data.List.Split
c=concat
t=transpose
k=chunksOf
p x=all(==[1..9])$(sort<$>)=<<[x,t x,k 9.c.c.t$k 3<$>x]

les usages:

-- k 9.c.c.t$k 3<$> x = chunksOf 9 $ concat $ concat $ transpose $ map chunksOf 3 x

let ts = k 9$[10*a+b|a<-[1..9],b<-[1..9]] --yep, this is ugly
in k 9.c.c.t$k 3<$>ts
-- prints:
--[[11,12,13,21,22,23,31,32,33],[41,42,43,51,52,53,61,62,63],[71,72,73,81,82,83,91,92,93],[14,15,16,24,25,26,34,35,36],[44,45,46,54,55,56,64,65,66],[74,75,76,84,85,86,94,95,96],[17,18,19,27,28,29,37,38,39],[47,48,49,57,58,59,67,68,69],[77,78,79,87,88,89,97,98,99]]

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


Vous avez raison, je n'ai pas remarqué que la vérification des lignes et des colonnes ne suffit pas ..
BlackCap

eh bien, j'ai aussi foiré :)
michi7x7

1
Vous pouvez remplacer (map sort)par(sort<$>)
BlackCap

1
Et .c$(sort<$>)<$>avec$(sort<$>)=<<
BlackCap

oh mon
Dieu


0

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 nilsinon, avec deux caractères supplémentaires pourrait retourner 1 en cas d'échec. Gère les nombres en dehors de 1 à 9 en retournant nilmais 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 valeurs 8et 9de différencier les valeurs des cellules des lignes et des colonnes.

(fn[s](if(= 243(count(set(apply concat(for[i(range 9)j(range 9)](let[v(nth(nth s i)j)q #(quot % 3)](if(<= 1 v 9)[[8 v i][9 v j][(q i)(q j)v]])))))))0))

L'entrée est un vecteur imbriqué de vecteurs (pour que ça nthmarche):

(def sudoku [[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]])

Non golfé:

(defn f [s]
  (->> (for [i (range 9) j (range 9)]
         (let [v (-> s (nth i) (nth j)) q #(quot % 3)]
           (if (<= 1 v 9)
             [[:row v i] [:col v j] [:cell [(q i) (q j)] v]])))
    (apply concat)
    set
    count
    (#(if (= 243 %) :pass :fail))))

0

PHP, 196 190 octets

while($i<9){for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];for(;$k<3;)$c.=substr($a[++$k+$i-$i%3],$i%3*3,3);if(($u=count_chars)($a[++$i],3)<($d=123456789)|$u($b,3)<$d|$u($c,3)<$d)die(1);}

Le 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

while($i<9)
{
    for($b=$c=$k=$y="";$y++<9;)$b.=($a=$argv)[$y][$i];  // column to string
    for(;$k++<3;)$c.=substr($a[$i-$i%3+$k],$i%3*3,3);   // sub-grid to string
    if(($u=count_chars)($a[++$i],3)<($d=123456789)      // check row
        |$u($b,3)<$d                                    // check column
        |$u($c,3)<$d                                    // check sub-grid
    )die(1);                                            // test failed: exit with 1
}

explication

count_charscompte 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 avec 3comme 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, 0x3456789ou similaire ne peut pas apparaître, car les caractères sont triés; et tout entier pur avec un chiffre manquant est plus petit que 123456789... et.23456789 aussi, bien sûr.

$a=$argvenregistre un octet, $d=123456789neuf et $u=count_chars13.


-1

C # - 306 298 288 caractères

Le programme de console suivant a été utilisé pour appeler la fonction de vérification;

static void Main(string[] args)
    {
        int[,] i={{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}
            };

            Console.Write(P(i).ToString());
    }

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);

private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];for(int p=0;p<9;p++){r[p]=45;c[p]=45;g[p]=45;}for(int y=0;y<9;y++){for(int x=0;x<9;x++){r[y]-=i[x,y];c[x]-=i[x,y];int k=(x/3)+((y/3)*3);g[k]-=i[x,y];}}for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}

Ou sous une forme entièrement présentée;

    private static int P(int[,] i)
    {
        int[] r = new int[9],c = new int[9],g = new int[9];
        for (int p = 0; p < 9; p++)
        {
            r[p] = 45;
            c[p] = 45;
            g[p] = 45;
        }

        for (int y = 0; y < 9; y++)
        {
            for (int x = 0; x < 9; x++)
            {
                r[y] -= i[x, y];

                c[x] -= i[x, y];

                int k = (x / 3) + ((y / 3) * 3);
                g[k] -= i[x, y];
            }
        }

        for (int p = 0; p < 9; p++)
            if (r[p] > 0 | c[p] > 0 | g[p] > 0) return 1;

        return 0;
    }

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.


Je pense que vous pouvez enregistrer quelques caractères en utilisant à la 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 la private static.
user12205

De plus, pour la dernière partie, en C, nous pouvons supprimer quelques accolades, c'est 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 #)
user12205

@ace - J'ai apporté plusieurs améliorations en fonction de vos suggestions. Maintenant à 298 caractères.
Will

Coupé 10 autres caractères sur la base des commentaires de @ace.
Will

1
Que se passe-t-il avec un tableau plein de numéros 5? Toutes les lignes, colonnes et carrés totalisent jusqu'à 45.
Level River St
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.