Это действительная доска Takuzu?


21

Такузу - логическая игра, в которой вы должны заполнить сетку ячейками, содержащими 0s и 1s. Сетка должна следовать 3 правилам:

  1. Три горизонтальные или вертикальные последовательные ячейки не могут быть одинаковыми.
  2. В каждой строке и столбце должно быть одинаковое количество 0s и 1s.
  3. Две строки не могут быть одинаковыми, а две колонки не могут быть одинаковыми.

Давайте посмотрим на готовую сетку:

0011
1100
0101
1010

Как видите, эта доска следует правилу 1, 2а 3. Не существует трех одинаковых горизонтальных или вертикальных ячеек, все строки и столбцы содержат одинаковое количество 0s и 1s, и нет двух одинаковых строк и двух столбцов.

Давайте посмотрим на сетку, которая не действительна:

110100
010011
011010
101100
100011
001101

Есть куча проблем с этой сеткой. Например, строка 5содержит три 0строки подряд, а столбец 2содержит три 1строки подряд, а затем три0 секунды. Следовательно, это недействительная сетка.

Задача:

Ваша задача - создать программу, которая, учитывая двумерный массив n* n 0s и 1s, проверяет доску, чтобы увидеть, является ли она действительной, готовой доской Takuzu.

Примеры:

0011
1100
0101
1010

Эта доска соответствует всем правилам и поэтому является действительной доской Такузу. Вы должны вернуть истинное значение для этого.

11
00

Это недействительная доска - строка 1не соответствует правилу 2. Вы должны вернуть значение Falsey для этого.

100110
101001
010101
100110
011010
011001

Это недопустимая доска, она терпит неудачу (только) из-за правила 3 ​​- первая и четвертая строки одинаковы.

110100
001011
010011
101100
100110
011001

Это недействительная доска, она терпит неудачу (только) из-за правила 3 ​​- первый и четвертый столбцы одинаковы.

011010
010101
101100
010011
100110
101001

Это действительная доска.

Правила и характеристики:

  • Можно предположить, что все доски имеют квадратные размеры n * n, где nположительное и четное число.
  • Вы можете предположить, что все доски закончены.
  • Вы можете принимать входные данные как двумерный массив, содержащий значения, обозначающие 0и 1, или как строку.
  • Вы должны вывести согласованные значения truey и falsey для досок truey и falsey, и значения, представляющие «truey» и «falsey», не могут быть одинаковыми.

Это , поэтому выигрывает самый короткий код в байтах!



3
Я знаю это как 0h h1 ...
Эрик Outgolfer

3
@EriktheOutgolfer Да, я начинал, зная это также как 0h h1, но Такузу - оригинальное название головоломки.
clismique

@EriktheOutgolfer Я всегда знал, что это «Binary Puzzle» или «Subiku», но «Takuzu» - это, как Qwerp-Derp упомянул оригинальное имя.
Кевин Круйссен

2
Еще несколько тестов было бы неплохо (я пропускаю большие, действительные доски.)
Lynn

Ответы:


16

Брахилог , 20 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

1
@ H.PWiz Хорошая находка, спасибо. Вернулся к 18-байтовой версии, которая работала.
Фатализировать

@ LuisMendo Я просто помещаю все строки и все столбцы в один и тот же список.
Fatalize

2
@ Згарб Правильно, спасибо. Это уже третий раз, когда мне приходилось откатывать редактирование, вступительное сообщение отчаянно нуждается в улучшенных тестовых случаях ...
Fatalize

11

Шелуха , 19 18 байт

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

Попробуйте онлайн!

1 байт сохранен благодаря H.PWiz!

Основная идея заключается в применении к входу серии преобразований, которые являются идентификаторами действительной доски, и проверке, совпадает ли конечный результат с исходным входом.

объяснение

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 это было почти очевидно, тупой меня!
Лев

7

Желе , 17 байт

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

Попробуйте онлайн!

-6 байт благодаря милям и Джонатану Аллану .


1
Я считаю, что вы можете сократить это до 21 байта. TIO
миль

@ миль ... может быть, даже 19 байтов ?
Джонатан Аллан

1
@JonathanAllan, это 18 байтов ... да, ты µZ$⁺снова сделал это: p ... и 17 байтов, немного
поменявшись

@EriktheOutgolfer Больше нет, это галстук!
Fatalize

@JonathanAllan Отлично. Также я считаю, что это первый раз, когда добавленный мной быстрый / префиксный инфикс был полезен.
миль

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)) всегда верно (список> int).
  • len(set(a))==len(set(b))==n проверяет правило 3.
  • n<'0, 0, 0' всегда верно (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достоверный ввод.
овс

3

Шелуха , 27 25 байт

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

Ввод - это список списков, а вывод - 1для Trueи 0дляFalse

Попробуйте онлайн!

Explaination

                      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 для недействительных. Редактировать: 4 байта сохранены благодаря @MartinEnder. Объяснение:

.+
$&,$&

Дублируйте каждый ряд с ,разделителями.

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

Транспонировать первый дубликат.

.+
$&;$&

Дублируйте снова, на этот раз с ;разделителями.

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

Удалите все совпадающие пары цифр перед точкой с запятой.

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

Проверьте, не нарушает ли какой-либо из столбцов или строк какое-либо из правил; (.)\1\1проверяет наличие трех одинаковых цифр подряд, \d,?;проверяет непарную цифру и (\D\d+\b).*\2проверяет дубликат.


Если цель на (...).*последнем этапе просто сделать, max(matches,1)то вы можете сохранить три байта, используя 1вместо этого в конфигурации.
Мартин Эндер

А .\b\d+\bможет быть \D\d+\b.
Мартин Эндер

@MartinEnder Изначально я заменил недействительный вывод без вывода и проверил его в конце ... В конце я отточил его до одного теста и понял, что могу опустить лидерство, .*которое ранее использовал, но не думал использовать Конфигурация для ограничения результата, спасибо!
Нил

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, Zip выше, [^, ^^] (и сгладить).
    & И выполняется ли следующее условие?
          .Am Все элементы правдивы при отображении над ^^.
              q / d \ 0 / d \ 1 Столько 0, сколько 1.
             &! + / d * 3 \ 0 / d * 3 \ 1 И нет трех одинаковых элементов.

3

MATL , 27 байт

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

Ввод представляет собой матрицу, содержащую 0и 1. Выход0 для фальши, 1для правды.

Попробуйте онлайн! Или посмотрите тестовые случаи: 1 , 2 , 3 , 4 , 5 .

объяснение

,       % 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 байт

-7 благодаря Джузеппе, вызывающему функции из строя и реально сжимающему условия

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 принимает двумерные массивы.

Выходы TRUE для сбоев, FALSE для пропусков.



Общие обновления: используемые mean(y)-.5внутри внутренней fфункции , чтобы получить средства , а не colMeans, и сделал gненазванным. Это добавит предупреждения для преобразования doubleв logicalв вызове , anyно это нормально.
Джузеппе

@ Giuseppe Спасибо! Мне очень нравится, что в сочетании применяются, очень умные изменения! У меня было 2 отдельных применения на ранней стадии, и я не понимал, насколько аккуратно их можно объединить.
Преступно-


2

Perl 6 ,100 93 байта

Переходы FTW! Они экономят 7 байтов.

В настоящее время это, кажется, превосходит все другие представления, написанные на языках, не относящихся к гольфу. Yippie!

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

Попробуйте онлайн!

Пояснение : Это блок, который принимает доску как список списков. Мы делаем транспонирование с помощью [Z] @^a(сокращаем список списков с помощью оператора zip). Так @^a,[Z] @^aже список платы и ее транспонирования. Мы зациклились на этомfor что работает точно так же map, просто в этом случае на 1 символ дешевле.

Внутри мы сначала соединяем списки, составляющие строки, в строки, поэтому у нас есть список строк вместо list lists ( @(.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. Это OR'red с |. (На самом деле он создает очень мощную вещь, называемую соединением , но мы не используем ни одну из его способностей :)) После всего этого мы получаем список из 2 «bools» (не свернутых соединений). Мы наконец или их (используя max) и negate ( !), что дает желаемый результат.


2

J, 40 38 55 байт

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

Попробуйте онлайн!

Определяет функцию, принимающую квадратную матрицу в качестве входных данных.

По крайней мере, он избивает Пита (пока ...) (ошибочно). Я должен вернуться к подсчету эмодзи, спрятанных в моем коде, поскольку 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 в противном случае. Он работает как с матрицей, так и с транспонированием, так как он дан обоим.

е

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_transи то и part_3 join_transдругое суммировалось в 0, если доска действительна. part_3должно быть все нули для действительной доски, а fсумма должна равняться нулю для действительной доски, что означает, что сумма их сумм равна 0 только для действительной доски.


По крайней мере, он избивает Пита (пока ...). - Мне действительно нужно
сыграть

@ Mr.Xcoder, хаха, да, ты всегда, кажется, справляешься с этим, поэтому я добавил немного «пока». Не то чтобы в моем ответе не было места для игры в гольф - я просто не знаю, как это сделать слишком хорошо.
Коул


1
Этот код для 33 байтов должен быть эквивалентен */@,@,&(~:,(0~:3|3+/\]),#=2*+/)|:
миль

2

Хаскелл , 137 136 127 байт

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в один 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]
Линн

@ Линн Спасибо! Я пытался свернуть эти два вместе некоторое время. Не знаю, почему я не мог понять это.
Wheat Wizard

1
Не могли бы вы изменить j=isSubSequenceOfна j x=isSubSequenceOf[x,x,x]?
Cyoce

@Cyoce Кажется, потерять мне байт. Если у вас есть способ сделать это, чтобы сэкономить мне байт, я был бы счастлив реализовать это. Идея кажется хорошей.
Мастер пшеницы

На мобильном ... хм ... Может, вместо того, чтобы 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

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или попробуйте онлайн .

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.