Escreva um regex que corresponda a qualquer solução sudoku válida e não a qualquer solução sudoku inválida. A entrada é uma versão desenrolada do sudoku, ou seja, não há delimitadores de linha. Por exemplo, o seguinte quadro:
7 2 5 8 9 3 4 6 1
8 4 1 6 5 7 3 9 2
3 9 6 1 4 2 7 5 8
4 7 3 5 1 6 8 2 9
1 6 8 4 2 9 5 3 7
9 5 2 3 7 8 1 4 6
2 3 4 7 6 1 9 8 5
6 8 7 9 3 5 2 1 4
5 1 9 2 8 4 6 7 3
seria dado como:
725893461841657392396142758473516829168429537952378146234761985687935214519284673
As regras provavelmente já são de conhecimento comum, mas por precaução ... um quadro de sudoku é válido se e somente se:
- Cada linha contém os dígitos a partir
1
de9
uma única vez. - Cada coluna contém os dígitos a partir
1
de9
uma única vez. - Cada um dos nove subgrids 3x3 contém os dígitos a partir
1
de9
uma única vez.
Regras
Sua resposta deve consistir em um único regex, sem nenhum código adicional (exceto, opcionalmente, uma lista de modificadores de regex necessários para fazer sua solução funcionar). Você não deve usar recursos do tipo regex do seu idioma que permitam invocar código no idioma de hospedagem (por exemplo, o e
modificador do Perl ).
Você pode usar qualquer sabor de regex que existia antes deste desafio, mas especifique o sabor.
Não suponha que o regex esteja ancorado implicitamente. Por exemplo, se você estiver usando Python, assuma que seu regex é usado com re.search
e não com re.match
. Sua regex não precisa corresponder à cadeia inteira. Ele só precisa corresponder a pelo menos uma substring (que pode estar vazia) para soluções válidas e não produzir correspondências para soluções inválidas.
Você pode assumir que a entrada sempre será uma sequência de 81 dígitos positivos.
Como o regex golf, ganha o menor regex em bytes. Se o seu idioma exigir delimitadores (geralmente /.../
) para indicar expressões regulares, não conte os delimitadores. Se sua solução exigir modificadores, adicione um byte por modificador.
Casos de teste
Placas válidas:
123456789456789123789123456231564897564897231897231564312645978645978312978312645
725893461841657392396142758473516829168429537952378146234761985687935214519284673
395412678824376591671589243156928437249735186738641925983164752412857369567293814
679543182158926473432817659567381294914265738283479561345792816896154327721638945
867539142324167859159482736275398614936241587481756923592873461743615298618924375
954217683861453729372968145516832497249675318783149256437581962695324871128796534
271459386435168927986273541518734269769821435342596178194387652657942813823615794
237541896186927345495386721743269158569178432812435679378652914924813567651794283
168279435459863271273415986821354769734692518596781342615947823387526194942138657
863459712415273869279168354526387941947615238138942576781596423354821697692734185
768593142423176859951428736184765923572389614639214587816942375295837461347651298
243561789819327456657489132374192865926845317581673294162758943735914628498236571
243156789519847326687392145361475892724918653895263471152684937436729518978531264
498236571735914628162758943581673294926845317374192865657489132819327456243561789
978531264436729518152684937895263471724918653361475892687392145519847326243156789
341572689257698143986413275862341957495726831173985426519234768734869512628157394
Placas inválidas:
519284673725893461841657392396142758473516829168429537952378146234761985687935214
839541267182437659367158924715692843624973518573864192298316475941285736456729381
679543182158926473432817659567381294914256738283479561345792816896154327721638945
867539142324167859159482736275398684936241517481756923592873461743615298618924375
754219683861453729372968145516832497249675318983147256437581962695324871128796534
271459386435168927986273541518734269769828435342596178194387652657942813823615794
237541896186927345378652914743269158569178432812435679495386721924813567651794283
168759432459613278273165984821594763734982516596821347615437829387246195942378651
869887283619214453457338664548525781275424668379969727517385163319223917621449519
894158578962859187461322315913849812241742157275462973384219294849882291119423759
123456789456789123564897231231564897789123456897231564312645978645978312978312645
145278369256389147364197258478512693589623471697431582712845936823956714931764825
243561789829317456657489132374192865916845327581673294162758943735924618498236571
243156789529847316687392145361475892714928653895263471152684937436719528978531264
498236571735924618162758943581673294916845327374192865657489132829317456243561789
978531264436719528152684937895263471714928653361475892687392145529847316243156789
342571689257698143986413275861342957495726831173985426519234768734869512628157394
345678192627319458892451673468793521713524986951862347179246835534187269286935714
341572689257698143986413275862341957495726831173985426519234768734869512628517394
Para outros casos de teste, você pode usar esse script CJam que aceita uma placa válida como entrada e a embaralha aleatoriamente para fornecer uma nova placa válida (formato de entrada irrelevante, desde que contenha apenas dígitos e, opcionalmente, espaço em branco).
Se o seu regex é compatível com o sabor do .NET, você pode testá-lo online usando o Retina. Uma solução válida deve ser impressa 0
para placas inválidas e algum número inteiro positivo para placas válidas. Para executar todos os casos de teste de uma só vez, use este modelo e insira o regex na segunda linha. Se você precisar de modificadores de regex, acrescente a `
a ao regex e coloque as letras modificadoras padrão na frente dele.
fonte
valid boards
?Respostas:
Regex Ruby,
717873 bytesEu realmente não conheço Ruby, mas aparentemente ele não reclama de quantificadores em cascata.
Experimente aqui.
Regex .NET,
797875 ou 77 bytesPorque Martin acha que isso é possível ... Mas acho que ele também incorporará essas mudanças.
Requer uma nova linha à direita na entrada para funcionar. Não tenho certeza se estou autorizado a fazer isso (provavelmente não).
Experimente aqui.
A versão sã de 77 bytes:
Obrigado Neil por apontar o erro na minha versão anterior e jogar 1 byte (para o
(...)*
).Experimente aqui.
PCRE,
7778 bytesApenas por completude.
Experimente aqui.
Outra versão, também com 78 bytes:
Experimente aqui.
Explicação
fonte
PCRE, 117
119 130 133 147bytesTambém deve funcionar nos sabores Python, Java etc.Agora com recursão! E o recurso "recursão" era usado de forma não recursiva para "sub-rotinas", das quais esqueci totalmente até precisar usar a recursão real.fonte
.{27}*
.^(?!(.{27})*(.{9})?(...){0,2}.?.?(.).?.?(?=(...)*$)(.{9})?.{6,8}\4.{0,17}(.{27})*$|.*(.)((.{9})+|((?!(.{9})*$).)+)(<=\8))
(<=\8)
não parece com sintaxe válida (falta um?
). Além disso, o único sabor que conheço que suporta referências anteriores em lookbehinds é o .NET.Regex .NET, 8339 bytes
Sim, eu sei que minha solução é muito ingênua, pois Martin me disse que fez isso em 130 bytes. De fato, o URL para experimentá-lo on-line é tão longo que não consegui encontrar um encurtador de URL que o aceitasse.
O link abaixo não funciona no IE, mas no Chrome e Firefox.
Experimente online - Todos os casos de teste de uma só vez, com a ajuda do
!`
início, não incluídos na contagem de bytes.Aqui está o script Python que eu usei para gerá-lo (código abaixo):
fonte
Regex .NET, 121 bytes
Explicação:
fonte
PCRE, 3579 bytes
Uma solução absolutamente terrível de força bruta. Lookbehinds negativo ahoy!
Eu gastei muito tempo nisso para abandoná-lo, então aqui está, pelo bem da posteridade.
Pelo lado positivo, se o Sudoku de repente começar a usar um conjunto diferente de 9 caracteres, ainda funcionará, eu acho ...
http://pastebin.com/raw/CwtviGkC
Não sei como operar o Retina, mas você também pode colá-lo em https://regex101.com ou similar e ele será compatível.
Código Ruby usado para gerar o regex:
fonte
Sabor rubi,
7574 bytesObrigado a jimmy23013 por economizar 1 byte.
Teste aqui.
Agora que finalmente foi derrotado, posso compartilhar minha própria solução. :) Descobri uma técnica interessante de regex (talvez nova?) No processo (a
(.|(.)){,8}\3
parte), que provavelmente seria imbatível nos casos em que isso não pode ser combinado com outras partes da regex (como foi o caso da resposta de jimmy23013) .Explicação
Como as outras respostas curtas, estou usando um visual negativo que procura duplicatas em linhas, colunas ou blocos. O alicerce básico da solução é este:
Observe que
\3
é reutilizado entre três alternativas diferentes (que usam grupo3
para detecção de duplicatas).Esse grupo à esquerda (que é grupo
2
, contendo grupo3
) é usado para qualquer posição que possa conter a primeira metade de um dígito duplicado (dentro de um grupo que não deve conter dígitos duplicados). Então,...
é algo que nos leva à próxima posição em que esse dígito pode ocorrer (se necessário) e\3
tenta encontrar a segunda metade da duplicata por referência anterior. A razão pela qual isso funciona é voltar atrás. Quando o mecanismo corresponder pela primeira vez,(.|(.))
ele simplesmente será usado.
todas as vezes e não capturará nada. Agora,\3
no final, falha. Mas agora o mecanismo tentará gradualmente usar em(.)
vez de.
para correspondências individuais. Por fim, se houver uma duplicata, ela encontrará a combinação em que(.)
foi usado pela última vez no primeiro dígito da duplicata (de modo que a captura não seja substituída posteriormente) e, em seguida, usa um pouco mais.
para preencher a lacuna com a referência anterior. Se houver uma duplicata, o retorno sempre a encontrará.Vejamos as três partes diferentes em que isso é usado:
Isso verifica duplicatas em alguma linha. Primeiro, pulamos para qualquer linha com
.{9}*
. Em seguida, combinamos até 8 caracteres (ou seja, qualquer coisa nessa linha, exceto o último dígito) usando a captura duplicada opcional e tentamos encontrar o que está\3
depois.Isso procura duplicatas em alguma coluna. Primeiro, observe que
\g<2>
é uma chamada de sub-rotina, portanto, é o mesmo que:onde os dois grupos que acabamos de inserir ainda são referidos como
2
e3
.Aqui, o
.*
arquivo simplesmente pula até o necessário (seria suficiente corresponder até 8 caracteres aqui, mas isso custa mais bytes). Em seguida, o grupo externo corresponde a uma linha completa (que pode ser dividida em duas linhas físicas) por vez, capturando opcionalmente o primeiro caractere. O\3
será procurado logo após isso, o que garante o alinhamento vertical entre a captura e a referência anterior.Por fim, verificando os blocos:
Novamente,
\g<2>
é uma chamada de sub-rotina, portanto, é o mesmo que:Para verificar os blocos, observe que, como já verificamos todas as linhas e colunas, precisamos verificar apenas quatro dos blocos 3x3. Quando sabemos que todas as linhas e colunas, bem como esses blocos 3x3, estão corretos:
Então sabemos que não pode haver duplicatas nos blocos restantes. Por isso, só estou verificando esses quatro blocos. Além disso, observe que não precisamos procurar duplicatas na mesma linha de um bloco 3x3. Basta encontrar a primeira metade da duplicata em uma linha e procurar a segunda metade em uma linha mais abaixo.
Agora, para o código em si, primeiro pulamos para o início de um dos quatro blocos com
.{27}?.{3}?
(opcionalmente pule três linhas, opcionalmente pule três colunas). Em seguida, tentamos combinar até duas das linhas do bloco 3x3 com o mesmo truque usado nas linhas anteriores:Permitimos, mas não exigimos a captura de nenhuma das três células na linha atual do bloco 3x3 e, em seguida, pularemos para a próxima linha com
.{6}
. Por fim, tentamos encontrar uma duplicata em qualquer uma das 3 células da linha em que terminamos:E é isso.
fonte
^(?!(.*((.|(.)).{8})*|.{9}*\g<3>{,8}|.{27}?.{3}?(\g<3>{3}.{6}){,2}.?.?)\4)
:; 73:^(?!(.*((.|(.)|\4()).{8})*|.{9}*\g<3>{9}|.{27}?.{3}?(\g<3>{3}.{6}){3})\5)
.\4()
truque em uma versão anterior para os blocos 3x3, mas acabei me livrando dele, porque era mais longo. : D341572689257698143986413275862341957495726831173985426519234768734869512628517394
Javascript regex,
532530481463 caracteresValide linhas:
Valide colunas:
Valide o quadrado do seu primeiro caractere:
Defina a visualização para o início do quadrado:
E toda a expressão:
Corresponde a toda a cadeia.
Teste em Javascript ES6:
fonte
.
entra(.{9})
com suportes por causa do próximo{0,8}
. Por que você acha que as colunas devem ser mais curtas?