Contexte
Je veux acheter un terrain et y construire ma maison. Ma maison doit être rectangulaire et aussi grande que possible; cependant, les parcelles disponibles ont beaucoup de zones rocheuses sur lesquelles je ne peux pas construire, et j'ai du mal à installer une maison potentielle sur les parcelles. Je veux que vous écriviez un programme qui analyse les parcelles pour moi.
Entrée et sortie
Votre entrée est un tableau 2D rectangulaire de bits, de taille au moins 1 × 1, dans n'importe quel format raisonnable. Le tableau représente une parcelle de terrain; 1
s sont de "bonnes" zones où je pourrais construire ma maison, et 0
s sont des zones "rocheuses" où la maison ne peut pas être construite.
Votre sortie doit être l'aire maximale d'un rectangle plein de 1
s dans le tableau d'entrée. Il représente la superficie de la plus grande maison que j'ai pu construire sur le terrain. Notez que s'il n'y a pas de 1
s dans l'entrée, alors la sortie l'est 0
.
Exemple
Considérez l'entrée
101
011
111
Le plus grand rectangle de 1
s est le rectangle 2 × 2 dans le coin inférieur droit. Cela signifie que la sortie correcte est 4
.
Règles et notation
Vous pouvez écrire un programme complet ou une fonction. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites.
Cas de test
0
-> 0
1
-> 1
00
00
-> 0
01
10
-> 1
01
11
-> 2
111
010
111
-> 3
101
011
111
-> 4
0111
1110
1100
-> 4
1111111
1110111
1011101
-> 7
111011000
110111100
001111110
011111111
001111110
000111100
000011000
-> 20
000110000
110110010
110111110
110011100
010011111
111111111
111101110
-> 12
plow
.Réponses:
Gelée ,
21201817 octetsEssayez-le en ligne! ou vérifiez tous les cas de test .
Contexte
Soit M une matrice de bits telle que
Nous commençons par compter le nombre de 1 bits dans chaque colonne de M , en réinitialisant le compte chaque fois que nous rencontrons un bit de 0 .
Pour notre exemple de matrice, cela donne
Ensuite, nous calculons toutes les sous-listes contiguës de chaque ligne. Nous y parvenons en générant toutes les tranches de longueur k , où k varie entre 1 et le nombre d'entrées dans chaque ligne.
Pour l'avant-dernière ligne, cela donne
Ensuite, nous mappons chaque tranche sur le produit de son minimum et de sa longueur. Pour chaque tranche, cela calcule l'aire du rectangle de 1 bits de hauteur maximale qui a la tranche donnée comme ligne du bas.
Pour les tranches de longueur 3 de l'avant-dernière ligne de notre exemple de matrice, cela donne
Il ne reste plus qu'à prendre le maximum sur toutes les tranches de toutes les lignes.
Pour notre exemple de matrice, cela donne 12 .
Comment ça marche
la source
MATL,
323127 octetsCela utilise une approche basée sur la convolution 2D par force brute. Toutes les tailles de rectangle possibles sont créées et convolutées avec le terrain. Le résultat maximum de toutes les circonvolutions est la zone de rectangle maximale.
C'est une solution extrêmement inefficace car pour économiser des octets, je crée des noyaux pour tous les rectangles entre
[1, 1]
et[numel(input) numel(input)]
plutôt que de déterminer réellement le nombre de lignes / colonnes dans l'entrée pour déterminer les plages de dimensions de rectangle appropriées.Merci à @Luis d'avoir suggéré l'utilisation
M
et omis le]]
.Essayez-le en ligne!
Explication
la source
Julia,
83605753 octetsEssayez-le en ligne! Le dernier cas de test dépasse le délai de TIO, mais je l'ai vérifié localement.
Comment ça marche
Tout d'abord ! vérifie si son argument de matrice M est entièrement composé de 1 .
Si oui ,! renvoie la somme des entrées de M , qui est égale à sa surface.
Sinon ,! fait ce qui suit:
Tournez M de 0 ° , 90 ° , 180 ° et 270 ° dans le sens horaire.
Retirer la première ligne de chacune des quatre rotations, éliminant efficacement une de rangée supérieure, rangée du bas, colonne de gauche et la colonne droite de M .
Appelez-vous récursivement sur chacune des sous-matrices.
Renvoie le maximum des valeurs de retour des appels récursifs.
la source
JavaScript (ES6), 97 octets
Il s'avère que le twiddling peu gagne toujours. Accepte un tableau de tableau d'entiers. Non golfé:
Le tableau est découpé en lignes selon les autres réponses, de sorte que chaque plage possible de lignes est bouclée. Étant donné une plage de lignes, l'étape suivante consiste à mesurer les rectangles disponibles. Ceci est réalisé en ANDant les lignes ensemble au niveau du bit; le résultat est une liste de bits qui ont été définis dans toute la plage de lignes. Il reste alors à trouver la longueur maximale des bits définis dans la ligne et à la multiplier par la hauteur de la plage. Test sans vergogne volé à @ ed65:
la source
Python 2.7,
9391898179 octetsL'entrée est une liste de tuples. Vérifiez les plus petits cas de test ici et les plus grands cas de test ici .
Sans mémorisation, les deux derniers cas de test dépassent le délai d'Ideone, car ils nécessitent respectivement 1 530 831 935 et 2 848 806 121 appels vers f , ce qui prend 39 et 72 minutes sur ma machine.
Algorithme
Pour une matrice M donnée , l'idée générale est d'itérer sur toutes les sous-matrices de M en supprimant les rangées supérieures et en faisant tourner les quarts de tour dans le sens antihoraire, en gardant une trace des tailles des sous-matrices rencontrées qui se composent entièrement de 1 bit.
Jouer une implémentation récursive simple de l'idée ci-dessus conduit à une fonction f (M) qui fait ce qui suit.
Si M ne contient aucun 0 bit, retourne son nombre de 1 bit.
Si nous avons pivotée M deux fois déjà et il ne contient pas de 1 bits retour 0 .
Si nous avons déjà tourné M cinq fois, retournez 0 .
Appeler récursivement f sur M sans sa ligne supérieure.
Appeler récursivement f sur M tourné d'un quart de tour dans le sens antihoraire.
Renvoie le maximum des valeurs de retour des appels récursifs.
Code
Dans l'implémentation, nous utilisons un argument de fonction supplémentaire t par défaut à 1 pour garder une trace du nombre de fois où nous avons déjà tourné cette matrice particulière. Cela permet de condenser les étapes 1 à 3 en une seule étape en testant
`t/3`in`M`
et en retournant`M`.count(`t`)
si le test échoue.Si t = 1 , nous n'avons pas fait tourner cette sous-matrice particulière précédemment dans cette branche.
t / 3 = 0 , donc
`t/3`in`M`
retournera True si la représentation sous forme de chaîne de M contient le caractère 0 .Si elle n'a pas, nous reviendrons
`M`.count(`t`)
, le nombre de fois que le caractère 1 apparaît dans la représentation de chaîne de M .Notez qu'une matrice sans 0 bit ne peut apparaître que si t = 1 , puisque nous ne récurrons pas dans ce cas.
Si 3 ≤ t ≤ 5 , nous avons précédemment tourné cette sous-matrice particulière au moins deux fois dans cette branche.
t / 3 = 1 , donc
`t/3`in`M`
retournera True si la représentation sous forme de chaîne de M contient le caractère 1 .Si elle ne le fait pas, nous revenons 0 calculé comme
`M`.count(`t`)
le nombre de fois la représentation de chaîne de t ( par exemple, le caractère 3 , 4 ou 5 ) apparaît dans la représentation de chaîne de M .Si t = 6 , nous avons précédemment tourné cette sous-matrice particulière cinq fois dans cette branche.
t / 3 = 2 ,
`t/3`in`M`
renvoie donc False , car la représentation sous forme de chaîne de M ne contient pas le caractère 2 .Nous revenons 0 calculé comme
`M`.count(`t`)
, le nombre de fois que le caractère 6 apparaît dans la représentation de chaîne de M .Si f n'est pas déjà retourné, les étapes restantes sont exécutées.
f(M[1:])
appelle f sur M sans sa ligne supérieure. Puisque t n'est pas spécifié, il vaut 1 par défaut , signalant que c'est la première fois que f rencontre cette sous-matrice particulière dans cette branche.f(zip(*M)[::-1],t+1)
les appels f sur M ont tourné d'un quart de tour dans le sens antihoraire, incrémentant t pour garder une trace du temps pendant lequel nous avons fait tourner cette sous-matrice particulière dans cette branche.Le quart de tour est obtenue par zipping les rangées de M avec l'autre, le retour tuples des éléments de concordance M rangées d », ainsi transposant M , puis en inversant l'ordre des lignes ( par exemple, en plaçant la ligne de haut en bas et vice - versa ).
max
Retourne enfin le maximum des valeurs de retour des appels récursifs.la source
zip
renvoie une liste de tuples des éléments correspondants de ses arguments. Avec une liste 2D non matricielle (matrice)*M
, il transpose essentiellement les lignes et les colonnes,zip(*M[::-1])
effectue donc une rotation de 90 ° dans le sens horaire.JavaScript (ES6), 154
176Edit a essayé de raccourcir un peu, mais ne peut pas rivaliser avec la solution de @ Neil
Essayez tous les rectangles possibles, renvoyez la taille maximale. Probablement le même algorithme de la réponse Matl, juste 6 fois plus longtemps.
Entrée sous forme de tableau 2d d'entiers
Moins golfé
Ceci est l'algorithme d'origine, la version golfée abuse de beaucoup de fonctions de traversée de tableau au lieu des boucles for
Tester
la source
APL (Dyalog Extended) ,
272320 octets-3 octets par Adám et ngn
Essayez-le en ligne!
la source
{⌈/,(×/×1∊⍵⍷⍨⍴∘1)¨⍳⍴⍵}
est plus court et plus simple (ne nécessite même pas Extended).{⌈/∊(×/×⍵⍷⍨⍴∘1)¨⍳⍴⍵}
Brachylog ,
201715 octetsMerci à Kroppeb pour 2 octets
Essayez-le en ligne!
Explication
la source
aa
peut être remplacé pars
Essayez-le en ligne!R ,
129122 octetsEssayez-le en ligne!
Approche brute et simple de la force brute.
Code déroulé et explication:
la source
Stax , 14 octets
Exécuter et déboguer
la source
Matlab 106 octets
Non golfé:
L'opération dans la boucle commence par une convolution 2D
conv2()
du tableau d'entrée avec lep*m
tableau de ceux-ci.==p*m
vérifie si le tableau résultant contient un élément égal àp*m
. L'élément correspondant est tourné vers1
, tous les autres éléments sont tournés vers0
.any()
transforme le tableau en vecteur.1
Sinon, les colonnes contenant au moins une entrée différente de zéro sont converties0
.p*m*()
multiplie le vecteur enp*m
transformant ainsi tous les1
-s enp*m
.[__,r]
les crochets concaténent le résultat obtenu avec la zone maximale précédente stockée dansr
. Enfin,max()
trouve la valeur maximale dans le vecteur résultant.la source
any()
renvoie1
si la colonne contient un élément différent de zéro et0
sinon.Matlab
(222)(209)En fait, cette solution me fait honte d'être deux fois la vraie solution dans la même langue mais ... blimey, j'y pensais depuis 6 heures! et l'astuce est une construction légèrement différente des réponses de Dennis et Neil.
La fonction est appelée comme
Je pourrais économiser plus d'octets si la longueur de la matrice était introduite dans les dimensions de la fonction, même si plus de golf était en cours.
Comment cela se passe-t-il?
Cet algorithme ajoute la matrice réelle à elle-même décalée de celle-ci vers la gauche, avec un peu de twiddling (&). à n'importe quel stade, la matrice résultante est définie comme initiale et ajoutée à elle-même, décalée vers le haut à plusieurs reprises, puis recroquevillée depuis le début avec la nouvelle matrice. Tous les sous-éléments de toutes les matrices générées par cette opération
(original_matrix+shifted_matrix)&shifted_and_original_matrices)
sont maximisés en sortie.exemple:
la source
Japt , 30 octets
Essayez tous les cas de test
Environ un port de Dennis's Jelly répond. Les cas de test sont simplement des tableaux 2D de nombres, convertis à partir du format de la question en utilisant ceci .
Explication:
la source
J , 38 octets
Essayez-le en ligne!
Comment
la source