Dividi una griglia in una griglia


22

introduzione

C'è un piccolo villaggio con nient'altro che poche case e campi vuoti. I burocrati locali vogliono dividere il villaggio in lotti in modo tale che ogni lotto contenga esattamente una casa e i bordi dei lotti formino una bella griglia in linea retta. Il tuo compito è determinare se questo è possibile.

L'obiettivo

Il tuo input è un array 2D rettangolare di bit; 1 rappresenta una casa e 0 un campo vuoto. La sua dimensione sarà almeno 1 × 1 e conterrà almeno un 1. È possibile accettare l'input in qualsiasi formato ragionevole (elenco nidificato di numeri interi, elenco di stringhe, stringa multilinea ecc.).

Il programma determinerà se l'array può essere diviso in celle della griglia usando linee orizzontali e verticali diritte in modo tale che ciascuna cella della griglia ne contenga esattamente 1. Le celle della griglia possono avere dimensioni e forme diverse, sebbene siano sempre rettangolari. Le linee devono passare da un bordo dell'array al bordo opposto.

Ad esempio, la seguente è una divisione valida di un array:

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

mentre la seguente divisione non è valida, poiché ci sono celle della griglia senza 1 o più di 1:

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

Se esiste una divisione valida, dovrai generare un valore di verità, e altrimenti un valore di falsa.

Regole e punteggio

È possibile scrivere un programma completo o una funzione. Vince il conteggio dei byte più basso.

Casi test

[[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]] può essere diviso in: 3X1, 2X1, 3X2, 2X1, Rettangoli 2X1 in questo modo o no? 001 | 01 --- + - 100 | 10 + - 000 | 10
officialaimm

4
@officialaimm No, questo non è valido. Le linee della griglia devono passare da un lato dell'array fino all'altro lato.
Zgarb,

Caso di prova proposto: [[1, 0, 1], [0, 1, 0], [1, 0, 0]]questa era l'unica matrice 3x3 per cui il mio nuovo approccio non andava a buon fine.
Dennis,

@Dennis Grazie, aggiunto.
Zgarb,

Risposte:


7

Pyth, 30 29 26 24 23 byte

sm.Asmmq1ssbCkds./MC./M

Provalo online.

Sono sicuro che questo si accorcia. Questo è O (2 mn ) , dove m e n sono la larghezza e l'altezza dell'array, ma completa gli ultimi due casi di test in 45 secondi sul mio laptop a batteria (i5-5200U con prestazioni limitate).

Emette il numero di soluzioni.

Spiegazione

Le matrici tridimensionali sono davvero divertenti con cui lavorare. </sarcasm> Non dovresti capire come funziona anche con la spiegazione.

                    ./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 byte

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

Provalo online!


1
Questo non viene compilato. Elimina la tua risposta fino a quando non viene risolta. Esiste anche un grande potenziale di golf, ad es. rinominando mergerowsin m.
Laikoni,

Avevo intenzione di rimanere senza competizione a causa della brevità della brevità di Pyth e grazie a te @Laikoni per aver individuato che probabilmente ho incasinato le mie parentesi graffe.
Roman Czyborra,

2
Questo dà erroneamente False [[1,0],[0,1],[1,0]]. Il problema è che un crollo avido può ostacolare un successivo crollo migliore.
xnor

In effetti, il mio [[1,1],[1,0]]crollo ostacola falsamente la [[1],[1],[1]]soluzione. Lasciami dormire su questo o dovrei eliminare?
Roman Czyborra,


1

Gelatina , 20 byte

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

Questa è ancora una soluzione a forza bruta, ma è un po 'più veloce della mia altra risposta - che non può far fronte agli ultimi due casi di test su TIO - e gestisce tutti i casi di test in ~ 4 secondi.

Provalo online!

Come funziona

ŒṖ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.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.