La piazza più grande


9

Questa domanda è simile a Biggest Square in una griglia .

Sfida

Data una matrice di 1e 0in un formato di stringa "xxxx,xxxxx,xxxx,xx.."o formato di matrice ["xxxx","xxxx","xxxx",...], verrà creata una funzione che determina l'area della matrice secondaria più grande che contiene tutto 1.

Una matrice secondaria ha una larghezza e un'altezza uguali e la funzione deve restituire l'area della matrice principale più grande che contiene solo 1.

Per esempio:

Dato "10100,10111,11111,10010", questo assomiglia alla seguente matrice:

1 0 1 0 0

1 0 1 1 1

1 1 1 1 1

1 0 0 1 0

Puoi vedere il grassetto 1creare la più grande matrice quadrata di dimensioni 2x2, quindi il tuo programma dovrebbe restituire l'area che è 4.

Regole

  • La matrice secondaria deve avere una larghezza e un'altezza uguali
  • La matrice secondaria deve contenere solo valori 1
  • La tua funzione deve restituire l'area della sottomatrix più grande
  • Nel caso in cui non venga trovata alcuna sottotrix, restituire 1
  • È possibile calcolare l'area della matrice secondaria contando il numero di 1nella matrice secondaria

Casi test

Ingresso: "10100,10111,11111,10010" Uscita: 4

Ingresso: "0111,1111,1111,1111" Uscita: 9

Ingresso "0111,1101,0111" Uscita: 1


Questo è , quindi vince la risposta più breve in byte.


3
Perché il formato stringa?
Stewie Griffin,

3
Possiamo prendere l'input come una matrice binaria (numerica)?
Stewie Griffin,

5
Per [0] è ancora richiesto l'uscita 1?
l4m2

6
Aspetta, perché restituire 1 quando non viene trovata alcuna matrice secondaria all-1, 0 non avrebbe molto più senso? (Altrimenti è semplicemente un caso speciale da gestire)
Jonathan Allan,

2
Allo stato attuale penso che a entrambi i rispondenti non dispiacerebbe se cambiassi le specifiche e consiglio vivamente di farlo perché non ha senso restituire 1 e ciò non rende le presentazioni più interessanti.
ბიმო

Risposte:


2

Gelatina , 18 byte

+2 per gestire l'output presente della sublist no-all-1

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1

Provalo online! Oppure vedi la suite di test

Come?

ẆZṡ¥"L€$ẎȦÐfL€Ṁ²»1 - Link: list of lists of 1s and 0s
Ẇ                  - all slices (lists of "rows") call these S = [s1,s2,...]
       $           - last two links as a monad:
     L€            -   length of each (number of rows in each slice) call these X = [x1, x2, ...]
    "              -   zip with (i.e. [f(s1,x1),f(s2,x2),...]):
   ¥               -     last two links as a dyad:
 Z                 -       transpose (get the columns of the current slice)
  ṡ                -       all slices of length xi (i.e. squares of he slice)
        Ẏ          - tighten (to get a list of the square sub-matrices)
          Ðf       - filter keep if:
         Ȧ         -   any & all (all non-zero when flattened?)
            L€     - length of €ach (the side length)
              Ṁ    - maximum
               ²   - square (the maximal area)
                »1 - maximum of that and 1 (to coerce a 0 found area to 1)

Eccezionale. Puoi aggiungere qualche spiegazione?
Luis felipe De jesus Munoz,

Lo farò, sto provando a pensare prima al più corto ...
Jonathan Allan,

@ Mr.Xcoder Ho aggiornato per gestire il requisito per ora
Jonathan Allan

5

Haskell , 113 121 118 117 byte

x!s=[0..length x-s]
t#d=take t.drop d
f x=last$1:[s*s|s<-min(x!0)$x!!0!0,i<-x!!0!s,j<-x!s,all(>'0')$s#i=<<(s#j)x,s>0]

Provalo online!

-3 byte grazie a Laikoni !

-1 byte grazie a Lynn !

+8 byte per il ridicolo requisito di restituire 1 per nessuna sub-matrice all-1s.

Spiegazione / Ungolfed

La seguente funzione di supporto crea solo degli offset per xconsentire di ridurli di s:

x!s=[0..length x-s]

x#yeliminerà gli yelementi da un elenco e quindi prenderà x:

t#d=take t.drop d

La funzione fscorre in ordine su tutte le dimensioni possibili per le sotto-matrici in ordine, genera ciascuna sotto-matrice della dimensione corrispondente, verifica se contiene solo se '1'memorizza la dimensione. Pertanto la soluzione sarà l'ultima voce dell'elenco:

--          v prepend a 1 for no all-1s submatrices
f x= last $ 1 : [ s*s
                -- all possible sizes are given by the minimum side-length
                | s <- min(x!0)$x!!0!0
                -- the horizontal offsets are [0..length(x!!0) - s]
                , i <- x!!0!s
                -- the vertical offsets are [0..length x - s]
                , j <- x!s
                -- test whether all are '1's
                , all(>'0') $
                -- from each row: drop first i elements and take s (concatenates them to a single string)
                              s#i =<<
                -- drop the first j rows and take s from the remaining
                                      (s#j) x
                -- exclude size 0...........................................
                , s>0
                ]

4

Haskell , 99 97 byte

b s@((_:_):_)=maximum$sum[length s^2|s==('1'<$s<$s)]:map b[init s,tail s,init<$>s,tail<$>s]
b _=1

Verifica se l'input è una matrice quadrata di solo quelli con s==('1'<$s<$s), se lo è, la risposta è lunghezza ^ 2, altro 0. Quindi taglia in modo ricorsivo la prima / ultima colonna / riga e assume il valore massimo che trova ovunque.

Provalo online!



3

J , 33 27 byte

-6 byte grazie a FrownyFrog!

[:>./@,,~@#\(#**/)@,;._3"$]

Provalo online!

Spiegazione:

Userò il primo caso di test nella mia spiegazione:

    ] a =. 3 5$1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

Genero tutte le possibili matrici quadrate con dimensioni da 1 al numero di righe dell'input.

,~@#\crea un elenco di coppie per le dimensioni delle sottomatrici cucendo insieme ,.la lunghezza dei prefissi successivi #\dell'input:

   ,~@#\ a
1 1
2 2
3 3

Quindi li uso per tagliare x u ;. _3 yl'input in sottoatrici. Ho già x(l'elenco delle dimensioni); yè l'argomento giusto ](l'input).

 ((,~@#\)<;._3"$]) a
┌─────┬─────┬─────┬───┬─┐
│1    │0    │1    │0  │0│
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │0    │1    │1  │1│
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1    │1    │1    │1  │1│
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0  │0 1  │1 0  │0 0│ │
│1 0  │0 1  │1 1  │1 1│ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│1 0  │0 1  │1 1  │1 1│ │
│1 1  │1 1  │1 1  │1 1│ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

┌─────┬─────┬─────┬───┬─┐
│1 0 1│0 1 0│1 0 0│   │ │
│1 0 1│0 1 1│1 1 1│   │ │
│1 1 1│1 1 1│1 1 1│   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

Per ogni sottomodulo controllo se è interamente composto da 1: (#**/)@,- appiattisci la matrice e metti in ordine il numero di articoli per il loro prodotto. Se tutti gli articoli sono 1s, il risultato sarà la loro somma, altrimenti - 0:

   (#**/)@, 3 3$1 0 0 1 1 1 1 1 1
0
   (#**/)@, 2 2$1 1 1 1
4 

   ((,~@#\)(+/**/)@,;._3"$]) a
1 0 1 0 0
1 0 1 1 1
1 1 1 1 1

0 0 0 0 0
0 0 4 4 0
0 0 0 0 0

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

Finalmente appiattisco l'elenco dei risultati per ogni sottomatrix e trovo il massimo:

>./@,

   ([:>./@,,~@#\(+/**/)@,;._3"$]) a
4

1
,~@#\e "1 2->"$
FrownyFrog il

@FrownyFrog Grazie! Non sapevo di"$
Galen Ivanov il

1
#è più breve dell'aggiunta di 1s.
FrownyFrog,

@ FrownyFrog Hmm, lo è davvero. Figo, grazie!
Galen Ivanov,


2

Retina , 143 byte

%`$
,;#
+%(`(\d\d.+;#)#*
$1¶$&¶$&#
\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2
)r`((11)|\d\d)(\d*,;?#*)\G
$#2$3
1,
#
Lv$`(#+).*;\1
$.($.1*$1
N`
-1G`
^$
1

Provalo online! Il link include casi di test. Accetta input come stringhe separate da virgola. Spiegazione:

%`$
,;#

Aggiungi a ,per terminare l'ultima stringa, a ;per separare le stringhe dalla se #a #come contatore.

+%(`
)

Ripeti il ​​blocco fino a quando non si verificano più sostituzioni (perché ogni stringa ora è lunga solo una cifra).

(\d\d.+;#)#*
$1¶$&¶$&#

Triplica la linea, impostando il contatore su 1 sulla prima riga e incrementandolo sull'ultima riga.

\G\d(\d+,)|\G((;#+¶|,)\d)\d+
$1$2

Nella prima riga, elimina la prima cifra di ogni stringa, mentre nella seconda riga elimina tutte le cifre tranne la prima.

r`((11)|\d\d)(\d*,;?#*)\G
$#2$3

Sulla terza riga, bit a bit e le prime due cifre insieme.

1,
#

A questo punto, ogni riga è composta da due valori, a) un contatore della larghezza orizzontale eb) bit per bit e di tanti bit presi da ciascuna stringa. Converti eventuali rimanenti 1in# s in modo che possano essere confrontate con il contatore.

Lv$`(#+).*;\1
$.($.1*$1

Trova tutte le corse di bit (in verticale) che corrispondono al contatore (in orizzontale), corrispondenti ai quadrati di 1s nell'input originale e piazza la lunghezza.

N`

Ordina numericamente.

-1G`

Prendi il più grande.

^$
1

Caso speciale la matrice zero.


2

JavaScript, 92 byte

a=>(g=w=>a.match(Array(w).fill(`1{${w}}`).join(`..{${W-w}}`))?w*w:g(w-1))(W=a.indexOf`,`)||1


2

APL (Dyalog Classic) , 21 20 byte

×⍨{1∊⍵:1+∇2×/2×⌿⍵⋄0}

Provalo online!


Ricorsione! Bello!
Zacharý,

@ Zacharý Grazie. In realtà, invece della ricorsione preferirei qualcosa come k's f \ x per una monadica f, che è (x; fx; ffx; ...) fino alla convergenza, ma non c'è equivalente in APL (ancora). Farlo con ⍣≡ richiede troppi byte.
ngn,

2

Python 2 , 117 109 byte

Ringraziamo @etene per aver segnalato un'inefficienza che mi è costata un byte aggiuntivo.

lambda s:max(i*i for i in range(len(s))if re.search(("."*(s.find(',')-i+1)).join(["1"*i]*i),s))or 1
import re

Provalo online!

Accetta l'input come stringa separata da virgola. Questo è un approccio basato su regex che prova a far corrispondere la stringa di input con i pattern del modulo111.....111.....111 per tutte le possibili dimensioni del quadrato.

Nei miei calcoli, farlo con un lambda anonimo è solo un po 'più breve della funzione definita o di un programma completo. La or 1parte alla fine è necessaria solo per gestire lo strano caso limite, dove dobbiamo emettere 1se non ce ne sono nell'input.


2

Python 2 , 116 115 117 109 byte

Ringraziamo @Kirill per avermi aiutato a giocare a golf ancora di più e per la sua soluzione intelligente e precoce

Modifica : golfato 1 byte usando un lambda, non sapevo che assegnarlo a una variabile non contava per il conteggio dei byte.

Modifica 2 : Kirill ha sottolineato che la mia soluzione non ha funzionato nei casi in cui l'input contiene solo1 s, ho dovuto ripararlo e ho perso due preziosi byte ...

Modifica 3 : più golf grazie a Kirill

Accetta una stringa separata da virgola, restituisce un numero intero.

lambda g:max(i*i for i in range(len(g))if re.search(("."*(g.find(",")+1-i)).join(["1"*i]*i),g))or 1
import re

Provalo online!

Ho trovato in modo indipendente una risposta vicina a quella di Kiril, ovvero basata su regex, tranne che uso re.search e adef .

Usa una regex creata durante ogni ciclo per abbinare un quadrato incrementalmente più grande e restituisce il più grande, o 1.


1
Bene, in qualche modo ho scartato automaticamente l' ifapproccio come "troppo lungo per certo", ma poi ho dovuto inventare un altro modo per ottenere un valore bool della partita. Sfortunatamente, la tua soluzione manca di un punto - non puoi averne solo range(l)- mancherà il caso quando non ci sono zero. Ad esempio, prendi il 2 ° caso di test e rendilo tutto 1s - dovrebbe diventare 16, non 9.
Kirill L.

Accidenti, ho pensato di provare con tutti gli zero ma non con tutti (mai menzionato nella sfida ...). Proverò a inventarmi qualcosa.
etene,

@KirillL. a proposito, sei veloce! Stavo ancora lavorando alla mia risposta quando hai pubblicato la tua ed ero un po 'sconvolta (e orgogliosa!) Quando ho visto che i nostri approcci erano simili ... il livello qui intorno è impressionante.
etene,

1
Golfato qualche byte in più eliminando duplicati find. Ora che i nostri codici non sono più identici, suggerisco almeno di correggere gli errori evidenti gli uni dagli altri - nel tuo caso il byte extra proviene dall'uso della tupla ("1"*i,)invece dell'elenco.
Kirill L.,

Grazie, sì, l'inutile tupla è piuttosto stupida da parte mia. E anche quello in più find, è stato intelligente da parte tua.
etene,



1

Python 2 , 138 128 byte

def f(m):j=''.join;L=j(m);k=map(j,zip(*m));return len(L)and max(len(L)*(len(m)**2*'1'==L),f(k[1:]),f(k[:-1]),f(m[1:]),f(m[:-1]))

Provalo online!


Salvato

  • -10 byte grazie agli ovs

1

Clojure, 193 byte

#(apply max(for [f[(fn[a b](take-while seq(iterate a b)))]R(f next %)R(f butlast R)n[(count R)]c(for[i(range(-(count(first R))n -1)):when(apply = 1(for[r R c(subvec r i(+ i n))]c))](* n n))]c))

Wow, le cose sono aumentate: o

Meno golf:

(def f #(for [rows (->> %    (iterate next)    (take-while seq)) ; row-postfixes
              rows (->> rows (iterate butlast) (take-while seq)) ; row-suffixes
              n    [(count rows)]
              c    (for[i(range(-(count(first rows))n -1)):when(every? pos?(for [row rows col(subvec row i(+ i n))]col))](* n n))] ; rectangular subsections
          c))
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.