Esta placa Takuzu é válida?


21

Takuzu é um jogo de lógica no qual você precisa completar uma grade com células contendo 0s e 1s. A grade deve seguir 3 regras:

  1. Não há três células consecutivas horizontais ou verticais que podem ser iguais.
  2. Tem de haver um número igual de 0s e 1s em cada linha e coluna.
  3. Não há duas linhas iguais, nem duas colunas iguais.

Vejamos uma grade finalizada:

0011
1100
0101
1010

Como você pode ver, este quadro segue a regra 1, 2e 3. Não há três células horizontais ou verticais, que são os mesmos, todas as linhas e colunas contêm um número igual de 0s e 1s, e não há duas filas e duas colunas não são o mesmo.

Vejamos uma grade que não é válida:

110100
010011
011010
101100
100011
001101

Há muitos problemas com essa grade. Por exemplo, a linha 5possui três 0s em uma linha e a coluna 2possui três 1s em uma linha, seguidos por três 0s. Portanto, essa não é uma grade válida.

Tarefa:

Sua tarefa é fazer um programa que, dada uma matriz 2D de n* n 0s e 1s, verifica a placa para ver se é uma placa válida, acabado Takuzu.

Exemplos:

0011
1100
0101
1010

Este fórum segue todas as regras e, portanto, é um conselho válido da Takuzu. Você deve retornar um valor verdadeiro para isso.

11
00

Este não é um quadro válido - a linha 1não segue a regra 2. Você deve retornar um valor falsey para isso.

100110
101001
010101
100110
011010
011001

Este não é um quadro válido; ele falha (somente) devido à regra 3 - a primeira e a quarta linhas são as mesmas.

110100
001011
010011
101100
100110
011001

Este não é um quadro válido; ele falha (somente) devido à regra 3 - a primeira e a quarta colunas são as mesmas.

011010
010101
101100
010011
100110
101001

Este é um quadro válido.

Regras e especificações:

  • Você pode assumir que todas as placas são quadradas de dimensões n * n, onde né um número inteiro positivo.
  • Você pode assumir que todas as placas estão concluídas.
  • Você pode receber a entrada como uma matriz 2D contendo valores significando 0e 1, ou como uma sequência.
  • É necessário gerar valores consistentes de truthy e falsey para placas de truthy e falsey, e os valores que representam "truthy" e "falsey" não podem ser os mesmos.

Isso é , então o código mais curto em bytes vence!



3
Eu sei disso como 0h h1 ...
Erik the Outgolfer

3
@EriktheOutgolfer Sim, eu comecei apenas sabendo isso como 0h h1, mas Takuzu é o nome original do quebra-cabeça.
Clismique

@EriktheOutgolfer Eu sempre o conheci como "Binary Puzzle" ou "Subiku", mas "Takuzu" é como Qwerp-Derp mencionou o nome original.
Kevin Cruijssen

2
Alguns mais casos de teste seria bom (eu estou perdendo grandes, placas válidos.)
Lynn

Respostas:


16

Braquilog , 20 18 bytes

≠\≠,?¬{∋s₃=|∋ọtᵐ≠}

Experimente online!

Explicação

≠                           All rows are different
 \                          Transpose
  ≠                         All columns are different
   ,?                       Append the list of rows to the list of columns
     ¬{          }          It is impossible that:
       ∋                      A row/column of the matrix…
        s₃=                   …contains a substring of 3 equal elements
           |                Or that:
            ∋ọ                The occurences of 1s and 0s in a row/column…
              tᵐ≠             …are not equal

" Anexar a lista de linhas à lista de colunas " maneira inteligente de jogar! E aqui eu pensei que sua resposta de 20 bytes era direta e jogava golfe o máximo que podia ser. Vejo que o Brachylog é tão bom em validar as matrizes quanto em resolvê-las . :)
Kevin Cruijssen

1
Não deveria produzir falsepara isso ?
H.PWiz

1
@ H.PWiz Boa localização, obrigado. Revertida para a versão de 18 bytes que funcionou.
Fatalize 01/09/19

@LuisMendo Estou apenas colocando todas as linhas e colunas na mesma lista basicamente.
Fatalize

2
@ Zgarb Correto, obrigado. Essa é a terceira vez que eu tinha que reverter uma edição, o post de abertura está na necessidade desesperada de melhores casos de teste ...
Fatalize

11

Casca , 19 18 bytes

S=‼(Tf§=LṁDum(ṁ↑2g

Experimente online!

1 byte salvo graças ao H.PWiz!

A idéia principal é aplicar uma série de transformações à entrada que são identidades para uma placa válida e verificar se o resultado final é o mesmo que a entrada original.

Explicação

S=‼(Tf§=LṁDum(ṁ↑2g
            m(ṁ↑2g    in each line, take at most two items for each sequence of equal items
           u          remove duplicate lines
     f§=LṁD          keep only those lines where the sum of each element doubled is equal to the length of the line
    T                 transpose the matrix (swap rows with columns)
  ‼                   do all the previous operations again
S=                    check if the final result is equal to the original input


@ H.PWiz que era quase óbvio, me engane!
Leo

7

Geléia , 17 bytes

-*S;E3Ƥ€F$TȯQZµ⁺⁼

Experimente online!

-6 bytes graças a milhas e Jonathan Allan .


1
Eu acredito que você pode encurtar isso para 21 bytes. TIO
milhas

@ milhas ... talvez até 19 bytes ?
Jonathan Allan

1
@ JonathanAllan que tem 18 bytes ... sim, você fez a µZ$⁺coisa novamente: p ... e 17 bytes trocando um pouco: D agora eu venci brachylog hehe
Erik the Outgolfer

@EriktheOutgolfer Não é mais, é um empate!
Fatalize

@JonathanAllan Nice. Também acredito que esta é a primeira vez que o prefixo / infixo rápido que adicionei foi útil.
milhas

5

Mathematica, 143 bytes

And@@Flatten@(((s=#;Equal@@(Count[s,#]&/@{0,1})&&FreeQ[Subsequences@s,#]&/@{{1,1,1},{0,0,0}})&/@#)&&(DeleteDuplicates@#==#)&/@{#,Transpose@#})&


entrada

[{{0, 0, 1, 1}, {1, 1, 0, 0}, {0, 1, 0, 1}, {1, 0, 1, 0}}]


5

Python 2 , 127 bytes

a=input()
n=len(a)
b=zip(*a)
print[n/2]*n*2==map(sum,a+b)>len(set(a))==len(set(b))==n<'0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`

Experimente online!

Lê uma lista de n n- pares como entrada.

Eu poderia produzir pelo código de saída escrevendo, em 1/(…)vez de, print…mas parece estranho. Eu devo?

Explicação

né o tamanho do quadro; bé uma lista de colunas (transposição de a). O resto é uma comparação longa e encadeada:

  • [n/2]*n*2==map(sum,a+b) verifica a regra 2. Cada linha e coluna deve somar n / 2.
  • map(sum,a+b)>len(set(a)) é sempre verdadeiro (lista> int).
  • len(set(a))==len(set(b))==n verifica a regra 3.
  • n<'0, 0, 0' é sempre verdadeiro (int <str).
  • '0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`verifica a regra 1. `a+b`é a representação em cadeia de todas as linhas e colunas; para o exemplo de entrada no TIO, é

    "[(0, 0, 1, 1), (1, 1, 0, 0), (0, 1, 0, 1), (1, 0, 1, 0), (0, 1, 0, 1), (0, 1, 1, 0), (1, 0, 0, 1), (1, 0, 1, 0)]"

    O `a+b`>'1, 1, 1'no centro é sempre verdadeiro, pois é garantido que essa sequência seja iniciada "[", que é maior que "1".


Se você deseja enviar pelo código de saída, é possível fazê-lo [n/2]*n*2==map(sum,a+b)>len(set(a))==len(set(b))==n<'0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`>x, que é 2 bytes menor que a divisão e resulta em uma NameErrorpara entradas verdadeiras.
ovs 01/09/19

3

Casca , 27 25 bytes

Λ§&Λȯ¬VEX3§&Λ§=#0#1S=uSeT

Entrada é uma lista de listas e a saída é 1para Truee 0paraFalse

Experimente online!

Explicação

                      SeT    Create a list with the input and itself transposed
Λ                            Is the following function true for all in the list
 §&                          And the results of the following functions
   Λȯ¬VEX3                     Test for rule 1
          §&                   The and of:
            Λ§=#0#1                Test for rule 2
                   S=u             Test for rule 3

Teste 1

Λȯ¬VEX3
Λ         Is it True for all ...
   V      Are any of the ...
     X3   Substrings of length 3 ...
    E     All equal
 ȯ¬       Logical not

Teste 2

Λ§=#0#1
Λ         Is it true for all that ...
 §=       The results of the two functions are equal
   #0         Number of 0s
     #1       Number of 1s

Teste 3

S=u
S=    Is the result of the following function equal two its argument
  u   Remove duplicates

3

Retina , 129 89 85 bytes

.+
$&,$&
O#$`.(?=.*,)
$.%`
.+
$&;$&
+`(01|10)(?=.*;)

1ms`(.)\1\1|\d,?;|(\D\d+\b).*\2

Experimente online! Saídas 0 para válido, 1 para inválido. Editar: salvou 4 bytes graças a @MartinEnder. Explicação:

.+
$&,$&

Duplique cada linha com ,separadores.

O#$`.(?=.*,)
$.%`

Transponha a primeira duplicata.

.+
$&;$&

Duplique novamente, desta vez com ;separadores.

+`(01|10)(?=.*;)

Exclua todos os pares de dígitos correspondentes que precedem um ponto-e-vírgula.

1ms`(.)\1\1|\d,?;|(\D\d+\b).*\2

Verifique se alguma coluna ou linha falha em alguma das regras; (.)\1\1verifica três dígitos idênticos seguidos, \d,?;verifica um dígito não emparelhado e (\D\d+\b).*\2verifica uma duplicata.


Se o objetivo do (...).*último estágio for apenas fazer max(matches,1), você poderá salvar três bytes usando um 1na configuração.
Martin Ender

E .\b\d+\bpode ser \D\d+\b.
Martin Ender

@MartinEnder Originalmente, substituí a saída inválida por nenhuma saída e testei no final ... Acabei aprimorando-o para um único teste no final e percebi que podia omitir a liderança .*que já estava usando anteriormente, mas que não pensava usar uma configuração para limitar o resultado, obrigado!
Neil

3

Pitão , 31 bytes

Muito obrigado a @Leaky Nun .

.Asm++mqy/k\0lQdm<hk3srL8d{Id,C

Verifique todos os casos de teste ou Experimente aqui!


Pitão ,  48 46 44  42 bytes

Esta é a solução inicial.

&{IQ&{I.TQ.Am&q/d\0/d\1!+/d*3\0/d*3\1sC,.T

Verifique todos os casos de teste ou Experimente aqui!

& {IQ & {I.TQ.Am & q / d \ 0 / d \ 1! + / D * 3 \ 0 / d * 3 \ 1sC, .T Programa completo com entrada implícita.

 {QI A entrada é invariável com desduplicação?
& {I.TQ E sua transposição também é invariável?
                                        .TQ Transpose.
                                           Q A entrada.
                                     sC, zip o acima, [^, ^^] (e aplainar).
    & E a seguinte condição foi atendida?
          .Am Todos os elementos são verdadeiros ao mapear sobre ^^.
              q / d \ 0 / d \ 1 Existem tantos 0s quanto 1s.
             &! + / d * 3 \ 0 / d * 3 \ 1 E não há execuções de 3 elementos iguais.

3

MATL , 27 bytes

,G@?!]tEqts~w7BZ+|3<bXBSdvA

Entrada é uma matriz que contém 0e 1. A saída é 0para falsidade, 1para verdade.

Experimente online! Ou veja os casos de teste: 1 , 2 , 3 , 4 , 5 .

Explicação

,       % Do twice. First iteration will use the input, second its transpose
  G     %   Push input
  @     %   Push iteration index: first 0, then 1
  ?     %   If nonzero
    !   %     Transpose
  ]     %   End
  t     %   The top of the stack contains the input or its transpose. Duplicate
  Eq    %   Convert to bipolar form, i.e. replace 0 by -1
  t     %   Duplicate
  s     %   Sum of each column
  ~     %   Negate. If all results are true, condition 2 is fulfilled
  w     %   Swap. Moves copy of bipolar input/transposed input to top
  7B    %   Push [1 1 1], obtained as 7 converted to binary
  Z+    %   2D convolution. Gives a matrix of the same size as the input
  |3<   %   Is each entry less than 3 in absolute value? If all results are true,
        %   condition 1 is fulfilled
  b     %   Bubble up. Moves copy of input/transposed input to top
  XB    %   Convert each row from binary to a number
  Sd    %   Sort, consecutive differences. If all results are nonzero, condition 3
        %   is fulfilled
  v     %   Concatenate all results so far into a column vector
  A     %   True if all entries are nonzero
        % End (implicit). Display (implicit)

2

R , 114 107 bytes

-7 graças a Giuseppe, chamar funções fora de ordem e realmente comprimir as condições

function(x)any(f(x),f(t(x)))
f=function(x)c(apply(x,1,function(y)max(rle(y)$l)>2+mean(y)-.5),duplicated(x))

Experimente online!

Isso apenas aplica as regras às colunas da matriz, depois às colunas da transposição da matriz.

Recebe entrada no formato:

matrix(c(0,0,1,1,1,1,0,0,0,1,0,1,1,0,1,0), ncol=4)

É assim que o R toma matrizes 2D.

Saídas TRUE para falhas, FALSE para passes.



Atualizações gerais: usado mean(y)-.5dentro do interno ffunção para obter os meios, em vez de colMeans, e fez ganônimo. Ele irá adicionar alertas para converter doublea logicalna chamada para anymas isso é OK.
Giuseppe

@Giuseppe Thanks! Eu realmente gosto da aplicação combinada, mudança muito inteligente! Eu tinha dois aplicativos separados em um estágio inicial e não percebi o quão limpo você poderia combiná-los.
CriminallyVulgar


2

Perl 6 ,100 93 bytes

Junções FTW! Eles economizam 7 bytes.

Por enquanto, isso parece estar superando todos os outros envios escritos em idiomas não relacionados ao golfe. Yippie!

{!max (@(.map(*.join)).&{.repeated| |.map:{$_~~/000|111/|.comb(0)-.comb(1)}}for @^a,[Z] @^a)}

Experimente online!

Explicação : É um bloco que assume o quadro como lista de listas. Fazemos uma transposição com [Z] @^a(reduza a lista de listas com o operador zip). Assim @^a,[Z] @^aé uma lista do quadro e sua transposição. Passamos por cima dele com o forqual funciona exatamente comomap , sendo apenas 1 char mais barato neste caso.

Por dentro, primeiro juntamos as listas que constituem linhas em strings, portanto, temos uma lista de strings em vez de uma lista de listas ( @(.map(*.join))). Em seguida, usamos um bloco anônimo nele ( .&{...}), onde avaliamos as regras. Nós os avaliaremos apenas em linhas. (Como fazemos isso para a matriz original e a transposição também.)

Para economizar bastante !, usamos um pouco de lógica e, em vez de testar (NO repeated rows) AND (NO 3 consecutive same symbols) AND (NOT different counts of 0 and 1), testamos NOT[ (repeated rows) OR (3 consecutive same symbols) OR (different counts) ]. É o que fazemos no bloco anônimo: .repeatedfornece todas as linhas que ocorrem mais de uma vez, depois mapeamos as linhas, tentamos combinar 3 símbolos consecutivos usando uma regex e subtraímos as contagens de 0 e 1. Estes são OR'red com o |. (Na verdade, ele cria uma coisa muito poderosa chamada junção , mas não usamos nenhum dos seus poderes :)) Depois de tudo isso, obtemos uma lista de 2 "bools" (junções não recolhidas). Finalmente, ou eles (usando max) e negamos ( !), o que fornece o resultado desejado.


2

J, 40 38 55 bytes

0=[:([:+/^:_(3(0=3|+/)\"1 ]),:-.@~:,:#=[:+/"1+:@])|:,:]

Experimente online!

Define uma função que utiliza uma matriz quadrada como entrada.

Pelo menos está vencendo Pyth (por enquanto ...) (erroneamente). Devo voltar a contar o emoji escondido no meu código, pois J também se presta bem a isso:

[: /^: :1 |: :] :-.@ :# :@] :~@

Explicação (ligeiramente desatualizada)

Isso parece diferente da minha resposta e eu posso atualizá-la. Partes dela ainda são as mesmas - eu simplesmente não estava verificando a regra 3 e verificando incorretamente a regra 2 antes.

Dividir em algumas funções e ungolfed:

join_trans  =. |: ,: ]
part_3      =. 3 (0 = 3 | +/)\"1 ]
f           =. 1 - 2 * ]
main        =. 0 = [: ([: +/^:_ part_3 , f) join_trans

join_trans

|: ,: ]
|:       Transpose
   ,:    Laminated to
      ]  Input

Isso une a transposição da matriz para si mesma, criando uma matriz de matrizes.

part_3

3 (0 = 3 | +/)\"1 ]
                  ]  Input (matrix and transpose)

Isso verifica a soma das partições de 3 em linhas para ver se é 3 ou 0 (já que qualquer uma delas significa uma placa inválida), retornando 1 se for e 0 em caso contrário. Opera tanto na matriz quanto na sua transposição, uma vez que são dadas as duas.

f

1 - 2 * ]

Por falta de um nome melhor, eu chamo isso f. Ele substitui os 0s por _1 e deixa os 1s inalterados. Isso me permite verificar se o número de 0s e 1s é igual em cada linha e coluna (a soma de cada uma das linhas deve ser 0).

a Principal

0 = [: ([: +/^:_ part_3 , f) join_trans
                             join_trans  Join transpose to input
                 part_3 , f              Apply the validity checks and join them
           +/^:_                         Sum until it converges
0 =                                      Equate to 0

Basicamente, eu aproveitar o fato de que eu configurá-lo para que f join_transe part_3 join_transambos devem somar 0 sse o conselho é válido. part_3devem ser todos os zeros para uma placa válida e a totalidade de fdeve somar zero a uma placa válida, o que significa que a soma de suas somas é 0 apenas para uma placa válida.


Pelo menos, está superando Pyth (por enquanto ...). - Eu realmente preciso de golfe a minha resposta
Mr. Xcoder

@ Mr.Xcoder haha ​​sim, você sempre parece puxar e é por isso que adicionei o bit "por enquanto". Não que minha resposta não tenha espaço para jogar golfe - simplesmente não sei como fazê-lo muito bem.
Cole


1
Esse código para 33 bytes deve ser equivalente ao seu*/@,@,&(~:,(0~:3|3+/\]),#=2*+/)|:
milhas

2

Haskell , 137 136 127 bytes

9 bytes salvos graças ao Lynn!

import Data.List
j=isSubsequenceOf
l x=x==nub x&&and[sum y*2==length x&&not(j[0,0,0]y||j[1,1,1]y)|y<-x]
g x=l x&&l(transpose x)

Experimente online!


Role os dois alls em um and: l x=x==nub x&&and[sum y*2==length x&&not(j[0,0,0]y||j[1,1,1]y)|y<-x]
Lynn

@Lynn Thanks! Eu estava tentando juntar os dois por um tempo. Não sei por que eu não consegui descobrir isso.
Wheat Wizard

1
Você poderia mudar j=isSubSequenceOfpara j x=isSubSequenceOf[x,x,x]?
Cyoce 6/09/17

@Cyoce Parece me perder um byte. Se você tem uma maneira de fazer isso que me poupa um byte, ficaria feliz em implementá-lo. A ideia parece ser boa.
Wheat Wizard

No celular, hmmm ... Talvez em vez de j a binvocar (e definir) como a#b?
Cyoce 7/09/17

2

Java 8, 350 326 325 312 303 299 298 259 255 bytes

int r,z,c,p,i,j,k,d,u,v=1;int c(int[][]b){v(b);k=v-=u=1;v(b);return r;}void v(int[][]b){String m="",x;for(d=b.length;j<d|k<d;k+=u,j+=v,r=m.contains(x)|z!=0?1:r,m+=x)for(x="#",c=0,k*=u,j*=v;j<d&k<d;z+=i|i-1,c*=i^p^1,x+=p=i,r=++c>2?1:r,k+=v,j+=u)i=b[k][j];}

Retorna 0quando é um quadro válido; 1se for inválido para uma ou mais das três regras.

-95 bytes graças a @Nevay .

Explicação:

Experimente aqui.

int r,z,c,p,i,j,k,d,u,v=1;
                     // Temp integers on class-level

int c(int[][]b){     // Method (1) with int-matrix parameter and int return-type
  v(b);              //  Validate the rows
  k=v-=u=1;          //  Switch rows with columns, and reset `u` to 1
  v(b);              //  Validate the columns
  return r;          //  Return the result
}                    // End of method (1)

void v(int[][]b){    // Separated method (2) with int-matrix parameter and no return-type
  String m="",s;     //  Two temp Strings to validate uniqueness of rows
  for(d=b.length;    //  Set the dimension of the matrix to `d`
      j<d|k<d        //  Loop (1) as long as either `j` or `k` is smaller than `d`
    ;                //   After every iteration:
     k+=u,j+=v       //    Increase the loop-indexes
     r=m.contains(s) //    If we've found a duplicated row,
     |z!=0?          //    or if the amount of zeroes and ones on this row aren't equal
      1:r,           //     Set `r` to 1 (invalid due to either rule 2 or 3)
     m+=s)           //    Append the current row to the String `m`
    for(s=",",       //   Set String `x` to a separator-character
        c=0,         //   Reset the counter to 0
        k*=u,j*=v,   //   Increase the loop-indexes
        j<d&k<d      //   Inner loop (2) as long as both `j` and `k` are smaller than `d`
     ;               //    After every iteration:
      z+=i|i-1,      //     Increase or decrease `z` depending on whether it's a 0 or 1
      c*=i^p^1,      //     Reset `c` if current digit `i` does not equal previous `p`
      s+=p=i,        //     Set previous `p` to current digit, and append it to String `s`
      r=++c>2?       //     If three of the same adjacent digits are found:
         1:r;        //      Set `r` to 1 (invalid due to rule 1)
        k+=v,j+=u)   //      Increase the loop-indexes
      i=b[k][j];     //    Set `i` to the current item in the matrix
                     //   End of inner loop (2) (implicit / single-line body)
                     //  End of loop (2) (implicit / single-line body)
}                    // End of separated method (2)


1

05AB1E , 29 bytes

ø‚D€ÙQIDøì©O·IgQP®εŒ3ù€Ë_P}PP

Experimente online!

Explicação

Regra: 3

ø‚        # pair the input with the zipped input
  D       # duplicate
   €Ù     # deduplicate each
     Q    # check for equality with the unmodified copy

Regra: 2

IDøì          # prepend zipped input to input
    ©         # store a copy in register for rule 1
     O        # sum each row/column
      ·       # double
       IgQ    # check each for equality to length of input
          P   # product

Regra 1

®ε            # apply to each row/column in register
  Œ3ù         # get sublists of length 3
     €Ë       # check each if all elements are equal
       _      # logical not
        P     # product
         }    # end apply
          P   # product

Depois, pegamos o produto do resultado de todas as três regras com P


1

Dyalog APL, 64 52 51 49 48 bytes

Requer ⎕IO←0

{⍲/{(∨/∊⍷∘⍵¨3/¨⍳2)∧((⊢≡∪)↓⍵)∧∧/(≢=2×+/)⍵}¨⍵(⍉⍵)}

Experimente online!


1

PHP, 245 + 1 bytes

como isso é volumoso. quebras de linha são apenas para conveniência de leitura:

$t=_;foreach($a=($i=str_split)($s=$argn)as$i=>$c)$t[$i/($e=strlen($s)**.5)+$i%$e*$e]=$c;
for(;$k++<2;$s=$t)$x|=preg_match("#000|111|(\d{"."$e}).*\\1#s",chunk_split($s,$e))
|($m=array_map)(array_sum,$m($i,$i($s,$e)))!=array_fill(0,$e,$e/2);echo!$x;

Pega uma única sequência sem novas linhas, imprime 1por verdade, nada por falsidade.

Execute como pipe -nRou experimente online .

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.