Розбийте сітку на сітку


22

Вступ

Є маленьке село, що не має нічого, крім кількох будинків і порожніх полів. Місцеві бюрократи хочуть розділити село на партії, щоб кожен лот містив рівно один будинок, а межі лотів утворювали приємну прямолінійну сітку. Ваше завдання - визначити, чи це можливо.

Завдання

Ваш вхід - це прямокутний 2D масив бітів; 1 являє собою будинок, а 0 - порожнє поле. Його розмір буде принаймні 1 × 1 , і він буде містити принаймні один 1. Ви можете взяти вхід у будь-якому розумному форматі (вкладений список цілих чисел, список рядків, багаторядковий рядок тощо).

Ваша програма визначає, чи можна масив поділити на комірки сітки за допомогою прямих горизонтальних і вертикальних ліній, щоб кожна комірка сітки містила рівно одну 1. Осередки сітки можуть мати різний розмір і форму, хоча вони завжди будуть прямокутними. Рядки повинні проходити від одного краю масиву до протилежного краю.

Наприклад, наступним є дійсний поділ масиву:

00|0010|01|1
01|0000|00|0
--+----+--+-
00|0000|00|1
01|0010|01|0
--+----+--+-
01|1000|10|1

враховуючи, що наступний поділ недійсний, оскільки є комірки сітки, що не мають 1 або більше однієї 1:

00|0010|01|1
--+----+--+-
01|0000|00|0
00|0000|00|1
01|0010|01|0
--+----+--+-
00|1000|10|1

Якщо існує дійсний поділ, ви повинні виводити значення "truthy", а інакше - хибне значення.

Правила та оцінка

Ви можете написати повну програму або функцію. Виграє найменший байт.

Тестові кейси

[[1]] -> True
[[0,1],[1,0]] -> True
[[1,1],[1,0]] -> False
[[1,0,1],[0,1,0]] -> True
[[1,0],[0,1],[0,1]] -> True
[[1,0,0],[0,0,1],[0,1,1]] -> True
[[1,1,1],[1,1,1],[1,1,1]] -> True
[[1,0,1],[0,1,0],[1,0,0]] -> True
[[1,0,0],[1,0,0],[0,1,1]] -> False
[[0,0,0,0,1],[1,0,0,1,0],[0,0,0,1,0]] -> False
[[0,0,1,0,1],[0,0,0,1,0],[0,0,0,0,0]] -> True
[[1,1,0,0,0],[0,0,0,0,0],[1,0,1,0,0]] -> True
[[1,1,0,1,1],[0,1,0,1,1],[1,0,0,0,0]] -> True
[[0,0,0,0,0,0,0],[0,1,1,1,0,1,0],[0,1,0,0,1,0,0],[0,0,0,0,0,0,1],[0,0,1,0,0,0,1],[1,1,0,1,1,0,0]] -> False
[[1,1,0,0,0,0,0],[1,0,1,1,0,1,0],[0,0,0,0,1,0,0],[0,1,0,1,1,0,0],[1,0,0,0,1,1,0],[0,0,0,0,0,1,0]] -> False
[[0,1,0,1,1,1,0],[0,0,0,0,1,0,0],[0,0,0,0,0,0,0],[1,0,0,1,0,0,0],[0,0,0,0,0,0,0],[0,0,0,0,0,0,1]] -> True
[[0,1,0,0,1,0,1],[1,0,0,0,1,0,1],[0,0,1,0,1,0,1],[1,0,0,0,1,1,0],[0,0,0,1,1,1,0],[0,1,0,0,1,0,1]] -> True
[[0,1,0,0,1,0,0,1,0],[0,0,0,0,1,1,0,1,0],[1,1,0,0,1,0,0,0,0],[0,0,1,0,1,0,1,0,0],[0,0,1,0,1,0,1,0,0],[0,1,0,0,0,1,0,0,1],[0,1,0,0,0,0,1,0,0]] -> False
[[1,0,1,0,0,1,1,0,1],[0,1,1,0,0,1,1,0,1],[1,0,0,0,0,1,0,0,0],[0,0,0,0,0,0,0,0,0],[0,0,1,0,0,0,0,1,1],[0,1,1,0,1,0,1,0,1],[1,0,1,0,0,1,1,0,1]] -> True

чи можна [[0,0,1,0,1], [1,0,0,1,0], [0,0,0,1,0]] поділити на: 3X1, 2X1, 3X2, 2X1, 2X1 прямокутники таким чином чи ні? 001 | 01 --- + - 100 | 10 + - 000 | 10
officialalaimm

4
@officialaimm Ні, це не вірно. Лінії сітки повинні проходити від однієї сторони масиву аж до іншої сторони.
Згарб

Запропонований тестовий випадок: [[1, 0, 1], [0, 1, 0], [1, 0, 0]]це була єдина матриця 3x3, для якої мені не вдалося новий підхід.
Денніс

@Dennis Спасибі, додано.
Згарб

Відповіді:


7

Pyth, 30 29 26 24 23 байт

sm.Asmmq1ssbCkds./MC./M

Спробуйте в Інтернеті.

Я впевнений, що це стане коротшим. Це O (2 mn ) , де m і n - ширина і висота масиву, але завершує два останні тестові випадки за 45 секунд на моєму ноутбуці на батареї (i5-5200U з обмеженою продуктивністю).

Виводить кількість рішень.

Пояснення

П’ятивимірні масиви справді цікаво працювати. </sarcasm> Ви не повинні розуміти, як це працює навіть із поясненням.

                    ./M    Find all partitions of each row. Now we have a list of rows,
                           each containing the ways to split the row, each containing
                           the parts of the split (3D).
                   C       Transpose. Now we have a list of ways to split the columns,
                           each containing the rows, each containing the parts of the
                           row (3D).
                ./M        Find all partitions of each row list. Now we have a list of
                           ways to split the columns, each containing the ways to split
                           the rows, each containing the bunch of rows, each containing 
                           the rows in the bunch, each containing the parts of the row
                           (6D).
               s           Combine the ways to split rows & columns into one array (5D).
 m            d            Do the following for each way to split rows & columns (4D):
     m       k                 Do the following for each bunch of rows (3D):
            C                      Transpose the array. We now have a list of column
                                   groups, each containing the row parts (3D).
      m    b                       Do the following for each column group (2D):
          s                            Combine the row parts in the column group. We now
                                       have the list of cells in this row/column group
                                       (1D).
         s                             Sum the cells.
       q1                              Check if the sum is one.
                                   We now have the list of booleans that tell if each
                                   row/column group is valid (1D).
                               We now have the 2D list of booleans that tell if each
                               row/column group in each bunch of rows is valid. (2D)
    s                          Combine the 2D list of booleans to 1D.
  .A                           Check if all values are truthy; if the split is valid.
                           We now have the validity of each split.
s                          Sum the list to get the number of valid solutions.


2

Haskell , 116 байт

import Data.List
m(a:b)=[a:e|e<-m b]++[zipWith(+)a d:e|d:e<-m b];m e=[e]
d=(any$any$all$all(==1)).map(m.transpose).m

Спробуйте в Інтернеті!


1
Це не компілюється. Видаліть свою відповідь, поки вона не буде виправлена. Також є багато потенціалу для гольфу, наприклад. перейменування mergerowsна m.
Лайконі

Я планував закінчитися конкуренцією завдяки важко переможеній стислість Pyth і дякую тобі @Laikoni за те, що я помітив, я, швидше за все, зіпсував свої відступи.
Роман Чиборра

2
Це неправильно дає False увімкнено [[1,0],[0,1],[1,0]]. Проблема полягає в тому, що жадібний крах може стати на шляху подальшого кращого краху.
xnor

Справді, мій [[1,1],[1,0]]крах помилково перешкоджає [[1],[1],[1]]вирішенню. Дозвольте мені поспати над цим чи треба видалити?
Роман Чиборра


1

Желе , 20 байт

ŒṖS€€ỊȦ$ÐfZ€µ⁺€Ȧ€€FS

Це все ще жорстоке рішення, але це трохи швидше, ніж моя інша відповідь - яка не впорається з двома останніми тестовими випадками в TIO - і обробляє всі тестові справи за ~ 4 секунди.

Спробуйте в Інтернеті!

Як це працює

ŒṖS€€ỊȦ$ÐfZ€µ⁺€Ȧ€€FS  Main link. Argument: M (matrix, array of rows)

ŒṖ                    Compute all partitions, i.e., all groupings of M's rows.
  S€€                 Map sum over all individual groupings, collapsing the grouped
                      rows into a single row.
        Ðf            Filter; keep only those partially collapsed matrices for
                      which the link to the left returns a truthy value.
       $                Group the two links to the left into a monadic chain.
     Ị                    Insignificant; map 0 and 1 to 1, greater integers to 0.
      Ȧ                   All; return 1 iff the matrix contains no zeroes.
          Z€          Zip/transpose all kept matrices,
            µ         Combine all links to the left into a monadic chain.
             ⁺€       Duplicate the chain and map it over the individual results
                      from the first call. We now have all possible combinations
                      of row and column groupings (represented by the corresponding
                      matrices of collapsed rows and columns) that do not have a
                      2 anywhere. However, they still may contain zeroes.
               Ȧ€€    Map the all atom over the matrices, returning 1 only for
                      matrices that consist entirely of ones.
                  FS  Flatten and sum, counting the number of valid divisions.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.