Localizador de Sudoku exclusivo


19

Desafio:

Dado um quadro de Sudoku na entrada padrão, encontre o número mínimo de números adicionados para tornar o quadro único.

Regras / Específicos:

  • A entrada está formatada da seguinte forma (todo o espaço em branco é significativo)

    516|827|943
    278|394|615
    349|615|872
    ---+---+---
    98 |4 2|156
    465|189|237
    12 |5 6|489
    ---+---+---
    892|743|561
    634|951|728
    751|268|394
    
  • A saída é formatada com um número por linha, formatada como (x,y):z- x e y começam de um no canto superior esquerdo e aumentam para baixo e para a direita; z é o número a ser adicionado.

    • Neste caso, estes seriam todos saídas válidas: (3,4):3, (3,4):7, (5,4):3, (5,4):7, (3,6):3, (3,6):7, (5,6):3, e (5,6):7, como qualquer um deles permitiria que a placa para ser resolvido.
  • Se for inserido um quadro de Sudoku exclusivo / resolvido, o programa não deverá imprimir nada, nem mesmo uma nova linha.
  • O programa deve ser executado em menos de uma hora para qualquer placa (sugiro testar usando uma placa totalmente em branco ou uma placa com um número aleatório ...).

Pontuação:

  • Pegue seu tamanho total de código (em golf) em caracteres, incluindo todos os espaços em branco ...

Bônus:

1/2 tamanho do código : se o programa imprimir um único ponto de exclamação e parar após ter uma placa sem soluções inseridas.

1/2 tamanho do código : Se o programa imprimir dois pontos de exclamação e parar após inserir uma placa com uma contradição interna (dois números iguais na mesma linha / coluna / quadrado).


3
Chato e provavelmente difícil :(
Oleh Prypin

6
Vaia. 'Não imprimir nada, nem mesmo uma nova linha' exclui o GolfScript.
Peter Taylor

11
um sudoku solver que nunca precisa de recuar / palpite para uma solução completa é necessária para isso, (e cada vez que um "palpite" é necessário saída dele)
aberração catraca

3
Não vejo o motivo para votar isso. Muito esforço foi feito para mostrar um belo quebra-cabeça; é muito claro e está corretamente indicado. É grande demais para o meu gosto, mas isso é subjetivo demais por uma razão para voto negativo, não é?
usuário desconhecido

Respostas:


10

Braquilog , 245 bytes / 2 = 122,5

@n:1a:"-"x:7fF:3a$\:3a@3:4a,Fc~bCh[0:0:0]gO,Co~c[V:O:T]h:F:6f:10ao:ba(h:11a;!);"!!"w!
h"-".|:"|"x:2f.
e(~m["0123456789":.]`;0<.<=9)
:ha#d.
:@3az:ca:5a.
:3a.
hs.:=a,?t:9ac:=fl1
:Im:8f:[[I]]z:ca.
:Jm:J.
:ha.
lg:?c.
b:+a[X:Y],?h:Y:Xr:"(~d,~d):~d
"w

(Observe que você deve usar a versão do idioma a partir deste commit . Este código precisaria de algumas alterações para que funcione corretamente nas seguintes versões do Brachylog)

Isso é impresso "!!"se o quadro fornecido tiver contradições internas (isso leva alguns segundos, no entanto, no TIO, portanto, seja paciente).

Não sei se entendi o primeiro bônus corretamente, por isso não estou tratando dele.

Obviamente, isso não é competitivo, já que o idioma é muito mais recente que o desafio, no entanto, como não há outras respostas, não tenho certeza se isso importa muito ...

Explicação

  • Predicado principal:

    @n                Split the input on line breaks
    :1a:"-"x          Transform into a list of lists, each sublist contains a line's values
    :7fF              Transform so that cells are [Value:X:Y]
    :3a               All values on lines must be different
    $\:3a             All values on columns must be different (by transposition)
    @3:4a,            All 3*3 block values must be different
    Fc~bCh[0:0:0]gO,  Append a fake cell [0:0:0]
    Co~c[V:O:T]       Sort the board, the blank cells V will be those before O ([0:0:0])
    h:F:6f            Find all subsets of blank cells with specific values for which 
                          the board has only one solution
    :10ao             Sort the subsets by lengths
    :ba               Discard the lengths
    (                 
      h:11a             Print the first subset = an answer
    ;                 Or (board is already fully determined)
      !                 Terminate
    )          
    ;                 Or (Some values don't respect the constraints)
    "!!"w!            Print "!!" and terminate
    
  • Predicado 1: remova tudo " |" nas linhas, transforme ---+---+---em -para removê-las depois

    h"-".    If the first char is "-", then Output is "-"
    |        Or
    :"|"x    Remove all occurences of "|" from the input
    :2f.     Output is the result of all outputs of predicate 2 on the filtered string
    
  • Predicado 2: converta um caractere para um número inteiro ou, se estiver em branco, em uma variável entre 1 e 9.

    e                      Take a char of the input string
    (
      ~m["0123456789":.]     Output is the index of the char in "0123456789"
      `                      Discard the choice point caused by the ;
    ;                      Or
      0<.<=9                 Output is an integer between 1 and 9
    )
    
  • Predicado 3: imponha que todos os valores da lista de entrada de células devam ser distintos

    :ha    Retrieve the head of each cell (i.e. the value) in the input 
    #d.    Apply a constraint of distinctness to those values
    
  • Predicado 4: aplique a restrição de distinção aos valores em 3 * 3 blocos

    :@3a            Split 3 lines of the board in 3 parts
        z           Zip them together
         :ca:5a.    Concatenate each element of the zip, apply predicate 5 to that
    
  • Predicado 5:

    :3a.    Apply predicate 3 to each element of the input
    
  • Predicado 6: Atribua valores que satisfaçam as restrições a um subconjunto das células em branco; então, com esses valores, haverá apenas uma solução para o quadro.

    hs.       Output is a subset of the blank cells
    :=a,      Assign values to those cells
    ?t:9ac    Concatenate the values of all cells of the board
    :=f       Find all solved boards
    l1        There is only 1 such solved board
    
  • Predicado 7: transforma a placa de modo que cada célula seja agora e [V:X:Y]não apenas V(o valor).

    :Im       Take the Ith line of the board
    :8f       Transform all elements of the line using predicate 8
    :[[I]]z   Zip the result with [I]
    :ca.      Concatenate each element of the zip
    
  • Predicado 8: transforma uma linha de modo que cada célula esteja agora [V:X].

    :Jm    Take the Jth element of the line
    :J.    Output is [That element:J]
    
  • Predicado 9: recuperar os valores das células

    :ha.   Take the head of each element of the input
    
  • Predicado 10: anexar o comprimento de um subconjunto no início dele

    lg     Put the length of the input in a list
    :?c.   Concatenate it with the input
    
  • Predicado 11: Imprimir uma célula

    b:+a[X:Y],        Increment coordinates by 1 to get X and Y
    ?h:Y:Xr:          Build the list [X:Y:Value]
    "(~d,~d):~d\n"w   Format that list as "('X','Y'):'Value'\n" to STDOUT
    

2
Você não pode simplesmente expandir isso para uma resposta do Prolog? Então seria competir! (Você pode publicá-lo separadamente.) Não tenho certeza de quão direto é o mapeamento entre Brachylog e Prolog.
Lynn

@ Lynn Sim, eu poderia, eu poderia até postar o código Prolog que é gerado pelo transpiler de Brachylog (que seria altamente destruído obviamente). Não o farei, porque tenho certeza de que o pôster do desafio nunca mais voltará a aceitar uma resposta: p
Fatalize
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.