Crea una soluzione di sudoku CHECKER


21

Crea una soluzione Sudoku CHECKER

Ci sono un sacco di Sudoku SOLVERS qui, ma voglio che tu crei una soluzione CHECKER il più piccolo possibile umanamente (code-golf).

  • Una voce valida sarà in grado di prendere un array 9x9 come argomento (passato per riferimento, serializzato sulla riga di comando, o comunque tu voglia prenderlo) o accettare un file di input che è nove righe di nove numeri per la griglia finale . Vedi esempi di input di seguito.

  • I valori validi devono essere numeri di base 10 (1-9)

  • Le posizioni mancanti, vuote, extra, non numeriche o le posizioni con numeri al di fuori di 1-9 devono essere rifiutate come input non validi restituendo un risultato diverso da zero, stampando un errore o entrambi.

  • Il tuo programma deve verificare se ogni numero appare una volta per colonna, una volta per riga e una volta per sub-griglia 3x3. Se passa, restituisce "0" e, in caso contrario, restituisce un risultato diverso da zero.

  • L'uso di risorse esterne (siti Web, ecc.) Deve essere evitato.

  • Se la tua soluzione è un programma autonomo, uscire con uno stato di uscita o stampare "0" o diverso da zero per "Pass" o "Fail", rispettivamente, va bene.

Lascia vincere la risposta più piccola!

Esempi di input:

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

file:

123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645

Le 9 griglie secondarie:

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

Risposte:


5

GolfScript, 39 caratteri

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

Prende una matrice di matrici come input (vedi esempio online ) e 0se è una griglia valida.

Breve spiegazione del codice

.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

Mi piace che l'output diverso da zero del tuo codice sia più significativo del semplice 1o-1
David Wilkins

Mi è piaciuta molto la tua risposta, ma alla fine ho scelto di non scegliere una soluzione di golfscript. Spero davvero che tu capisca
David Wilkins

2
@DavidWilkins In realtà non capisco - hai fatto le regole (!) E non hai dichiarato da nessuna parte che GolfScript non era permesso.
Howard

Il tuo punto è del tutto valido ... in verità non ho nulla da giustificare non scegliere la tua risposta. Ben suonato
David Wilkins

10

Python, 103

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

Come funziona: ogni riga, colonna e blocco deve avere ogni numero compreso tra 1 e 9. Quindi per ogni 0 <= i, j < 9cella la cella i,jè in blocco 3*floor(i/3) + floor(j/3). Pertanto, ci sono 243 requisiti da soddisfare. Rendo ogni requisito una tupla ((item index,item type number),symbol)dove item indexc'è un numero compreso tra 0 e 8 (compreso), item type numberè 0,1 o 2 per indicare rispettivamente riga, colonna o blocco ed symbolè la voce b[i][j].

Modifica: per errore non ho verificato la presenza di voci valide. Ora faccio.


Il tuo programma dovrebbe uscire 0se la soluzione passa, nonTrue
David Wilkins

@DavidWilkins che requisito strano. Fisso.
stand

Signore, ricevete il mio voto solo per il modo in cui avete iniziato la vostra risposta: D
Teun Pronk,

9

APL (46)

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

Questo richiede una matrice 9 per 9. L'esempio può essere inserito su TryAPL in questo modo:

     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

Spiegazione:

  • ↓⍉⍵: ottieni le colonne di ,
  • ↓⍵: ottieni le righe di ,
  • 3/3⌿3 3⍴Z←⍳9: crea una matrice 3 per 3 contenente i numeri 1per 9, quindi triplica ogni numero in entrambe le direzioni, dando una matrice 9 per 9 con i numeri 1per 9indicare ciascun gruppo,
  • Z∘.=: per ogni numero 1da 9, creare una maschera di bit per il gruppo dato,
  • /∘(,⍵)¨: e maschera con ciascuno, dando i gruppi di .
  • ∊∘Z¨: per ciascun array secondario, vedere se contiene i numeri 1per 9,
  • ∧/,↑: considera insieme la logica anddi tutti questi numeri.

+1 bello! Ma i gruppi 3 × 3 possono essere giocati ancora a golf. Ad esempio, questo ↓9 9⍴1 3 2⍉3 3 9⍴⍵è equivalente /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9ma piuttosto breve. Sono sicuro che ci sono formule ancora più brevi.
Tobia,

Inoltre, potresti concatenare le matrici per la 1a dimensione ed eseguire una singola divisione alla fine:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Tobia

C'è un bug: questo codice ∊∘Z¨sta verificando se ogni sotto-array (riga, colonna o blocco) è composto solo dai numeri da 1 a 9. Non sta verificando se tutti i numeri sono rappresentati. Devi fare qualcosa del genere Z∘.∊che verifica che ogni numero in Z sia contenuto in ogni sottosray.
Tobia,

E questo ∧/,↑può essere abbreviato ∧/∊. Ho finito, ho finito! ;-)
Tobia

Molto compatto, ma hai perso un punto critico che posso vedere subito:If it passes, return "0" and if not, return a non-zero result.
David Wilkins

5

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

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

(Passare booleana boolper C #)

formattato:

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

Il metodo crea un array ucon 27 maschere di bit, che rappresentano le cifre trovate nelle nove righe, colonne e quadrati.

Quindi scorre su tutte le celle, eseguendo l'operazione 1 << a[x][y]per creare una maschera di bit che rappresenta la cifra e gli OR la ​​sua maschera di bit di colonna, riga e quadrato con essa.

Quindi esegue l'iterazione su tutte le 27 maschere di bit, assicurando che tutte si sommino a 27594 (1022 * 9, 1022 essendo la maschera di bit per tutte le cifre 1-9 presenti). (Nota che yfinisce come 27603 perché contiene già 9 che seguono il doppio loop.)

Modifica: accidentalmente lasciato in un %3non più necessario.

Modifica 2: ispirato al commento di Bryce Wagner, il codice è stato compresso un po 'di più.


Quasi lo stesso algoritmo nei caratteri C # 149 (ma solo se Linq è consentito): bool s (int [] a) {int x = 0, y, j; var u = new int [27]; while (x ++ <(y = 9)), mentre (y> 0) {j = 1 << una [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 sarebbe davvero utile. Tuttavia, la mia soluzione è per Java con C # che è un ripensamento (nemmeno menzionato nel post originale) e quindi una priorità inferiore. Ho anche usato array unidimensionali per la compattezza all'inizio prima di decidere contro di esso (poiché gli esempi usano quelli bidimensionali). Tuttavia, il tuo codice mi ha dato alcune idee su come eliminare qualche byte in più. :)
Smallhacker

3

python = 196

Non il più golfato, ma l'idea è lì. I set sono piuttosto utili.

Tavola:

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

Programma:

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 (range (1,10)) / salva 3 caratteri.
MatrixFrog

In Python 3.5 puoi usare n={*range(1,10)}, ma è più recente della sfida. Usa invece set(range(1,10))come diceva MatrixFrog.
mbomb007,

3

Java - 385 306 328 260 caratteri

Modifica: ho stupidamente frainteso le istruzioni secondo cui la risposta doveva essere un programma completo. Dal momento che può essere solo una funzione valida, ho riscritto e ridotto a icona per essere una funzione, e ho riscritto la mia introduzione alla soluzione tenendo presente ciò.

Quindi, come una sfida per me stesso, ho pensato di provare a creare il più piccolo correttore di soluzioni Java.

Per ottenere ciò, suppongo che il puzzle del sudoku verrà passato come un array multidimensionale Java, in questo modo:

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

Quindi, abbiamo il risolutore reale, che restituisce "0" se valida soluzione, "1" in caso contrario.

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

Leggibile:

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

Quindi come funziona? Fondamentalmente creo solo la mia base numerica con una risoluzione sufficiente in ogni cifra che devo fare solo tre confronti numerici dopo aver attraversato il puzzle una volta per sapere se è valido. Ho scelto la base 49 per questo problema, ma qualsiasi base superiore a 45 sarebbe sufficiente.

Un esempio (si spera) chiaro: immagina che ogni "riga" nel puzzle del sudoku sia una singola cifra in un numero di base 49. Rappresenteremo ogni cifra nel numero base-49 come numero base-10 in un vettore per semplicità. Quindi, se tutte le righe sono "corrette", ci aspettiamo il seguente numero base-49 (come vettore base-10):

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

o convertito in un singolo numero base-10: 1526637748041045

Seguire una logica simile per tutte le colonne e lo stesso per le "griglie secondarie". Qualsiasi valore rilevato nell'analisi finale che non corrisponde a questo "numero ideale" significa che la soluzione di puzzle non è valida.

Modifica per risolvere la vulnerabilità di tutti i 5 e altri problemi correlati: aggiungo un quarto numero base-49, basato sull'idea che dovrebbero esserci 9 di ogni numero in ogni puzzle. Quindi, aggiungo 5 a ciascuna cifra nel numero base-49 per ogni occorrenza del numero base-10 che rappresenta l'indice della cifra. Un esempio, se ci sono 10 9 e 9 8, 9 7, 8 6 e 9 di tutti gli altri, otterresti un numero base-49 (come un vettore base 10 della dimensione 10 per gestire l'overflow):

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

Che fallirà rispetto al nostro numero "ideale" di base 49.

La mia soluzione sfrutta questa soluzione matematica, per evitare il più possibile il looping e il confronto. Uso semplicemente un longvalore per memorizzare ogni numero di base-49 come numero di base-10 e utilizzo un array di ricerca per ottenere i "fattori" per ogni cifra di base-49 durante il calcolo del valore di controllo colonna / riga / sottogriglia.

Poiché Java non è progettato per essere conciso, stare attenti nella costruzione matematica era l'unico modo in cui immaginavo di poter costruire un correttore conciso.

Fatemi sapere cosa ne pensate.


1
In realtà, questo soffre della stessa vulnerabilità menzionata da @ steve-verrill: tutti e 5 i numeri, o qualsiasi serie di numeri che somma a 45, "ingannano" il risolutore. Ho intenzione di rivedere. Ho un'idea su come batterlo.
Programmatore

Ho risolto questa vulnerabilità nel mio ultimo aggiornamento. Ora quel caso viene affrontato e tutti gli altri del suo tipo. Fondamentalmente, era una seria svista non occuparsi dei "conteggi" di ogni tipo di cifra di base 10. Ora eseguo quel controllo direttamente, ma usando lo stesso approccio matematico (numero base-49).
Programmatore

Dan, grazie per il riconoscimento. L'ho visto e mi chiedevo perché non ero stato avvisato, ma vedo che hai messo un trattino a mio nome. Questo sembra aver confuso il sistema. Ometti semplicemente lo spazio. Prenderò in considerazione di cambiare il modo in cui il mio nome viene visualizzato.
Level River St

Ahha, questo lo spiega. Grazie @steveverrill - Mi sto ancora abituando al modo di fare le cose con stackexchange. Detto questo, il tuo conciso exploit del principio sum-45 è stato brillantemente affermato. Ha reso la mia soluzione più lunga per superarla, ma quella è vita!
Programmatore


3

Haskell (Lambdabot), 65 byte

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

2

Perl, 193 byte

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'input è previsto in forma di array:

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

Il codice di uscita è 0, se @aè una soluzione, altrimenti 1viene restituito.

Versione non golfata:

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

Ognuna delle 9 righe, 9 colonne e 9 sotto array viene inserita in un array ordinato e verificata, se corrisponde all'array (1..9). Il numero $rviene incrementato per ogni corrispondenza corretta che deve essere sommata a 27 per una soluzione valida.


2

J 52 54

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

Prende l'argomento incollato sulla riga di comando, terminato con a) come:

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
)

Restituisce 1 se superato, 0 in caso contrario.

Internamente, converte la griglia 9x9 in una griglia 3x3x3x3 e fa alcune permutazioni sugli assi per ottenere l'unità desiderata (file, linee e caselle) nelle ultime 2 dimensioni.

Successivamente, viene verificato che ogni unità abbia 9 valori univoci.

Probabilmente lontano dall'essere perfetto, ma batte già la maggioranza ;-)


A prima vista, sei stato colto dallo stesso requisito di alcuni degli altri .... I tuoi ritorni dovrebbero essere invertiti ... 0 per il passaggio, diverso da zero per il fallimento
David Wilkins

0 per pass è idiota. C'è una ragione per cui Boole ha scelto 1 per vero e 0 per falso. Ma hai ragione. Aggiunge 2 caratteri.
jpjacobs,

Pensalo come uno stato di uscita, non un valore booleano
David Wilkins,

Sto scegliendo la tua risposta perché funziona. Hai seguito le regole e il tuo programma è molto breve. Grazie!
David Wilkins,

Beh, mi sono arrabbiato ... In verità non posso giustificare non scegliere la risposta Golfscript più corta della tua ... Ma complimenti per il 2 ° posto
David Wilkins

2

Mathematica, 84 79 caratteri

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

Esempi:

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


Il tuo terzo esempio di output: è 3sempre indicativo di input non validi o a volte è una risposta a una soluzione non riuscita?
David Wilkins,

2

Javascript ES6, 150 caratteri

Accetta l'input come stringa da 81 caratteri senza delimitatori.

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

La funzione restituisce nulluna risposta negativa e una matrice con una stringa originale nel primo elemento come una positiva. Può cambiare in bool aggiungendo !!alla funzione inizio.

Test (vedi sfida relativa per più detais):

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

Questa è una regex ridicola ... Incredibile lavoro.
ETHproductions

2

R, 63 50 byte

Presuppone che l'input msia una matrice di numeri 9x9.

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

Avevo ragione sul fatto che fosse possibile giocare a golf ulteriormente.

Spiegazione:

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

Prendi me per ogni riga applica la matchfunzione. Specifichiamo un ulteriore argomento x=1:9a cui passare match. xè il primo argomento di posizione predefinito e pertanto ogni riga viene posizionata nella seconda posizione di argomento, ovvero table. La funzione matchcerca istanze di xin table. In questo caso, quindi, cerca 1:9(i numeri da 1 a 9) in ogni riga. Per ciascuno di essi 1:9, verrà restituito TRUE(o FALSE) se tale numero viene trovato (o meno).

Quindi, questo produce una serie di 81 valori booleani.

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

Ripeti quanto sopra per ogni colonna dell'input.

all(                                             )

Infine, allcontrolla se ogni elemento dell'elenco di booleani è TRUE. Questo sarà il caso se e solo se la soluzione è corretta (cioè ogni numero 1:9è presente solo una volta in ogni colonna e ogni riga).

Vecchio approccio:

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

Prende ogni riga, la ordina e poi la confronta [1, 2, ... 9]. Una riga corretta dovrebbe corrispondere esattamente. Quindi fa lo stesso per ogni colonna. In totale, dovremmo avere 162 corrispondenze esatte, che è ciò che la parte finale controlla. C'è probabilmente un certo margine per ulteriori golf qui ...


Sembra che tu stia controllando colonne e righe, ma non scatole ...
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 funzione vè quella da chiamare. Funziona ottenendo la differenza di ogni riga, colonna e blocco rispetto all'elenco [1..9]e sommando le lunghezze di tali elenchi di differenze.

Demo usando l'esempio 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 caratteri

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]

Si aspetta ache esista un array e crea una variabile oper l'output che ha 0successo e diversa da zero in caso contrario.

Funziona verificando che la somma della posizione in cui si verifica ciascun valore per ciascuna riga, colonna e griglia 3 * 3 sia uguale a 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8).

analisi

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

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

(Ultime 2 cifre scambiate)

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

o=-284


1

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

usi:

-- 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 carica Data.List e Data.List.Split per impostazione predefinita (non credo che la soluzione di BlackCap spunta le caselle).

Idee per il miglioramento sono benvenute

// Modifica: ho incasinato :)
// Modifica: 3 byte salvati da BlackCap


Hai ragione, non ho notato che il controllo delle righe e delle colonne non è abbastanza ..
BlackCap

bene, ho anche fatto un
casino

1
È possibile sostituire (map sort)con(sort<$>)
BlackCap

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

oh mio, avrei dovuto ricordare quei 2
michi7x7 del


0

Clojure, 151 byte

Abbastanza a lungo, ma anche altri sembrano esserlo. Inoltre, è fastidioso che l'unione di set richieda a require, quindi ho usato un concat di vettori.

Esegue un'iterazione su ogni riga e colonna e se il valore è compreso tra 1 e 9, emette tre vettori, uno per riga, colonna e cella 3x3. Restituisce 0 in caso di successo e in caso nilcontrario, con due caratteri aggiuntivi potrebbe restituire 1 in caso di esito negativo. Gestisce i numeri al di fuori di 1 - 9 restituendo nilma si bloccherà su altre anomalie come valori non interi. I quotienti sono 0 - 2, quindi è sicuro usare valori 8e 9differenziare i valori di cella da righe e colonne.

(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'input è un vettore nidificato di vettori (quindi nthfunziona):

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

Ungolfed:

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

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

Il programma accetta 9 argomenti di riga di comando separati (una stringa di cifre per ogni riga della griglia);
esce con 1(errore) per non valido, 0(ok) per valido.

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

abbattersi

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
}

spiegazione

count_charsconta i caratteri in una stringa e di solito crea un array con codici ASCII come chiavi e il conteggio dei caratteri come valori; ma con 3come parametro mode, crea una stringa ordinata dai caratteri; e che può essere facilmente confrontato con il numero con le cifre desiderate.

Il confronto non controlla solo i duplicati, ma include anche il controllo dei caratteri non validi. E richiede solo <, non !=, perché si tratta di un confronto numerico: PHP interpreterà la stringa come un numero per quanto è possibile. 123e56789, 0x3456789O simile non può apparire, perché i personaggi sono ordinati; e qualsiasi numero intero puro con una cifra mancante è più piccolo di 123456789... e .23456789anche, ovviamente.

$a=$argvsalva un byte, $d=123456789salva nove e $u=count_charssalva 13.


-1

C # - 306 298 288 caratteri

Il seguente programma della console è stato utilizzato per chiamare la funzione di controllo;

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

Tutto ciò che fa è inizializzare l'array e passarlo nella funzione di controllo P.

La funzione di controllo è la seguente (in forma 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;}

O in forma completamente definita;

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

Questo usa l'idea che tutte le colonne, le righe e le griglie secondarie dovrebbero aggiungere fino a 45. Funziona attraverso l'array di input e sottrae il valore di ogni posizione dalla sua riga, colonna e griglia secondaria. Una volta completato, verifica che nessuna delle righe, colonne o griglie secondarie abbia ancora un valore.

Come richiesto restituisce uno 0 se l'array è una soluzione di Sudoku valida e diverso da zero (1) dove non lo è.


Penso che puoi salvare alcuni caratteri usando private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];invece. (Nota la rimozione dello spazio dopo la parentesi quadra chiusa ].) Inoltre, non sono sicuro, ma penso che potresti liberarti di private static.
user12205,

Inoltre, per l'ultima parte, in C possiamo rimuovere alcune parentesi graffe for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}, ad esempio , non sono sicuro che funzioni in C #. (In realtà non conosco C #)
user12205,

@ace - Ho apportato diversi miglioramenti in base ai tuoi suggerimenti. Ora fino a 298 caratteri.
Will

Ho eliminato altri 10 caratteri in base ai commenti di @ace.
Will

1
Cosa succede con un array pieno di numeri 5? Tutte le righe, colonne e quadrati si sommano a 45.
Level River St
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.