Crear una solución de sudoku CHEQUEADOR


21

Crear una solución de Sudoku CHEQUEADOR

Aquí hay montones de SOLDADORES de Sudoku, pero quiero que crees una solución CHECKER tan pequeña como sea humanamente posible (code-golf).

  • Una entrada válida podrá tomar una matriz de 9x9 como argumento (pasado por referencia, serializado en la línea de comando, o como quiera tomarlo) o aceptar un archivo de entrada que tenga nueve líneas de nueve números para la grilla final . Ver ejemplos de entrada a continuación.

  • La entrada válida debe ser números de base 10 (1-9)

  • Las posiciones faltantes, vacías, extra, no numéricas, o las posiciones con números fuera del 1-9 deben rechazarse como una entrada no válida al devolver un resultado distinto de cero, imprimir un error o ambos.

  • Su programa necesita probar si cada número aparece una vez por columna, una vez por línea y una vez por cada subcuadrícula 3x3. Si pasa, devuelve "0" y si no, devuelve un resultado distinto de cero.

  • Se debe evitar el uso de recursos externos (sitios web, etc.).

  • Si su solución es un programa independiente, salir con un estado de salida o imprimir "0" o distinto de cero para "Pasar" o "Fallar", respectivamente, está bien.

¡Que gane la respuesta más pequeña!

Ejemplos de entrada:

matriz 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}
                };

archivo:

123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645

Las 9 subrejillas:

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

Respuestas:


5

GolfScript, 39 caracteres

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

Toma una matriz de matrices como entrada (ver ejemplo en línea ) y salidas 0si es una grilla válida.

Breve explicación del código.

.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

Me gusta que el resultado distinto de cero de su código sea más significativo que simplemente 1o-1
David Wilkins

Realmente me gustó su respuesta, pero al final elegí no ir con una solución de golfscript. Realmente espero que entiendas
David Wilkins

2
@DavidWilkins En realidad no entiendo: ¡usted hizo las reglas (!) Y no dijo en ningún lado que GolfScript no estaba permitido.
Howard

Su punto es completamente válido ... en verdad no tengo nada que justificar que no elija su respuesta. Bien jugado
David Wilkins

10

Python, 103

Odio el 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))))

Cómo funciona: cada fila, columna y bloque debe tener cada número del 1 al 9. Entonces, para cada 0 <= i, j < 9celda, la celda i,jestá en bloque 3*floor(i/3) + floor(j/3). Por lo tanto, hay 243 requisitos para satisfacer. Hago que cada requisito sea una tupla ((item index,item type number),symbol)donde item indexhay un número entre 0 y 8 (inclusive), item type numberes 0,1 o 2 para denotar fila, columna o bloque, respectivamente, y symboles la entrada b[i][j].

Editar: por error no verifiqué las entradas válidas. Ahora lo hago.


Su programa debe de salida 0si la solución pasa, noTrue
David Wilkins

@DavidWilkins qué requisito tan extraño. Fijo.
Boothby

Señor, obtenga mi voto por la forma en que comenzó su respuesta: D
Teun Pronk

9

APL (46)

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

Esto toma una matriz de 9 por 9. El ejemplo uno se puede ingresar en TryAPL así:

     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

Explicación:

  • ↓⍉⍵: obtener las columnas de ,
  • ↓⍵: obtener las filas de ,
  • 3/3⌿3 3⍴Z←⍳9: haga una matriz de 3 por 3 que contenga los números 1para 9, luego triplique cada número en ambas direcciones, dando una matriz de 9 por 9 con los números 1para 9indicar cada grupo,
  • Z∘.=: Para cada número 1a 9, hacer una máscara de bits para el grupo dado,
  • /∘(,⍵)¨: y enmascarar con cada uno, dando los grupos de .
  • ∊∘Z¨: para cada submatriz, vea si contiene los números 1para 9,
  • ∧/,↑: tome la lógica andde todos estos números juntos.

+1 Nice! Pero los grupos 3 × 3 se pueden jugar un poco más. Por ejemplo, esto ↓9 9⍴1 3 2⍉3 3 9⍴⍵es equivalente /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9pero bastante más corto. Estoy seguro de que hay fórmulas aún más cortas.
Tobia

Además, puede concatenar las matrices por primera dimensión y realizar una sola división al final:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Tobia

Hay un error: este código ∊∘Z¨está probando si cada sub-matriz (fila, columna o bloque) solo está hecha de los números 1 a 9. No está probando si todos los números están representados. Debe hacer algo como Z∘.∊qué pruebas de que cada número en Z está contenido en cada sub-matriz.
Tobia

Y esto ∧/,↑se puede acortar a ∧/∊. ¡Ya terminé, ya terminé! ;-)
Tobia

Muy compacto, pero te perdiste un punto crítico que puedo ver de inmediato:If it passes, return "0" and if not, return a non-zero result.
David Wilkins

5

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

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

(Cambiar booleana boolpara C #)

Formateado:

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

El método crea una matriz ucon 27 máscaras de bits, que representan los dígitos encontrados en las nueve filas, columnas y cuadrados.

Luego itera sobre todas las celdas, realizando la operación 1 << a[x][y]para crear una máscara de bits que representa el dígito y OR con su columna, fila y máscara de bits cuadrada.

Luego itera sobre las 27 máscaras de bits, asegurando que todas sumen 27594 (1022 * 9, 1022 es la máscara de bits para todos los dígitos 1-9 presentes). (Tenga en cuenta que ytermina como 27603 debido a que ya contiene 9 después del doble bucle).

Editar: accidentalmente dejado en un %3que ya no es necesario.

Edición 2: inspirado en el comentario de Bryce Wagner, el código se ha comprimido un poco más.


Casi el mismo algoritmo en caracteres C # 149 (pero solo si se permite Linq): bool s (int [] a) {int x = 0, y, j; var u = new int [27]; while (x ++ <(y = 9)) while (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 sería realmente útil. Sin embargo, mi solución es para Java con C # como una ocurrencia tardía (ni siquiera mencionada en la publicación original) y, por lo tanto, con menor prioridad. También utilicé matrices unidimensionales para la compacidad al principio antes de decidir en contra (ya que los ejemplos usan las bidimensionales). Sin embargo, su código me dio algunas ideas sobre cómo podrían eliminarse unos pocos bytes más. :)
Smallhacker

3

pitón = 196

No es el más golfista, pero la idea está ahí. Los sets son bastante útiles.

Tablero:

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

Programa:

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 (rango (1,10)) / guarda 3 caracteres.
MatrixFrog

En Python 3.5 puedes usar n={*range(1,10)}, pero eso es más nuevo que el desafío. En su lugar, use set(range(1,10))como dijo MatrixFrog.
mbomb007

3

Java: 385306328252 caracteres

Editar: tontamente leí mal las instrucciones de que la respuesta tenía que ser un programa completo. Como puede ser solo una función válida, he reescrito y minimizado para ser una función, y reescribí la introducción de mi solución con eso en mente.

Entonces, como un desafío para mí, pensé que intentaría hacer el verificador de soluciones Java más pequeño.

Para lograr esto, supongo que el rompecabezas sudoku se pasará como una matriz multidimensional de Java, de esta manera:

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

Luego, tenemos el solucionador real, que devuelve "0" si la solución es válida, "1" si no.

Completamente golfizado:

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

Legible:

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

Entonces, ¿cómo funciona esto? Básicamente, creo mi propia base de números con una resolución suficiente en cada dígito que solo tengo que hacer tres comparaciones numéricas después de pasar por el rompecabezas una vez para saber si es válido. Elegí la base 49 para este problema, pero cualquier base mayor que 45 sería suficiente.

Un ejemplo (con suerte) claro: imagine que cada "fila" en el rompecabezas de sudoku es un solo dígito en un número de base 49. Representaremos cada dígito en el número de base 49 como un número de base 10 en un vector por simplicidad. Entonces, si todas las filas son "correctas", esperamos el siguiente número de base 49 (como un vector de base 10):

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

o convertido a un solo número de base 10: 1526637748041045

Siga una lógica similar para todas las columnas, y lo mismo para las "sub-cuadrículas". Cualquier valor encontrado en el análisis final que no sea igual a este "número ideal" significa que la solución del rompecabezas no es válida.

Edite para resolver la vulnerabilidad de todos los 5 y otros problemas relacionados: agrego un cuarto número de base 49, basado en la idea de que debería haber 9 de cada número en cada rompecabezas. Entonces, agrego 5 a cada dígito en el número de base 49 para cada aparición del número de base 10 que representa el índice del dígito. Un ejemplo, si hay 10 9 y 9 8, 9 7, 8 6 y 9 de todos los demás, obtendría un número de base 49 (como un vector de base 10 de tamaño 10 para tratar el desbordamiento):

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

Lo cual fallará en comparación con nuestro número "ideal" de base 49.

Mi solución aprovecha esta solución matemática para evitar la mayor cantidad posible de bucles y comparación. Simplemente uso un longvalor para almacenar cada número de base 49 como un número de base 10 y utilizo una matriz de búsqueda para obtener los "factores" para cada dígito de base 49 durante el cálculo del valor de verificación de columna / fila / subcuadrícula.

Como Java no está diseñado para ser conciso, tener cuidado en la construcción matemática fue la única forma en que pensé que podría construir un corrector conciso.

Déjame saber lo que piensas.


1
En realidad, esto sufre de la misma vulnerabilidad mencionada por @ steve-verrill: los 5, o cualquier conjunto de números que sume a 45, "engañarán" al solucionador. Voy a revisar Tengo una idea de cómo superar eso.
ProgramadorDan

He abordado esta vulnerabilidad en mi última actualización. Ahora se aborda ese caso y todos los demás de su tipo. Básicamente, fue un descuido serio no tratar con "conteos" de cada tipo de dígitos de base 10. Ahora realizo esa verificación directamente, pero usando el mismo enfoque matemático (número base 49).
ProgramadorDan

Dan, gracias por el reconocimiento. Lo vi y me pregunté por qué no me notificaron, pero veo que pones un guión a mi nombre. Esto parece haber confundido el sistema. Simplemente omita el espacio. Consideraré cambiar la forma en que se muestra mi nombre.
Level River St

Ahha, eso lo explica. Gracias @steveverrill. Todavía me estoy acostumbrando a la forma de hacer las cosas en stackexchange. Dicho esto, tu hazaña concisa del principio de la suma 45 se declaró brillantemente. Hice mi solución más larga para superarla, ¡pero así es la vida!
ProgramadorDan


3

Haskell (Lambdabot), 65 bytes

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

2

Perl, 193 bytes

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)

La entrada se espera en forma de matriz:

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

El código de salida es 0, si @aes una solución, de lo contrario 1se devuelve.

Versión sin golf:

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

Cada una de las 9 filas, 9 columnas y 9 sub matrices se colocan en una matriz ordenada y se comprueba si coincide con la matriz (1..9). El número $rse incrementa para cada coincidencia exitosa que debe sumar hasta 27 para una solución válida.


2

J 52 54

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

Toma su argumento pegado en la línea de comando, terminó con a) como:

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
)

Devuelve 1 si se pasa, 0 si no.

Internamente, convierte la cuadrícula de 9x9 en una cuadrícula de 3x3x3x3 y realiza algunas permutaciones en los ejes para obtener la unidad deseada (filas, líneas y cuadros) en las últimas 2 dimensiones.

Después de hacer eso, se verifica que cada unidad tenga 9 valores únicos.

Probablemente lejos de ser perfecto, pero ya supera a la mayoría ;-)


A primera vista, ha sido atrapado por el mismo requisito que algunos de los otros ... Sus devoluciones deben revertirse ... 0 para pasar, no cero para fallar
David Wilkins

0 para pasar es idiota. Hay una razón por la cual Boole eligió 1 para verdadero y 0 para falso. Pero tienes razón. Agrega 2 caracteres.
jpjacobs

Piense en ello como un estado de salida, no un valor booleano
David Wilkins

Elijo tu respuesta porque funciona. Seguiste las reglas y tu programa es muy corto. ¡Gracias!
David Wilkins

Bueno, me engañé ... En verdad, no puedo justificar no elegir la respuesta de Golfscript que es más corta que la tuya ... Pero felicitaciones por el segundo lugar
David Wilkins

2

Mathematica, 84 79 caracteres

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

Ejemplos:

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


Su tercer ejemplo de salida: ¿Es 3siempre indicativo de una entrada inválida, o es a veces una respuesta a una solución fallida?
David Wilkins

2

Javascript ES6, 150 caracteres

Toma la entrada como una cadena de 81 caracteres sin delimitadores.

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

La función regresa nullcomo respuesta negativa y una matriz con una cadena original en el primer elemento como positiva. Puede cambiar a bool agregando !!a la función de inicio.

Prueba (ver desafío relacionado para más detalles):

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

Esa es una expresión ridícula ... Un trabajo increíble.
ETHproductions

2

R, 63 50 bytes

Asume que la entrada mes una matriz de números 9x9.

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

Tenía razón en que era posible seguir jugando al golf.

Explicación:

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

Tome m, y para cada fila, aplique la matchfunción. Especificamos un argumento adicional x=1:9para pasar match. xes el argumento predeterminado de la primera posición y, por lo tanto, cada fila se coloca en la segunda posición del argumento, que es table. La función matchbusca instancias de xin table. En este caso, entonces, está buscando 1:9(los números del 1 al 9) en cada fila. Para cada uno 1:9, devolverá TRUE(o FALSE) si se encuentra ese número (o no).

Entonces, esto produce una serie de 81 valores booleanos.

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

Repita lo anterior para cada columna de la entrada.

all(                                             )

Finalmente, allverifica si cada elemento de la lista de booleanos es TRUE. Este será el caso si y solo si la solución es correcta (es decir, cada número 1:9está presente solo una vez en cada columna y cada fila).

Viejo enfoque:

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

Toma cada fila, la ordena y luego la compara [1, 2, ... 9]. Una fila correcta debe coincidir exactamente. Luego hace lo mismo para cada columna. En total, deberíamos tener 162 coincidencias exactas, que es lo que verifica la parte final. Es probable que haya algún margen para seguir jugando al golf aquí ...


Parece que está buscando columnas y filas, pero no cuadros ...
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 función ves la que hay que llamar. Funciona obteniendo la diferencia de cada fila, columna y bloque contra la lista [1..9]y sumando las longitudes de esas listas de diferencias.

Demo usando el ejemplo 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 caracteres

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]

Espera aque exista una matriz y crea una variable opara la salida que tiene 0éxito y, de lo contrario, no es cero.

Funciona comprobando que la suma de la posición en la que se produce cada valor para cada fila, columna y cuadrícula 3 * 3 es igual a 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8).

Pruebas

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

Da '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]
  ];

(Últimos 2 dígitos intercambiados)

Da 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]
  ];

Da o=-284


1

Haskell, 121 130 127 bytes (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]

usos:

-- 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 carga Data.List y Data.List.Split de forma predeterminada (no creo que la solución de BlackCap marque las casillas).

Ideas de mejora bienvenidas

// Editar: me equivoqué :)
// Editar: 3 bytes guardados por BlackCap


Tienes razón, no noté que verificar las filas y columnas no es suficiente ...
BlackCap

bueno, me
equivoqué

1
Puede reemplazar (map sort)con(sort<$>)
BlackCap

1
Y .c$(sort<$>)<$>con$(sort<$>)=<<
BlackCap

oh my, debería haber recordado esos 2
michi7x7


0

Clojure, 151 bytes

Bastante largo, pero otros parecen serlo también. También es molesto que la unión de conjuntos requiera un require, así que usé un concat de vectores en su lugar.

Itera sobre cada fila y columna y si el valor está entre 1 y 9, emite tres vectores, uno para fila, col y celda 3x3. Devuelve 0 en caso de éxito y nil, de lo contrario, con dos caracteres adicionales podría devolver 1 en caso de error. Maneja los números fuera del 1 al 9 al regresar, nilpero se bloqueará en otras anomalías, como los valores no enteros. Los cocientes son 0 - 2, por lo que es seguro usar valores 8y 9diferenciar los valores de celda de filas y columnas.

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

La entrada es un vector anidado de vectores (para que nthfuncione):

(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]])

Sin 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 bytes

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

El programa toma 9 argumentos de línea de comando separados (una cadena de dígitos para cada línea de la cuadrícula);
sale con 1(error) para inválido, 0(ok) para válido.

Corre con php -nr '<code>' <row1> <row2> ....

Descompostura

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
}

explicación

count_charscuenta los caracteres en una cadena y generalmente crea una matriz con códigos ascii como claves y los caracteres cuentan como valores; pero con 3como parámetro de modo, crea una cadena ordenada a partir de los caracteres; y eso se puede comparar fácilmente con el número con los dígitos deseados.

La comparación no solo busca duplicados, sino que también incluye la verificación de caracteres no válidos. Y solo requiere <, no !=, porque esta es una comparación numérica: PHP interpretará la cadena como un número en la medida de lo posible. 123e56789, 0x3456789o similar no puede aparecer, porque los caracteres están ordenados; y cualquier entero puro con un dígito faltante es más pequeño que 123456789... y .23456789también, por supuesto.

$a=$argvahorra un byte, $d=123456789salva nueve y $u=count_charssalva 13.


-1

C # - 306 298 288 caracteres

El siguiente programa de consola se usó para llamar a la función de verificación;

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

Todo lo que hace es inicializar la matriz y pasarla a la función de verificación P.

La función de verificación es la siguiente (en forma de Golf);

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

O en forma completamente establecida;

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

Esto utiliza la idea de que todas las columnas, filas y subcuadrículas deben sumar 45. Funciona a través de la matriz de entrada y resta el valor de cada posición de su fila, columna y subcuadrícula. Una vez completado, verifica que ninguna de las filas, columnas o subcuadrículas aún tenga un valor.

Según lo solicitado, devuelve un 0 si la matriz es una solución de Sudoku válida y no es cero (1) donde no lo es.


Creo que puede guardar algunos caracteres utilizando en su private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];lugar. (Tenga en cuenta la eliminación del espacio después del corchete cerrado ]). Además, no estoy seguro, pero creo que puede deshacerse de él private static.
usuario12205

Además, para la última parte, en C podemos eliminar algunas llaves for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}, es decir , no estoy seguro si funciona en C #. (En realidad no sé C #)
usuario12205

@ace: he realizado varias mejoras basadas en sus sugerencias. Ahora hasta 298 caracteres.
Será el

Recortó otros 10 caracteres basados ​​en los comentarios de @ace.
Será el

1
¿Qué sucede con una matriz llena de números 5? Todas las filas, columnas y cuadrados suman 45.
Level River St
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.