Herausforderung
Bestimmen Sie anhand einer grafischen Eingabe einer Form, wie viele Löcher sich darin befinden.
Nicht duplizieren
Diese Frage wurde als mögliches Duplikat von Count Islands markiert . Ich glaube, diese Herausforderung unterscheidet sich von der Count Island-Herausforderung, weil Sie in dieser herausfinden müssen, wie Sie Blöcke entfernen, die die Grenze berühren.
Eingang
Die Eingabe erfolgt in Form einer 2D-Eingabe, entweder als mehrzeilige Zeichenfolge, als Array von Zeichenfolgen oder als Array von Zeichenfeldern. Dies repräsentiert die Form. Die Form ist garantiert nur einteilig und durch eine Kante verbunden. Bitte geben Sie an, wie die Eingabe erfolgen soll.
Ausgabe
Die Ausgabe ist eine einzelne Ganzzahl, die angibt, wie viele Löcher sich in der Form befinden. Ein abschließender Zeilenumbruch ist zulässig, jedoch kein anderes führendes oder abschließendes Leerzeichen. Mit anderen Worten, die Ausgabe muss mit dem regulären Ausdruck übereinstimmen ^\d+\n?$
.
Was ist ein Loch?
Dies sind Einzellöcher:
####
# #
# #
####
####
# #
# ##
###
#####
# # #
# #
#####
Dies sind keine Löcher:
########
########
# ####
# ####
# ######
#
########
###
#
###
##########
#
# ########
# # #
# # #### #
# # ## #
# ###### #
# #
##########
Ziemlich genau, wenn sich die Lücke mit der Außenkante verbindet, ist es kein Loch.
Testfälle
#####
# # # -> 2
#####
#####
#
# ### -> 1
# # #
#####
####
## # -> 1 (things are connected by edges)
# ##
####
###
### -> 0 (You must handle shapes with no holes, but input will always contain at least one filled space)
###
Sie können anstelle des '#' und anstelle der Leerzeichen ein beliebiges Zeichen verwenden.
Objektive Bewertungskriterien
Die Punktzahl wird als Anzahl der Bytes in Ihrem Programm angegeben.
Gewinnen
Der Gewinner ist die Einsendung mit der niedrigsten Punktzahl bis zum 4. April.
###|# #|##
als Testfall hinzufügen ? Das sollte sein0
, richtig?Antworten:
MATLAB / Octave, 18 Bytes
Probieren Sie es online!
Dies ist eine anonyme Funktion, die eine logische Matrix als Eingabe verwendet. Das Objekt wird aus den
true
Einträgen (mit der angegebenen Konnektivität) gebildet, der leere Raum sind diefalse
Einträge.bweuler
berechnet dann die Eulernummer des durch diese Matrix dargestellten binären Bildes, dh die Anzahl der Objekte abzüglich der Anzahl der Löcher.quelle
Mathematica,
5957 BytesDafür gibt es eine eingebaute. Nimmt Eingaben als 2D-Matrix aus
1
s (Wänden) und0
s (Löchern) auf. Der Einfachheit halber sind hier alle Testfälle in diesem Eingabeformat aufgeführt:Alternative Lösung, 59 Bytes
Dies war mein ursprünglicher Ansatz. Es basiert auch auf den komponentenbezogenen Einbauten, zählt jedoch die Löcher nicht direkt (stattdessen werden die Löcher selbst als Komponenten behandelt).
Verwendet dasselbe Eingabeformat wie oben, jedoch mit vertauschten Rollen von
0
s und1
s.Der Grund, warum ich dies in eine
Image
erste konvertieren muss, besteht darin, dass Mathematica andernfalls alle1
-Zellen als Teil einer einzelnen Komponente betrachtet (da die Matrix als Komponentenbeschriftungsmatrix behandelt wird). Wenn also eine1
-Zelle an den Rand grenzt, werden alle gelöscht. WennDeleteBorderComponents
stattdessen ein Image verwendet wird, wird eine implizite Konnektivitätsprüfung durchgeführt, um die Komponenten zu finden.Alternativ könnte ich
MorphologicalComponents
zuerst aufrufen , um die Eingabe in eine geeignete Beschriftungsmatrix umzuwandeln. Wenn ich dies jedoch zumDeleteBorderComponents
zweiten Mal tue, kann nicht mehr garantiert werden, dass die maximale Komponentenbeschriftung der Anzahl der Komponenten entspricht (da ich möglicherweise eine kleinere Komponente lösche).quelle
GenerateBuiltin
. Es generiert ein eingebautes für jede Herausforderung, die kein eingebautes hat. Ich fühle mich auch schlecht für den Posteingang von Martin Ender. Wenn Sie möchten, lassen Sie uns diese Diskussion hier fortsetzenPerl 5 , 154 Bytes
152 Byte Code + 2 Byte für
-p0
Flag.Probieren Sie es online!
Ich denke, der Code ist ziemlich selbsterklärend.
Wenn Sie einige Erklärungen benötigen, um diese zu verstehen, finden Sie hier einige Schritte der Transformationen, die das Programm an einer einfachen Eingabe (von hier aus ) durchführt, gefolgt von den folgenden Erklärungen:
Erstens
s/^ | $/A/gm;s/^.*\K | (?=.*$)/A/&&redo
werden die Leerzeichen in der Umrandung (1. Regex für links / rechts, 2. für unten / oben) durchA
(ich wähle dieses Zeichen ziemlich willkürlich) ersetzt.Dann erhalten wir die Breite der Form mit
/.*/;$@="@+"-1;
.Jetzt wollen wir jeden Raum ersetzen, die eine verbunden ist
A
mit einemA
(denn wenn ein Raum a verbunden istA
, bedeutet dies nicht Teil eines Lochs sein kann. Das wird getan durchfor$%(A,X){(s/$%(.?.?.{$@})? /$%$1$%/s||s/ (.?.?.{$@})?$%/$%$1$%/s)&&redo}
. (Sie werden feststellen , dass dies geschehen ist einmal für dasA
s und einmal für dasX
s - Erklärungen für dasX
sind unten) Hier gibt es zwei reguläre Ausdrücke:s/$%(.?.?.{$@})? /$%$1$%/s
befasst sich mit den Räumen, die rechts oder unten von a stehen,A
unds/ (.?.?.{$@})?$%/$%$1$%/s
mit den Räumen oben oder links von aA
.Zu diesem Zeitpunkt sind die einzigen Leerzeichen, die in der Zeichenfolge verbleiben, Teil von Löchern.
Während es noch Leerzeichen gibt, wiederholen wir:
- Um zu wissen, wie viele Löcher es gibt, ersetzen wir ein Leerzeichen durch ein
X
(s/ /X/
) und erhöhen den Zähler der Löcher ($\++
) und wiederholen das gesamte Programm (eigentlich wollen wir nur diefor
Schleife wiederholen) , aber es sind weniger Bytes, um das gesamte Programm zu wiederholen).- Dann ersetzt die
for
Schleife jeden Raum, der mit a verbunden ist,X
durch aX
, da sie Teil desselben Lochs sind.Am Ende wird
$\|=0
sichergestellt, dass, wenn keine Löcher vorhanden sind,0
anstelle eines leeren Strings ein gedruckt wird. Und$\
wird dank-p
Flagge implizit gedruckt .quelle
Python 2, 282 Bytes
+100 für diagonale Berührungen TT_TT (brauchen wir das wirklich?)
-119 dank @Rod Anleitung :)
Probieren Sie es online aus . Nimmt ein Array von Arrays aus Zeichen '#' und Leerzeichen als Eingabe.
Sucht nach dem ersten Leerzeichen und markiert es als nicht leer ('#'). Überprüfen Sie rekursiv die gesamte Umgebung, während Sie alle leeren Zellen füllen. Wenn sich eine leere Zelle des aktuellen "Lochs" auf dem Grenzzähler zu befinden scheint, ändert sich dies nicht. Andernfalls wird sie um 1 erhöht. Wiederholen Sie den Vorgang, bis keine Leerzeichen mehr vorhanden sind.
quelle
sum(A,[])
, um zu glättenNone
s, aber das ist irrelevant)x=T[0];y=T[1]
-> verwendenx,y=T
, müssen (wahrscheinlich) nicht in derg=1
3. Zeile deklarieren , und Sie können Strings verwenden<
oder>
vergleichen (es wird denord()
Wert jedes Zeichens annehmen ), wodurch Sie ersetzen könnenA[y][x]!='#'
durchA[y][x]<'#'
, da' '<'#'
.Python 2,
233225222 Bytesmath_junkie : -8 Bytes
Nimmt ein 2d-Array von Booleschen Werten / Ganzzahlen (0/1) als Eingabe
Probieren Sie es online!
Formatierte Version:
quelle
print sum(m(x,y)...
anstelle vona=
und speichernprint a
C # 7, 364 Bytes
Unzufrieden damit ... vielleicht kann es jemand anderes klären ... Wenn ich später die Energie habe, werde ich die erste Schleife invertieren und sehen, ob dies dazu beitragen kann, die Grenzwertprüfung zu vereinfachen.
Probieren Sie es online aus
Komplettes Programm, akzeptiert Eingaben zum Standardeingang, Ausgabe zum Standardausgang. Verwendet disjunkte Sets, um provisorische Löcher zu bestimmen, und wenn sie getötet werden, berühren Sie die Ränder (mit ein wenig Bedächtigkeit für die obere Kante).
Formatierter und kommentierter Code:
quelle
Func<List<string>, int>
um, um Flusen und Konsolenmaterial zu entfernen. Ich habe jedoch gesehen, dass Sie lokale Funktionen haben, sodass Sie diese möglicherweise nicht in einer Funk haben können. Konnte nur zu einer Methode kompilierenint h(string[] s) { }
.Schnecken , 48 Bytes
Ungolfed:
quelle
JavaScript (ES6), 192 Byte
Basierend auf meiner Antwort auf Fehlerhafte Schlösser erkennen . Zuerst wird die Zeichenfolge mit Leerzeichen aufgefüllt, um einen Bereich um die Form herum zu erstellen. Der RegExp sucht dann nach zwei benachbarten Feldern, von denen eines
@
ein Leerzeichen enthält, und ersetzt beide durch ein@
. Wenn dies nicht möglich ist, wird ein Leerzeichen mit einem@
gefüllt und dies als neues Loch gezählt. Schließlich wird einer abgezogen, um die Umgebung zu berücksichtigen.quelle