Bei einer zweidimensionalen Matrix von 0 und 1s. Finden Sie die Anzahl der Inseln für 1s und 0s, bei denen die Nachbarn nur horizontal und vertikal sind.
Given input:
1 1 1 0
1 1 1 0
output = 1 1
Number of 1s island = 1
xxx-
xxx-
Number of 0s island = 1
---x
---x
------------------------------
Given input:
0 0 0 0
1 1 1 1
0 0 0 0
1 1 1 1
output = 2 2
Number of 1s island = 2
----
xxxx <-- an island of 1s
----
xxxx <-- another island of 1s
Number of 0s island = 2
xxxx <-- an island
----
xxxx <-- another island
----
------------------------------
Given input:
1 0 0
0 0 0
0 0 1
output = 2 1
Number for 1's island = 2:
x-- <-- an island of 1s
---
--x <-- an island of 1s
Number of 0's island = 1:
-xx \
xxx > 1 big island of 0s
xx- /
------------------------------
Given input:
1 1 0
1 0 0
output = 1 1
Number for 1's island =1 and number of 0's island = 1
------------------------------
Given input:
1 1
1 1
output = 1 0
Number for 1's island =1 and number of 0's island = 0
code-golf
binary-matrix
KB Freude
quelle
quelle
[[1,0];[0,1]]
, um sicherzustellen, dass keine diagonale Konnektivität enthalten ist11111 / 10001 / 10101 / 10001 / 11111
→2 1
Antworten:
APL (Dyalog Unicode) ,
2928 Bytes SBCS-1 danke an @ Adám
Probieren Sie es online!
⊂,~∘⊂
die Matrix und ihre Negation{
}¨
für jeden von ihnen⍸⍵
Liste der Koordinatenpaare von 1s+/↑|∘.-⍨
Matrix von Manhattan Entfernungen2>
Nachbarmatrix∨.∧⍨⍣≡
Transitive Schließung≢∪
Anzahl eindeutiger Zeilenquelle
^:_
?J , 57 Bytes
Probieren Sie es online!
Dies ist eine von denen, bei denen die Idee unglaublich einfach ist (und ich denke, dass sie Spaß macht), aber die Ausführung hatte eine gewisse mechanische Länge, die die Einfachheit maskiert ... ZB ist das Verschieben der ursprünglichen Matrix in alle Richtungen mit 0-Füllung die ausführliche
((,-)#:i.3) |.!.0
.Es ist wahrscheinlich, dass diese mechanische Länge weiter verbessert werden kann, und ich werde es vielleicht morgen Abend versuchen, aber ich werde jetzt den Kern davon veröffentlichen.
Sagen wir, unser Input ist:
Wir beginnen mit einer Matrix eindeutiger Ganzzahlen gleicher Größe:
Dann finden wir für jede Zelle das Maximum aller Nachbarn und multiplizieren mit der Eingabemaske:
Wir wiederholen diesen Vorgang, bis sich die Matrix nicht mehr ändert:
Zählen Sie dann die Anzahl der eindeutigen Elemente ungleich Null. Das sagt uns die Anzahl der 1-Inseln.
Wir wenden den gleichen Prozess auf "1 minus der Eingabe" an, um die Anzahl der 0-Inseln zu erhalten.
quelle
JavaScript (ES7),
138 ... 107106 BytesGibt ein Array zurück
[ones, zeros]
.Probieren Sie es online!
Wie?
Um Bytes zu sparen, wird sowohl für die Root-Iteration als auch für die rekursiven Iterationen derselbe Code verwendet, der sich jedoch etwas anders verhält.
Während der ersten Iteration:
Während der rekursiven Iterationen:
c[v ^ 1]++
Kommentiert
quelle
MATL ,
1412 BytesProbieren Sie es online! Oder überprüfen Sie alle Testfälle .
Erläuterung
quelle
K (ngn / k) ,
60 55 51 5046 BytesProbieren Sie es online!
~:\
ein Paar der Eingabe und ihrer Negation (wörtlich: Iteration-Konvergenz negieren){
}'
für jeden,/x
mach das arg platt&
Wo sind die Einsen? - Liste der Indizes(0,#*x)\
divmod width (input), um zwei separate Listen für ys und xs zu erhaltenx-\:'x:
Achsabstände ∆x und ∆yx*x:
Quadrieren Sie sie+/
addiere ∆x² und ∆y²2>
Nachbarmatrix{|/'x*\:x}/
Transitive Schließung#?
Zählen Sie eindeutige Zeilenquelle
Wolfram Language (Mathematica) ,
6462 BytesProbieren Sie es online!
Dank attinat : wir können
1<0
stattFalse
zwei Bytes schreiben und sparen.Ungolf-Version:
Es gibt natürlich ein Mathematica- Objekt
MorphologicalComponents
, das ein Array (oder ein Bild) aufnimmt und dasselbe zurückgibt, wobei die Pixel jeder morphologisch verbundenen Insel durch den Inselindex ersetzt werden. AusMax
diesem Ergebnis ergibt sich die Anzahl der Inseln (die Hintergrundnullen bleiben bei Null, und der Inselindex beginnt bei 1). Wir müssen dies separat für das Array (Angabe der Anzahl der 1-Inseln) und eins minus des Arrays (Angabe der Anzahl der 0-Inseln) tun. Damit diagonale Nachbarn nicht als Nachbarn gelten, muss die OptionCornerNeighbors->False
angegeben werden.quelle
Rule
Python 3,
144127 BytesDiese Lösung nutzt
cv2
die unglaubliche Bildverarbeitungsleistung. Trotz der weniger beeindruckenden, superlangen und lesbaren Methodennamen von cv schlägt es die beiden anderen Python-Antworten!Golf gespielt:
Erweitert:
quelle
4
stattconnectivity=4
undn.uint8
stattdtype=n.uint8
möglich?cv2.connectedComponents
Methode finden, also war ich verwirrt und dachte, es könnte einen anderen Grund dafür gegeben haben, die Argumentnamen zu benötigen. Wie gesagt, ich kenne Python nicht so gut. Alles, was ich daraus gelernt habe, ist von hier an CCGC. ;) Es ist jedoch sinnvoll, die Variablennamen zu verwenden, um andere optionale Argumente zu überspringen.J ,
46 4443 Bytes-1 Byte dank @miles
Probieren Sie es online!
Tests und der
,&
-.
Wrapper von @ jonahs Antwort gestohlen,&
-.
für die Eingabe und deren Negation machen Sie:4$.$.
(y, x) Koordinaten der Einsen als n × 2 Matrix1#.[:|@-"1/~
manhattan entfernungen: abs (∆x) + abs (∆y)2>
Nachbarmatrix[:+./ .*~^:_:
Transitive Schließung#&~.&(
)
Anzahl eindeutiger Zeilenquelle
,&#&~.
um die[:
Retina 0,8,2 , 155 Bytes
Probieren Sie es online! Link enthält Testfall. Erläuterung:
Wenn es eine gibt
1
, ändern Sie sie in;
und fügen Sie einea
an das Ende der Eingabe an, damit sie nicht im Weg ist.Fülle alle angrenzenden
1
s mit;
s.Wiederholen, bis alle Inseln von
1
s zu;
s geworden sind.Wenn es eine gibt
0
, ändern Sie sie in:
und fügen Sie eineb
an das Ende der Eingabe an, damit sie nicht im Weg ist.Fülle alle angrenzenden
0
s mit:
s.Wiederholen, bis alle Inseln von
0
s zu:
s geworden sind.Zählen Sie getrennt die Anzahl der Inseln
1
s und0
s.quelle
Haskell ,
228227225224 BytesProbieren Sie es online!
Erläuterung:
Die Idee für diese Lösung lautet wie folgt: Initialisieren Sie die Matrix mit eindeutigen Werten in jeder Zelle, positiv für
1
und negativ für0
. Vergleichen Sie dann wiederholt jede Zelle mit ihren Nachbarn und ersetzen Sie die Zellennummer durch die Nummer des Nachbarn, wenn der Nachbar das gleiche Vorzeichen, aber eine Nummer mit einem größeren absoluten Wert hat. Sobald dies einen festen Punkt erreicht, zählen Sie die Anzahl der eindeutigen positiven Zahlen für die Anzahl der1
Regionen und die eindeutigen negativen Zahlen für die Anzahl der0
Regionen.In Code:
kann in die Vorverarbeitung (Zuweisen von Zahlen zu Zellen), die Iteration und die Nachverarbeitung (Zählen von Zellen) unterteilt werden
Vorverarbeitung
Der Vorverarbeitungsteil ist die Funktion
Wofür
z
als Abkürzung verwendet wirdzipWith
, um ein paar Bytes abzukürzen . Was wir hier tun, ist das zweidimensionale Array mit Integer-Indizes in den Zeilen und ungeraden Integer-Indizes in den Spalten zu komprimieren. Wir tun dies, da wir(i,j)
mithilfe der Formel eine eindeutige Ganzzahl aus einem Paar von Ganzzahlen erstellen können(2^i)*(2j+1)
. Wenn wir nur ungerade Ganzzahlen für generierenj
, können wir die Berechnung überspringen2*j+1
und drei Bytes einsparen.Mit der eindeutigen Zahl müssen wir nur noch ein Vorzeichen multiplizieren, das auf dem Wert in der Matrix basiert, die erhalten wird als
2*x-1
Iteration
Die Iteration erfolgt durch
Da die Eingabe in Form einer Liste von Listen erfolgt, führen wir den Nachbarvergleich für jede Zeile durch, transponieren die Matrix, führen den Vergleich für jede Zeile erneut durch (was aufgrund der Transponierung die vorherigen Spalten ist) und transponieren erneut. Der Code, der einen dieser Schritte ausführt, lautet
((.)>>=id$transpose.map l)
Wo
l
ist die Vergleichsfunktion (siehe unten) undtranspose.map l
führt die Hälfte der Vergleichs- und Umsetzungsschritte aus.(.)>>=id
führt sein Argument zweimal aus, wobei es\f -> f.f
in diesem Fall die punktfreie Form von und um ein Byte kürzer ist , da die Regeln für die Rangfolge der Operatoren gelten.l
ist in der obigen Zeile definiert alsl x=z(!)(z(!)x(0:x))$tail x++[0]
. Dieser Code führt einen Vergleichsoperator(!)
(siehe unten) für jede Zelle mit zuerst ihrem linken Nachbarn und dann mit ihrem rechten Nachbarn durch, indem die Listex
mit der rechtsverschobenen Liste0:x
und der linksverschobenen Liste nacheinander gezippt wirdtail x++[0]
. Wir verwenden Nullen, um die verschobenen Listen aufzufüllen, da sie in der vorverarbeiteten Matrix niemals auftreten können.a!b
ist in der Zeile darüber definiert alsa!b=div(max(a*a)(a*b))a
. Was wir hier machen wollen, ist die folgende Fallunterscheidung:sgn(a) = -sgn(b)
wir zwei gegenüberliegende Bereiche in der Matrix haben und diese nicht vereinheitlichen möchten,a
bleibt dies unverändertsgn(b) = 0
ja, haben wir den Eckfall, in demb
gepolstert wird und bleiben dahera
unverändertsgn(a) = sgn(b)
ja, möchten wir die beiden Bereiche vereinheitlichen und den Bereich mit dem größeren absoluten Wert verwenden (der Einfachheit halber).Beachten Sie, dass
sgn(a)
es niemals sein kann0
. Dies erreichen wir mit der angegebenen Formel. Wenn die Vorzeichen vona
und verschieden sindb
,a*b
kleiner oder gleich Null sind, während siea*a
immer größer als Null sind, wählen wir sie als Maximum und teilen sie mita
, um zurück zu kommena
. Andernfallsmax(a*a)(a*b)
istabs(a)*max(abs(a),(abs(b))
, und dies wird durch Division durcha
, bekommen wirsgn(a)*max(abs(a),abs(b))
, was die Zahl mit dem größeren Absolutwert ist.Um die Funktion zu iterieren,
((.)>>=id$transpose.map l)
bis sie einen festen Punkt erreicht, verwenden wir(until=<<((==)=<<))
, der aus dieser Stapelüberlaufantwort entnommen wird .Nachbearbeitung
Für die Nachbearbeitung verwenden wir das Teil
Das ist nur eine Ansammlung von Schritten.
(>>=id)
Zerquetscht die Liste der Listen in eine einzelne Liste, entferntnub
Doppelte, unterteilt(\x->length.($x).filter<$>[(>0),(<0)])
die Liste in zwei Listen, eine für positive und eine für negative Zahlen, und berechnet deren Länge.quelle
Java 10,
359355281280261246 Bytes-74 Bytes dank @NahuelFouilleul .
Probieren Sie es online aus.
Erläuterung:
quelle
|=2
: 0 -> 2 und 1 -> 3, wurde jedoch>0
geändert zu==1
|=2
! Und ich könnte immer noch<2
anstelle von==1
für -1 Byte verwenden, indem ich zuerst nach0
(und damit werden sie in geändert)2
und dann mit dem<2
nach1
(die in geändert werden3
)Python 3 , 167 Bytes
Probieren Sie es online!
Python 2 , 168 Bytes
Probieren Sie es online!
-2 Bytes dank Kevin Cruijssen
+2 Bytes Formatierungskorrektur
Erläuterung
Ein Zähler wird für 0s und 1s gehalten. Für jeden Eintrag in der Matrix werden die folgenden Aktionen ausgeführt:
Dies führt zu einem Fehlalarm für linksbündige Fälle wie
oder
In diesem Fall wird der Zähler um 1 verringert.
Rückgabewert ist
[#1, #0]
quelle
[#1, #0]
. Es ist ein bisschen sinnlos, dies durchzusetzen, aber es ist das, was es jetzt ist. Wie auch immer, können Sie Golf das{not c}
zu{c^1}
, und befestigen Sie das Problem , das ich durch Änderung erwähntn[c]+=
zun[c^1]+=
in einer ähnlichen Angelegenheit. Gute Antwort, +1 von mir. :)Perl 5 (
-0777p
), 110 BytesKann verbessert werden, verwendet einen regulären Ausdruck zum Ersetzen
1
durch3
und dann0
durch2
.TIO
quelle
Jelly ,
4436 BytesProbieren Sie es online!
Ein monadischer Link, der eine Liste mit Ganzzahllisten als Argument akzeptiert und eine Liste mit der Anzahl der Inseln 1 und 0 in dieser Reihenfolge zurückgibt.
Erläuterung
Schritt 1
Liste aller Matrixindizes mit den Indizes des Nachbarn rechts (außer rechts) und unten (außer unten) erstellen
Schritt 2
Teilen Sie diese Indizes auf, indem Sie angeben, ob die Eingabe 1 oder 0 enthält. Gibt eine Liste von Indizes mit Nachbarn für 1s und eine andere für 0s zurück.
Schritt 3
Zusammenführen von Listen mit gemeinsamen Mitgliedern und Ausgabezahlen
quelle
T-SQL 2008, 178 Byte
Die Eingabe ist eine Tabellenvariable.
Die in diesem Beispiel verwendeten Testdaten:
Probieren Sie es online aus
quelle
R ,
194172 BytesProbieren Sie es online!
Führen Sie eine Tiefensuche durch, beginnend in jeder Zelle der Matrix, die gleich 1 (oder Null) ist.
quelle