这是有效的Takuzu棋盘吗?


21

Takuzu是一种逻辑游戏,您必须使用包含0s和1s的单元格完成网格。网格必须遵循3条规则:

  1. 三个水平或垂直连续的像元不能相同。
  2. 必须有相等的0s和1每行和每一列中 s。
  3. 没有两行可以相同,也没有两列可以相同。

让我们看一个完成的网格:

0011
1100
0101
1010

正如你所看到的,这款主板遵循规则123。没有三个相同的水平或垂直单元格,所有行和列都包含相等数量的0s和1s,并且没有两行和两列相同。

让我们看一下无效的网格:

110100
010011
011010
101100
100011
001101

这个网格存在很多问题。例如,row连续5有三个0s,column连续2有三个1s,然后是三个0s。因此,这不是有效的网格。

任务:

您的任务是制作一个给定n* n 0的2D数组和1 s,以验证电路板以查看其是否为有效的成品Takuzu电路板。

例子:

0011
1100
0101
1010

该董事会遵循所有规则,因此是有效的Takuzu董事会。您必须为此返回真实值。

11
00

这不是有效的木板行1,不遵守规则2。您必须为此返回一个false值。

100110
101001
010101
100110
011010
011001

这不是有效的木板,它(仅)由于规则3而失败-第一和第四行相同。

110100
001011
010011
101100
100110
011001

这不是有效的木板,它(仅)由于规则3而失败-第一和第四列相同。

011010
010101
101100
010011
100110
101001

这是一个有效的板。

规则和规格:

  • 您可以假定所有板的尺寸均为正方形n * n,其中n为正偶数。
  • 您可以假定所有板均已完成。
  • 您可以将输入作为2D数组,其中包含表示01,也可以作为字符串。
  • 必须为真假板输出一致的真假值,并且表示“真实”和“假”的值不能相同。

这是,因此以字节为单位的最短代码胜出!



3
我知道这是0h h1 ...
Erik the Outgolfer

3
@EriktheOutgolfer是的,我也只知道这个为0h h1,但是Takuzu是这个难题的原始名称。
clismique

@EriktheOutgolfer我一直将其称为“二进制拼图”或“ Subiku”,但“ Takuzu”是Qwerp-Derp提到的原始名称。
凯文·克鲁伊森

2
还有更多的测试用例会很好(我缺少大型的有效木板。)
Lynn

Answers:


16

Brachylog20 18字节

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

在线尝试!

说明

≠                           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

将行列表添加到列列表 ”是打高尔夫的明智之举!在这里,我认为您的20字节答案很重要,并且尽可能多地打高尔夫球。我看到Brachylog在验证矩阵方面和在求解矩阵方面一样好。:)
凯文·克鲁伊森

1
难道不应该输出false这个
H.PWiz'9

1
@ H.PWiz很好,谢谢。恢复为有效的18字节版本。
致命

@LuisMendo我只是将所有行和所有列基本上放在同一列表中。
致命

2
@Zgarb正确,谢谢。那是我第三次不得不回滚编辑,开头的帖子迫切需要更好的测试用例……
Fatalize

11

外壳19 18字节

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

在线尝试!

感谢H.PWiz,节省了1个字节!

主要思想是对输入进行一系列转换,以确认有效板的身份,并检查最终结果是否与原始输入相同。

说明

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

2
一些改组以删除)
H.PWiz

@ H.PWiz几乎是显而易见的,愚蠢的我!
狮子座

7

果冻,17个字节

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

在线尝试!

-6个字节感谢MilesJonathan Allan


1
我相信您可以将其缩短到21个字节。TIO
英里

@miles ...甚至可能是19个字节
乔纳森·艾伦,

1
@JonathanAllan这是18个字节...是的,您又做了µZ$⁺一次:p ...和17个字节,通过交换了一点:D现在我击败了brachylog hehe
Erik the Outgolfer

@EriktheOutgolfer不再了,这是一条领带!
致命

@乔纳森·艾伦尼斯。我也相信这是我添加的前缀/前缀快速第一次有用。
英里

5

Mathematica,143个字节

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


输入

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


5

Python 2,127个字节

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`

在线尝试!

读取n n的列表元组作为输入。

我可以通过编写1/(…)而不是通过退出代码输出print…但感觉很傻。我是不是该?

说明

n董事会的大小;b是列的列表(的转置a)。剩下的就是一个长链比较:

  • [n/2]*n*2==map(sum,a+b) 检查规则2。每一行和每一列的总和应为n / 2。
  • map(sum,a+b)>len(set(a)) 始终为true(列表>整数)。
  • len(set(a))==len(set(b))==n 检查规则3。
  • n<'0, 0, 0' 始终为true(int <str)。
  • '0, 0, 0'not in`a+b`>'1, 1, 1'not in`a+b`检查规则1. `a+b`是所有行和列的字符串表示形式;对于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)]"

    `a+b`>'1, 1, 1',因为这串保证与开始在中心总是正确的"[",这是大于"1"


如果要通过退出代码输出,则可以执行[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,它比除法短2个字节,并导致NameError输入真实。
ovs's

3

外壳27 25字节

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

输入是一个列表的列表和输出是1用于True0False

在线尝试!

讲解

                      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

测试1

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

测试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

测试3

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

3

视网膜129 89 85字节

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

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

在线尝试!输出0表示有效,1表示无效。编辑:由于@MartinEnder,节省了4个字节。说明:

.+
$&,$&

,分隔符复制每一行。

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

转置第一个副本。

.+
$&;$&

再次复制,这次使用;分隔符。

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

删除分号前面所有匹配的数字对。

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

检查是否有任何列或行不符合任何规则;(.)\1\1连续检查三个相同的数字,\d,?;检查未配对的数字并(\D\d+\b).*\2检查重复的数字。


如果(...).*最后一步的目的只是为了实现目的,max(matches,1)则可以通过1在配置中使用a来节省三个字节。
Martin Ender

并且.\b\d+\b可以\D\d+\b
Martin Ender

@MartinEnder最初,我将无效输出替换为无输出,并在最后进行了测试...最终,我将其磨练到最后一个测试,并意识到我可以省略.*我以前一直使用但不认为使用的引线限制结果的配置,谢谢!
尼尔于2009年

3

Pyth,31个字节

非常感谢@Leaky Nun

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

验证所有测试用例在此处尝试!


Pyth 48 46 44  42字节

这是最初的解决方案。

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

验证所有测试用例在此处尝试!

&{IQ&{I.TQ.Am&q / d \ 0 / d \ 1!+ / d * 3 \ 0 / d * 3 \ 1sC,.T具有隐式输入的完整程序。

 {IQ输入重复数据消除后输入不变吗?
&{I.TQ并且它的转置不变吗?
                                        .TQ转置。
                                           Q输入。
                                     sC,压缩上面的[^,^^](并展平)。
    &并且满足以下条件?
          .Am在^^上映射时,所有元素都是真实的。
              q / d \ 0 / d \ 1 0和1s一样多。
             &!+ / d * 3 \ 0 / d * 3 \ 1而且没有3个相等元素的游程。

3

MATL,27字节

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

输入是一个包含0和的矩阵1。输出是0虚假的,1是真实的。

在线尝试!还是看测试情况: 1 2 345

说明

,       % 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

[R114个 107字节

-7感谢朱塞佩(Giuseppe),无序调用函数并真正压缩了条件

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

在线尝试!

这只是将规则应用于矩阵的列,然后应用于矩阵转置的列。

采用以下形式的输入:

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

R就是采用2D数组的方式。

对于失败,输出TRUE,对于失败,输出FALSE。



常规更新:mean(y)-.5在内部f函数内部使用以获得平均值而不是colMeans,并进行g匿名化。它将在调用中添加警告以将其转换doublelogicalany但这没关系。
朱塞佩

@Giuseppe谢谢!我真的很喜欢这种组合申请,非常聪明的改变!我有它,因为在早期有2个单独的应用程序,却没有意识到可以将它们组合得多么干净。
刑事


2

Perl 6100 93字节

交界处FTW!他们保存7个字节。

就目前而言,这似乎击败了所有其他使用非古体语言编写的意见书。耶皮!

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

在线尝试!

说明:这是一个将板子作为列表列表的块。我们进行转置[Z] @^a(使用zip运算符减少列表的列表)。@^a,[Z] @^a木板及其转置清单也是如此。我们循环使用它,for其工作方式与相似map,在这种情况下仅便宜1个字符。

在内部,我们首先将构成行的列表连接成字符串,所以我们有了字符串列表,而不是列表列表(@(.map(*.join)))。然后,我们在其上使用匿名块(.&{...}),在其中实际评估规则。我们将仅逐行评估它们。(因为我们对原始数组和转置都这样做。)

为了节省很多!,我们使用一些逻辑,而不是测试(NO repeated rows) AND (NO 3 consecutive same symbols) AND (NOT different counts of 0 and 1),我们测试NOT[ (repeated rows) OR (3 consecutive same symbols) OR (different counts) ]。这就是我们在匿名块中所做的:.repeated给所有出现多次的行,然后将它们映射,尝试使用正则表达式匹配3个连续的符号,并减去0和1的计数。这些与进行或|。(实际上,它创建了一个非常强大的功能,称为结点,但我们没有使用它的任何功能:))所有这些之后,我们获得了2个“布尔”(未折叠结点)的列表。我们最终或使用它们(或)对它们进行max取反(!),从而得出所需的结果。


2

J,40 38 55字节

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

在线尝试!

定义一个函数,以方矩阵为输入。

至少(错误地)它在击败Pyth(现在……)。我应该回到计数隐藏在我代码中的表情符号,因为J也很适合:

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

说明(略过时)

这看起来与我的答案有所不同,我可能会对其进行更新。它的某些部分仍然是相同的-我只是没有检查规则3,并且之前没有正确检查规则2。

拆分为几个函数,不再赘述:

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

join_trans

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

这将矩阵的转置连接到自身,从而创建矩阵数组。

part_3

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

这将按行检查3个分区的总和,以查看它是3还是0(因为这两个都表示板无效),如果是则返回1,否则返回0。因为它既给定了矩阵,又对它的转置矩阵都起作用。

F

1 - 2 * ]

由于缺乏更好的名字,我称其为 f。它将0替换为_1,并保持1不变。这是为了让我最终检查每一行和每一列中0和1的数目是否相等(每行的总和应为0)。

主要

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

基本上,我会充分利用我已对其进行设置的事实,以便在董事会有效的情况下f join_transpart_3 join_trans两者都应为0。part_3对于一个有效的电路板,应该为全零,而对于一个有效的电路板,所有的f总和应为零,这意味着仅对于一个有效的电路板,它们的总和为0。


至少它在击败Pyth(现在……)。-我确实需要回答我的问题
Xcoder先生

@ Mr.Xcoder哈哈,是的,您似乎总是很努力,这就是为什么我添加了“ for now”位。并不是说我的答案没有打高尔夫球的空间-我只是不知道怎么做得好。
cole


1
此33个字节的代码应等效于您的代码*/@,@,&(~:,(0~:3|3+/\]),#=2*+/)|:
英里

2

Haskell中137个 136 127字节

感谢Lynn,节省了9个字节!

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)

在线尝试!


将两者都滚动all为一个andl x=x==nub x&&and[sum y*2==length x&&not(j[0,0,0]y||j[1,1,1]y)|y<-x]
Lynn

@琳恩谢谢!我试图将这两部分放在一起一段时间。不知道为什么我不知道这一点。
小麦巫师

1
你可以改变j=isSubSequenceOfj x=isSubSequenceOf[x,x,x]
Cyoce

@Cyoce似乎让我失去了一个字节。如果您有一种方法可以节省一个字节,那么我很乐意实现它。这个想法似乎是一个好主意。
小麦巫师

在移动设备上,hmmm ...也许不是将其j a b调用(并定义为)a#b
Cyoce

2

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

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

0当它是一个有效的板时返回;1如果对三个规则中的一个或多个无效。

-95字节感谢@Nevay

说明:

在这里尝试。

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个字节

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

在线尝试!

说明

规则:3

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

规则: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

规则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

然后我们将所有3条规则的结果乘以 P


1

Dyalog APL,64 52 51 49 48字节

需要 ⎕IO←0

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

在线尝试!


1

PHP,245 + 1字节

嗯,这很笨重。换行符仅出于阅读方便:

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

接受不带换行符的单个字符串,打印1以获取真实性,而打印则不包含虚假性。

与管道一起运行-nR在线尝试

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.