Der größte Platz


9

Diese Frage ähnelt dem größten Platz in einem Raster .

Herausforderung

Bei einer Matrix von 1und 0in einem Zeichenfolgen- "xxxx,xxxxx,xxxx,xx.."oder Array-Format ["xxxx","xxxx","xxxx",...]erstellen Sie eine Funktion, die den Bereich der größten quadratischen Submatrix bestimmt, die alle enthält 1.

Eine quadratische Submatrix hat die gleiche Breite und Höhe, und Ihre Funktion sollte den Bereich der größten Submatrix zurückgeben, die nur enthält 1.

Beispielsweise:

Gegeben "10100,10111,11111,10010", das sieht aus wie die folgende Matrix:

1 0 1 0 0

1 0 1 1 1

1 1 1 1 1

1 0 0 1 0

Sie können sehen, dass die Fettschrift 1die größte quadratische Submatrix der Größe 2x2 erstellt, sodass Ihr Programm den Bereich zurückgeben sollte, der 4 ist.

Regeln

  • Die Submatrix muss gleich breit und hoch sein
  • Die Submatrix darf nur Werte enthalten 1
  • Ihre Funktion muss den Bereich der größten Submatrix zurückgeben
  • Falls keine Submatrix gefunden wird, kehren Sie zurück 1
  • Sie können die Fläche der Submatrix berechnen, indem Sie die Anzahl 1der Submatrix zählen

Testfälle

Eingabe: "10100,10111,11111,10010" Ausgabe: 4

Eingabe: "0111,1111,1111,1111" Ausgabe: 9

Eingabe "0111,1101,0111" Ausgabe: 1


Dies ist , also gewinnt die kürzeste Antwort in Bytes.


3
Warum String-Format?
Stewie Griffin

3
Können wir die Eingabe als binäre (numerische) Matrix nehmen?
Stewie Griffin

5
Für [0] noch 1 ausgeben?
14 m2

6
Bleib dran, warum 1 zurückgeben, wenn keine All-1-Submatrix gefunden wird, wäre 0 nicht viel sinnvoller? (Ansonsten ist es einfach ein Sonderfall)
Jonathan Allan

2
So wie es aussieht, würde es beiden Antwortenden nichts ausmachen, wenn Sie die Spezifikationen ändern, und ich empfehle dies dringend, da es keinen Sinn macht, 1 zurückzugeben, und dies macht die Einsendungen nicht interessanter.
25.

Antworten:


2

Gelee , 18 Bytes

+2, um die aktuelle Ausgabe der Nicht-Unterliste 1 zu verarbeiten

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

Probieren Sie es online aus! Oder sehen Sie sich die Testsuite an

Wie?

Ẇ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)

Genial. Können Sie eine Erklärung hinzufügen?
Luis Felipe De Jesus Munoz

Ich werde, ich versuche zuerst an kürzere zu denken ...
Jonathan Allan

@ Mr.Xcoder Ich habe aktualisiert, um die Anforderung für jetzt zu behandeln
Jonathan Allan

5

Haskell , 113 121 118 117 Bytes

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]

Probieren Sie es online aus!

-3 Bytes dank Laikoni !

-1 Byte danke an Lynn !

+8 Bytes für die lächerliche Anforderung, 1 für keine All-1s-Submatrix zurückzugeben.

Erklärung / Ungolfed

Die folgende Hilfsfunktion erstellt nur Offsets, um xsie dekrementieren zu können um s:

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

x#ylöscht yElemente aus einer Liste und nimmt dann x:

t#d=take t.drop d

Die Funktion fdurchläuft alle möglichen Größen für Untermatrizen der Reihe nach, generiert jede Untermatrix der entsprechenden Größe, prüft, ob sie nur '1's enthält, und speichert die Größe. Somit ist die Lösung der letzte Eintrag in der Liste:

--          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 Bytes

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

Überprüft, ob die Eingabe eine quadratische Matrix von nur Einsen s==('1'<$s<$s)ist. Wenn dies der Fall ist, lautet die Antwort Länge ^ 2, sonst 0. Dann wird die erste / letzte Spalte / Zeile rekursiv zerhackt und der maximal gefundene Maximalwert verwendet.

Probieren Sie es online aus!



3

J , 33 27 Bytes

-6 Bytes dank FrownyFrog!

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

Probieren Sie es online aus!

Erläuterung:

Ich werde den ersten Testfall in meiner Erklärung verwenden:

    ] 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

Ich generiere alle möglichen quadratischen Submatrizen mit einer Größe von 1 bis zur Anzahl der Zeilen der Eingabe.

,~@#\,.Erstellt eine Liste von Paaren für die Größe der Submatrizen, indem die Länge der aufeinanderfolgenden Präfixe #\der Eingabe zusammengefügt wird:

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

Dann benutze ich sie, um x u ;. _3 ydie Eingabe in Submatrizen zu schneiden . Ich habe bereits x(die Liste der Größen); yist das richtige Argument ](die Eingabe).

 ((,~@#\)<;._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│   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
│     │     │     │   │ │
├─────┼─────┼─────┼───┼─┤
│     │     │     │   │ │
└─────┴─────┴─────┴───┴─┘

Für jede Submatrix überprüfe ich, ob sie vollständig aus 1s besteht: (#**/)@,- Reduzieren Sie die Matrix und multiplizieren Sie die Anzahl der Artikel nach Produkt. Wenn alle Elemente 1s sind, ist das Ergebnis ihre Summe, andernfalls - 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

Schließlich reduziere ich die Ergebnisliste für jede Submatrix und finde das Maximum:

>./@,

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

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

@ FrownyFrog Danke! Ich wusste nicht über"$
Galen Ivanov

1
#ist kürzer als die Addition der Einsen.
FrownyFrog

@ FrownyFrog Hmm, das ist es wirklich. Cool, danke!
Galen Ivanov


2

Netzhaut , 143 Bytes

%`$
,;#
+%(`(\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

Probieren Sie es online aus! Link enthält Testfälle. Übernimmt die Eingabe als durch Kommas getrennte Zeichenfolgen. Erläuterung:

%`$
,;#

Fügen Sie a hinzu, ,um die letzte Zeichenfolge zu beenden, a ;, um die Zeichenfolgen von #s zu trennen, und a #als Zähler.

+%(`
)

Wiederholen Sie den Block, bis keine Unterteilungen mehr auftreten (da jede Zeichenfolge nur noch eine Ziffer lang ist).

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

Verdreifachen Sie die Zeile, setzen Sie den Zähler in der ersten Zeile auf 1 und erhöhen Sie ihn in der letzten Zeile.

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

Löschen Sie in der ersten Zeile die erste Ziffer jeder Zeichenfolge, während Sie in der zweiten Zeile alle Ziffern außer der ersten löschen.

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

In der dritten Zeile bitweise und die ersten beiden Ziffern zusammen.

1,
#

Zu diesem Zeitpunkt besteht jede Zeile aus zwei Werten, a) einem Zähler für die horizontale Breite und b) dem bitweisen Wert und den vielen Bits, die aus jeder Zeichenfolge entnommen wurden. Konvertieren Sie alle verbleibenden 1s in #s, damit sie mit dem Zähler verglichen werden können.

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

Suchen Sie alle Bitläufe (vertikal), die mit dem Zähler (horizontal) übereinstimmen, entsprechend den Quadraten von 1s in der ursprünglichen Eingabe, und quadrieren Sie die Länge.

N`

Numerisch sortieren.

-1G`

Nimm den größten.

^$
1

Sonderfall die Nullmatrix.


2

JavaScript, 92 Bytes

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 bis 20 Byte

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

Probieren Sie es online aus!


Rekursion! Nett!
Zacharý

@ Zacharý Danke. Anstelle einer Rekursion würde ich eigentlich etwas wie ks f \ x für ein monadisches f bevorzugen, das bis zur Konvergenz (x; fx; ffx; ...) ist, aber es gibt (noch) kein Äquivalent in APL. Das Ausführen mit ⍣≡ dauert zu viele Bytes.
ngn

2

Python 2 , 117 109 Bytes

Dank an @etene für den Hinweis auf eine Ineffizienz, die mich ein zusätzliches Byte gekostet hat.

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

Probieren Sie es online aus!

Übernimmt die Eingabe als durch Kommas getrennte Zeichenfolge. Dies ist ein Regex-basierter Ansatz, bei dem versucht wird, die Eingabezeichenfolge mit Mustern des Formulars 111.....111.....111für alle möglichen Größen des Quadrats abzugleichen.

In meinen Berechnungen ist dies mit einem anonymen Lambda nur ein bisschen kürzer als die definierte Funktion oder ein vollständiges Programm. Der or 1Teil am Ende ist nur notwendig, um den seltsamen Kantenfall zu behandeln, bei dem wir ausgeben müssen, 1wenn keine in der Eingabe sind.


2

Python 2 , 116 115 117 109 Bytes

Dank an @Kirill, der mir geholfen hat, noch mehr Golf zu spielen, und für seine clevere und frühe Lösung

Bearbeiten : 1 Byte mit einem Lambda gespielt, ich wusste nicht, dass das Zuweisen zu einer Variablen nicht zur Anzahl der Bytes zählt.

Edit 2 : Kirill wies darauf hin, dass meine Lösung in Fällen, in denen die Eingabe nur 1s enthält , nicht funktionierte. Ich musste sie reparieren und verlor zwei wertvolle Bytes ...

Edit 3 : Mehr Golf dank Kirill

Nimmt eine durch Kommas getrennte Zeichenfolge und gibt eine Ganzzahl zurück.

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

Probieren Sie es online aus!

Ich habe unabhängig eine Antwort gefunden, die Kirils nahe kommt, dh auf Regex basiert, außer dass ich re.search und a verwendedef .

Es verwendet einen regulären Ausdruck, der während jeder Schleife erstellt wird, um einem inkrementell größeren Quadrat zu entsprechen, und gibt das größte oder 1 zurück.


1
Schön, ich habe den ifAnsatz irgendwie automatisch als "sicher zu lang" verworfen , musste dann aber einen anderen Weg finden, um aus dem Match einen Bool-Wert zu machen. Leider verfehlt Ihre Lösung einen Punkt - Sie können nicht einfach haben range(l)- es wird den Fall verfehlen, wenn es überhaupt keine Nullen gibt. Nehmen Sie zum Beispiel den 2. Testfall und machen Sie alle 1s - es sollte 16 werden, nicht 9.
Kirill L.

Verdammt, ich habe darüber nachgedacht, mit allen Nullen zu testen, aber nicht mit allen Einsen (in der Herausforderung nie erwähnt ...). Ich werde versuchen, etwas zu erfinden.
etene

@ KirillL. du bist übrigens schnell! Ich habe immer noch an meiner Antwort gearbeitet, als Sie Ihre gepostet haben, und war ein bisschen verblüfft (und stolz!), Als ich sah, dass unsere Ansätze ähnlich waren ... das Niveau hier ist beeindruckend.
etene

1
Golf ein paar weitere Bytes durch Entfernen von Duplikaten find. Jetzt, da unsere Codes nicht mehr identisch sind, schlage ich vor, dass wir zumindest die offensichtlichen Fehler voneinander beheben - in Ihrem Fall stammt das zusätzliche Byte aus der Verwendung von Tupel ("1"*i,)anstelle von Liste.
Kirill L.

Danke, ja, das nutzlose Tupel ist meinerseits ziemlich dumm. Und das Extra findauch, das war klug von dir.
etene




1

Clojure, 193 Bytes

#(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, die Dinge eskalierten: o

Weniger 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))
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.