Fractionner une grille en une grille

22

introduction

Il y a un petit village avec seulement quelques maisons et des champs vides. Les bureaucrates locaux veulent diviser le village en lots de sorte que chaque lot contienne exactement une maison, et les limites des lots forment une belle grille en ligne droite. Votre tâche consiste à déterminer si cela est possible.

La tâche

Votre entrée est un tableau 2D rectangulaire de bits; 1 représente une maison et 0 un champ vide. Sa taille sera d'au moins 1 × 1 et il contiendra au moins un 1. Vous pouvez prendre l'entrée dans n'importe quel format raisonnable (liste imbriquée d'entiers, liste de chaînes, chaîne multiligne, etc.).

Votre programme doit déterminer si le tableau peut être divisé en cellules de grille en utilisant des lignes droites horizontales et verticales de sorte que chaque cellule de grille en contienne exactement un 1. Les cellules de grille peuvent avoir différentes tailles et formes, bien qu'elles soient toujours rectangulaires. Les lignes doivent s'étendre d'un bord du tableau au bord opposé.

Par exemple, ce qui suit est une division valide d'un tableau:

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

alors que la division suivante n'est pas valide, car il existe des cellules de grille sans 1 ou plus d'un 1:

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

S'il existe une division valide, vous devez afficher une valeur véridique, et sinon une valeur falsifiée.

Règles et notation

Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas gagne.

Cas de 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
Zgarb
la source
[[0,0,1,0,1], [1,0,0,1,0], [0,0,0,1,0]] peuvent être divisés en: 3X1, 2X1, 3X2, 2X1, Rectangles 2X1 de cette manière ou non? 001 | 01 --- + - 100 | 10 + - 000 | 10
officialaimm
4
@officialaimm Non, ce n'est pas valide. Les lignes de la grille doivent s'étendre d'un côté de la baie jusqu'à l'autre côté.
Zgarb
Cas de test proposé: [[1, 0, 1], [0, 1, 0], [1, 0, 0]]C'était la seule matrice 3x3 pour laquelle ma nouvelle approche échouait.
Dennis
@Dennis Merci, a ajouté.
Zgarb

Réponses:

7

Pyth, 30 29 26 24 23 octets

sm.Asmmq1ssbCkds./MC./M

Essayez-le en ligne.

Je suis sûr que cela raccourcira. Il s'agit de O (2 mn ) , où m et n sont la largeur et la hauteur de la baie, mais complète les deux derniers cas de test en 45 secondes sur mon ordinateur portable sur batterie (i5-5200U avec des performances limitées).

Affiche le nombre de solutions.

Explication

Les tableaux à cinq dimensions sont vraiment amusants à travailler. </sarcasm> Vous n'êtes pas censé comprendre comment cela fonctionne même avec l'explication.

                    ./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.
PurkkaKoodari
la source
2

Haskell , 116 octets

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

Essayez-le en ligne!

Roman Czyborra
la source
1
Cela ne compile pas. Veuillez supprimer votre réponse jusqu'à ce qu'elle soit corrigée. Il y a aussi beaucoup de potentiel golfique, par exemple. renommer mergerowsen m.
Laikoni
Je prévoyais de manquer de compétition en raison de la brièveté de Pyth difficile à battre et merci à toi @Laikoni pour avoir repéré j'ai probablement gâché mes accolades d'indentation.
Roman Czyborra
2
Cela donne incorrectement False [[1,0],[0,1],[1,0]]. Le problème est qu'un effondrement gourmand peut entraver un effondrement ultérieur meilleur.
xnor
En effet, mon [[1,1],[1,0]]effondrement entrave faussement la [[1],[1],[1]]solution. Laissez-moi dormir là-dessus ou dois-je supprimer?
Roman Czyborra
1

Gelée , 20 octets

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

C'est toujours une solution de force brute, mais c'est un peu plus rapide que mon autre réponse - qui ne peut pas faire face aux deux derniers cas de test sur TIO - et gère tous les cas de test en ~ 4 secondes.

Essayez-le en ligne!

Comment ça marche

ŒṖ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.
Dennis
la source