Crie uma solução sudoku CHECKER


21

Crie uma solução Sudoku CHECKER

Existem muitos SOLVERS do Sudoku aqui, mas quero que você crie uma solução CHECKER tão pequena quanto humanamente possível (código-golfe).

  • Uma entrada válida poderá aceitar uma matriz 9x9 como argumento (passado por referência, serializado na linha de comando ou como você desejar) ou aceitar um arquivo de entrada com nove linhas de nove números para a grade final . Veja exemplos de entrada abaixo.

  • A entrada válida deve ter números de base 10 (1-9)

  • As posições ausentes, vazias, extras, não numéricas ou com números fora de 1 a 9 devem ser rejeitadas como entrada inválida retornando um resultado diferente de zero, imprimindo um erro ou ambos.

  • Seu programa precisa testar se cada número aparece uma vez por coluna, uma vez por linha e uma vez por sub-grade 3x3. Se for aprovado, retorne "0" e, se não, retorne um resultado diferente de zero.

  • O uso de recursos externos (sites, etc.) deve ser evitado.

  • Se a sua solução for um programa independente, sair com um status de saída de ou imprimir "0" ou diferente de zero para "Aprovado" ou "Reprovado", respectivamente, está ok.

Deixe a menor resposta vencer!

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

Arquivo:

123456789
456789123
789123456
231564897
564897231
897231564
312645978
645978312
978312645

As 9 subgrelhas:

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

Respostas:


5

GolfScript, 39 caracteres

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

Ele pega uma matriz de matrizes como entrada (veja o exemplo on-line ) e sai 0se for uma grade válida.

Breve explicação do 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

Eu gosto que a saída diferente de zero do seu código seja mais significativa do que apenas 1ou-1
David Wilkins

Gostei muito da sua resposta, mas no final decidi não usar uma solução golfscript. Eu realmente espero que você entenda
David Wilkins

2
@DavidWilkins Na verdade eu não entendo - você fez as regras (!) E não declarou em nenhum lugar que o GolfScript não era permitido.
Howard

Seu argumento é inteiramente válido ... na verdade, não tenho nada para justificar não escolher sua resposta. Bem jogado
David Wilkins

10

Python, 103

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

Como funciona: cada linha, coluna e bloco deve ter cada número de 1 a 9. Portanto, para cada 0 <= i, j < 9célula, a célula i,jestá em bloco 3*floor(i/3) + floor(j/3). Portanto, existem 243 requisitos a serem satisfeitos. Faço de cada requisito uma tupla, ((item index,item type number),symbol)onde item indexé um número entre 0 e 8 (inclusive), item type numberé 0,1 ou 2 para indicar linha, coluna ou bloco, respectivamente, e symbolé a entrada b[i][j].

Editar: por engano, não verifiquei entradas válidas. Agora eu faço.


Seu programa deve saída 0se a solução passa, nãoTrue
David Wilkins

@DavidWilkins que requisito estranho. Fixo.
usar o seguinte comando

Você senhor meu voto apenas para a maneira que você começou a sua resposta: D
Teun Pronk

9

APL (46)

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

Isso requer uma matriz 9 por 9. O exemplo pode ser inserido no TryAPL da seguinte forma:

     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

Explicação:

  • ↓⍉⍵: obtenha as colunas de ,
  • ↓⍵: obtém as linhas de ,
  • 3/3⌿3 3⍴Z←⍳9: crie uma matriz 3 por 3 contendo os números 1para 9, em seguida, triplique cada número nas duas direções, fornecendo uma matriz 9 por 9 com os números 1para 9indicar cada grupo,
  • Z∘.=: Para cada número 1para 9, fazer uma máscara de bits para o grupo determinado,
  • /∘(,⍵)¨: e mascarar com cada um, dando os grupos de .
  • ∊∘Z¨: para cada subconjunto, veja se ele contém os números 1para 9,
  • ∧/,↑: pegue a lógica andde todos esses números juntos.

+1 Bom! Mas os grupos 3 × 3 podem jogar golfe um pouco mais. Por exemplo, isso ↓9 9⍴1 3 2⍉3 3 9⍴⍵é equivalente, /∘(,⍵)¨↓Z∘.=,3/3⌿3 3⍴Z←⍳9mas bem mais curto. Tenho certeza de que existem fórmulas ainda mais curtas.
Tobia

Além disso, você pode concatenar as matrizes pela 1ª dimensão e executar uma única divisão no final:↓(9 9⍴1 3 2⍉3 3 9⍴⍵)⍪⍵⍪⍉⍵
Tobia

Há um erro: esse código ∊∘Z¨está testando se cada sub-matriz (linha, coluna ou bloco) é composta apenas dos números 1 a 9. Não está testando se todos os números estão representados. Você precisa fazer algo como o Z∘.∊teste de que todo número em Z está contido em cada sub-matriz.
Tobia

E isso ∧/,↑pode ser reduzido para ∧/∊. Acabei, acabei! ;-)
Tobia 01/03

Muito compacto, mas você perdeu um ponto crítico que eu posso ver com o pé direito: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;}

(Altere booleanpara boolpara C #)

Formatado:

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

O método cria uma matriz ucom 27 máscaras de bits, representando os dígitos encontrados nas nove linhas, colunas e quadrados.

Em seguida, itera sobre todas as células, executando a operação 1 << a[x][y]para criar uma máscara de bits representando o dígito e ORs sua coluna, linha e máscara de bits quadrada com ele.

Ele itera sobre todas as 27 máscaras de bits, garantindo que todas elas adicionem até 27594 (1022 * 9, 1022 sendo a máscara de bit para todos os dígitos de 1 a 9 presentes). (Observe que yacaba como 27603, pois já contém 9 após o loop duplo.)

Editar: acidentalmente deixado em um %3que não é mais necessário.

Edit 2: Inspirado pelo comentário de Bryce Wagner, o código foi compactado um pouco mais.


Quase o mesmo algoritmo nos caracteres C # 149 (mas apenas se o Linq for permitido): 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;} retorna u.Sum () == 27594;}
Bryce Wagner

@BryceWagner Linq seria realmente útil. No entanto, minha solução é para Java, com C # sendo uma reflexão tardia (nem mencionada na publicação original) e, portanto, com menor prioridade. Também usei matrizes unidimensionais para compactação no início antes de decidir contra ela (como os exemplos usam as bidimensionais). No entanto, seu código me deu algumas idéias de como mais alguns bytes poderiam ser removidos. :)
Smallhacker

3

python = 196

Não é o mais jogado, mas a idéia está aí. Conjuntos são bastante úteis.

Borda:

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

No Python 3.5, você pode usar n={*range(1,10)}, mas isso é mais recente que o desafio. Em vez disso, use set(range(1,10))como MatrixFrog disse.
mbomb007

3

Java - 385306328 260 caracteres

Edit: Eu tolamente enganei as instruções de que a resposta tinha que ser um programa completo. Como ela pode ser apenas uma função válida, reescrevi e minimizei para ser uma função e reescrevi minha introdução à solução com isso em mente.

Então, como um desafio para mim, pensei em tentar fazer o menor verificador de solução Java.

Para conseguir isso, assumo que o quebra-cabeça do sudoku será transmitido como uma matriz multidimensional java, da seguinte forma:

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

Então, temos o solucionador real, que retorna "0" se solução válida, "1" se não.

Totalmente jogado:

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

Legível:

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

Então, como isso funciona? Basicamente, apenas crio minha própria base numérica com resolução suficiente em cada dígito, para que eu só precise fazer três comparações numéricas depois de passar pelo quebra-cabeça uma vez para saber se é válido. Eu escolhi a base 49 para esse problema, mas qualquer base maior que 45 seria suficiente.

Um exemplo (espero) claro: imagine que toda "linha" no quebra-cabeça sudoku seja um único dígito no número da base 49. Representaremos cada dígito no número da base 49 como um número da base 10 em um vetor para simplificar. Portanto, se todas as linhas estiverem "corretas", esperamos o seguinte número da base 49 (como um vetor da base 10):

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

ou convertido em um único número base-10: 1526637748041045

Siga uma lógica semelhante para todas as colunas e o mesmo para as "sub-grades". Qualquer valor encontrado na análise final que não seja igual a esse "número ideal" significa que a solução do quebra-cabeça é inválida.

Edite para solucionar a vulnerabilidade do all-5s e outros problemas relacionados: adiciono um quarto número da base 49, com base na idéia de que deve haver 9 de cada número em cada quebra-cabeça. Portanto, adiciono 5 a cada dígito no número da base 49 para cada ocorrência do número da base 10 que representa o índice do dígito. Por exemplo, se houver 10 9 e 9 8, 9 7, 8 6 e 9 de todos os outros, você obteria um número base 49 (como um vetor base 10 do tamanho 10 para lidar com o estouro):

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

O que falhará quando comparado com o número "ideal" da base 49.

Minha solução tira proveito dessa solução matemática, para evitar o máximo possível de loop e comparação. Simplesmente uso um longvalor para armazenar cada número da base 49 como um número base 10 e uso uma matriz de pesquisa para obter os "fatores" para cada dígito da base 49 durante o cálculo do valor da verificação de coluna / linha / sub-grade.

Como o Java não foi projetado para ser conciso, ter cuidado na construção matemática era a única maneira que eu imaginava que poderia construir um verificador conciso.

Diz-me o que pensas.


11
Na verdade, isso sofre da mesma vulnerabilidade mencionada por @ steve-verrill - todos os 5, ou qualquer conjunto de números que totalize 45, "enganarão" o solucionador. Eu vou revisar. Eu tenho uma idéia de como vencer isso.
ProgrammerDan

Eu resolvi esta vulnerabilidade na minha atualização mais recente. Agora esse caso está resolvido e todos os outros desse tipo. Basicamente, foi uma supervisão séria não lidar com as "contagens" de cada tipo de dígito de base 10. Agora, faço essa verificação diretamente, mas usando a mesma abordagem matemática (número da base 49).
ProgrammerDan

Dan, obrigado pelo reconhecimento. Eu vi e me perguntei por que não fui notificado, mas vejo que você põe um traço em meu nome. Isso parece ter confundido o sistema. Simplesmente omita o espaço. Vou considerar mudar a maneira como meu nome é exibido.
Level River St

Ahha, isso explica isso. Obrigado @steveverrill - ainda estou me acostumando com a maneira de fazer as coisas de stackexchange. Dito isto, sua exploração concisa do princípio da soma 45 foi brilhantemente declarada. Tornei minha solução mais longa para superá-la, mas é a vida!
ProgrammerDan

3

R 145

function(x)colSums(do.call(rbind,lapply(list(R<-row(b<-matrix(1,9,9)),C<-col(b),(R-1)%/%3+1+3*(C-1)%/%3),sapply,`==`,1:9))%*%c(2^(x-1))==511)==27

O código retirado do golfe (mais ou menos) pode ser encontrado aqui /programming//a/21691541/1201032 .


você pode fornecer um exemplo de trabalho em um site como o r-fiddle? r-fiddle.org/#
David Wilkins

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)

A entrada é esperada no formato 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]
);

O código de saída é 0, se @afor uma solução, caso contrário, 1será retornado.

Versão não destruída:

@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 uma das 9 linhas, 9 colunas e 9 sub-matrizes é colocada em uma matriz classificada e verificada, se corresponde à matriz (1..9). O número $ré incrementado para cada correspondência bem-sucedida que deve somar 27 para uma solução válida.


2

J 52 54

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

Leva seu argumento colado na linha de comando, terminado com 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
)

Retorna 1 se aprovado, 0 se não.

Internamente, ele converte a grade 9x9 em uma grade 3x3x3x3 e faz algumas permutações nos eixos para obter a unidade desejada (linhas, linhas e caixas) nas duas últimas dimensões.

Depois disso, é verificado que cada unidade possui 9 valores exclusivos.

Provavelmente longe de ser perfeito, mas já supera a maioria ;-)


À primeira vista, você foi pego pela mesma exigência como alguns dos outros .... Seu retorno deve ser revertida ... 0 para a passagem, diferente de zero para falhar
David Wilkins

0 para passe é idiota. Há uma razão pela qual Boole escolheu 1 para verdadeiro e 0 para falso. Mas você está certo. Adiciona 2 caracteres.
precisa saber é

Pense nisso como um estado de saída, e não um valor booleano
David Wilkins

Eu estou escolhendo sua resposta porque funciona. Você seguiu as regras e seu programa é muito curto. Obrigado!
David Wilkins

Bem, eu menti ... Na verdade eu não posso justificar a não escolher a resposta Golfscript que é menor do que o seu ... Mas elogios para 2º lugar
David Wilkins

2

Mathematica, 84 79 caracteres

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

Exemplos:

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


Seu terceiro exemplo de saída: é 3sempre indicativo de entrada inválida ou, às vezes, é uma resposta a uma solução com falha?
David Wilkins

2

Javascript ES6, 150 caracteres

Recebe a entrada como uma sequência de 81 caracteres sem delimitadores.

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

A função retorna nullcomo resposta negativa e uma matriz com a sequência original no primeiro elemento como positiva. Pode mudar para bool, adicionando !!a função de início.

Teste (veja o desafio relacionado para mais detalhes):

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

Esse é um regex ridículo ... Um trabalho incrível.
ETHproductions

2

R, 63 50 bytes

Assume que a entrada mé uma matriz de números 9x9.

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

Eu estava certo que mais golfe era possível.

Explicação:

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

Pegue me, para cada linha, aplique a matchfunção Especificamos outro argumento x=1:9a ser passado match. xé o argumento de primeira posição padrão e, portanto, cada linha é colocada na segunda posição de argumento, que é table. A função matchprocura instâncias de xin table. Nesse caso, ele está procurando 1:9(os números de 1 a 9) em cada linha. Para cada um deles 1:9, ele retornará TRUE(ou FALSE) se esse número for encontrado (ou não).

Portanto, isso gera uma série de 81 valores booleanos.

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

Repita o procedimento acima para cada coluna da entrada.

all(                                             )

Finalmente, allverifica se todos os elementos da lista de booleanos são TRUE. Este será o caso se e somente se a solução estiver correta (ou seja, cada número 1:9está presente apenas uma vez em cada coluna e cada linha).

Abordagem antiga:

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

Ele pega cada linha, classifica-a e depois a compara [1, 2, ... 9]. Uma linha correta deve corresponder exatamente. Em seguida, faz o mesmo para cada coluna. No total, devemos ter 162 correspondências exatas, que é o que a parte final verifica. Provavelmente existe alguma margem para mais golfe aqui ...


Parece que você está verificando para colunas e linhas, mas não para caixas ...
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]]]

A função vé a única a chamar. Ele funciona obtendo a diferença de cada linha, coluna e bloco na lista [1..9]e resumindo os comprimentos dessas listas de diferenças.

Demonstração usando o exemplo 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 que uma matriz aexista e cria uma variável opara saída 0com êxito e diferente de zero.

Funciona verificando se a soma da posição em que cada valor ocorre para cada linha, coluna e grade 3 * 3 é igual a 36 (0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8).

Teste

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

Dá '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 trocados)

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

usa:

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

O Lambdabot carrega Data.List e Data.List.Split por padrão (não acho que a solução do BlackCap marque as caixas).

Idéias para melhoria bem-vindas

// Edit: eu errei :)
// Edit: 3 bytes salvos pelo BlackCap


Você está certo, eu não aviso que verificar as linhas e colunas não são suficientes ..
Cabeção

bem, eu errei bem :)
michi7x7

11
Você pode substituir (map sort)por(sort<$>)
BlackCap 19/09/16

11
E .c$(sort<$>)<$>com$(sort<$>)=<<
BlackCap 19/09/16

oh meu, deveria ter lembrado aqueles 2
michi7x7 19/09/16


0

Clojure, 151 bytes

Muito tempo, mas outros parecem também. Também é irritante que a união de conjuntos exija a require, então usei uma concat de vetores.

Repete cada linha e coluna e, se o valor estiver entre 1 e 9, emite três vetores, um para a linha, a coluna e a célula 3x3. Retorna 0 em caso de sucesso e nil, caso contrário, com dois caracteres extras, pode retornar 1 em caso de falha. Manipula números fora de 1 a 9 retornando, nilmas trava em outras anomalias, como valores não inteiros. Os quocientes são de 0 a 2, portanto, é seguro usar valores 8e 9diferenciar valores de células de linhas e colunas.

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

Input é um vetor aninhado de vetores (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]])

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

O programa recebe 9 argumentos de linha de comando separados (uma sequência de dígitos para cada linha da grade);
sai com 1(erro) inválido, 0(ok) válido.

Corra com php -nr '<code>' <row1> <row2> ....

demolir

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
}

explicação

count_charsconta caracteres em uma string e geralmente cria uma matriz com códigos ASCII como chaves e caracteres como valores; mas com o 3parâmetro mode, ele cria uma sequência classificada a partir dos caracteres; e isso pode ser facilmente comparado ao número com os dígitos desejados.

A comparação não apenas verifica duplicatas, mas também inclui a verificação de caracteres inválidos. E isso requer apenas <, não !=, porque esta é uma comparação numérica: o PHP interpretará a string como um número, na medida do possível. 123e56789, 0x3456789Ou similar não pode aparecer, porque os personagens são classificadas; e qualquer número inteiro puro com um dígito ausente é menor que 123456789... e.23456789 também, é claro.

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


-1

C # - 306 298 288 caracteres

O seguinte programa Console foi usado para chamar a função de verificação;

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

Tudo isso é inicializar o array e passá-lo para a função de verificação P.

A função de verificação é a seguinte (na 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;}

Ou de forma totalmente definida;

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

Isso usa a ideia de que todas as colunas, linhas e subgrades devem adicionar até 45. Ele funciona através da matriz de entrada e subtrai o valor de cada posição da sua linha, coluna e sub-grade. Depois de concluído, verifica se nenhuma das linhas, colunas ou subgrades ainda possui um valor.

Conforme solicitado, retorna 0 se a matriz for uma solução Sudoku válida e diferente de zero (1) onde não estiver.


Eu acho que você pode salvar alguns caracteres usando private static int P(int[,]i){int[]r=new int[9],c=new int[9],g=new int[9];. (Observe a remoção do espaço após o colchete fechado ].) Além disso, não tenho certeza, mas acho que você pode se livrar do private static.
user12205

Além disso, na última parte, em C, podemos remover algumas chaves for(int p=0;p<9;p++)if(r[p]>0|c[p]>0|g[p]>0)return 1;return 0;}, ou seja , não sabemos se funciona em C #. (Eu realmente não sei C #) #
11002 user12205 28/02

@ace - Fiz várias melhorias com base nas suas sugestões. Agora, com 298 caracteres.
Will

Aparados outros 10 caracteres com base nos comentários de @ace.
Will

11
O que acontece com uma matriz cheia de números 5? Todas as linhas, colunas e quadrados somam 45.
Level River St
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.