In dem Videospiel Minecraft geht es darum, verschiedene Arten von Blöcken in dem 3D- Ganzzahlgitter , aus dem die virtuelle Welt besteht, zu platzieren und zu entfernen . Jeder Gitterpunkt kann genau einen Block enthalten oder leer sein ( offiziell ein " Luft " -Block). In dieser Herausforderung werden wir uns nur mit einer vertikalen 2D-Ebene der 3D-Welt und einem Blocktyp befassen: Obsidian .
Wenn der Obsidian den Umriss eines leeren Rechtecks in einer vertikalen Ebene bildet, kann ein Unterportal erstellt werden. Das leere Rechteck kann eine beliebige Größe von 2 Einheiten breit und 3 Einheiten hoch bis 22 Einheiten breit und 22 Einheiten hoch haben. Die Ecken des Rechtecks müssen nicht in Obsidian umrandet sein, sondern nur die Seiten.
Angenommen, es X
handelt sich um Obsidian und .
Leere: (Die Zahlen dienen nur zu Identifikationszwecken und sind ebenfalls leer.)
...................................
..XXXX....XXXX....XXXXXXXXX........
..X..X...X....X..X.........X..XXXX.
..X.1X...X.2..X..X...3...X.X..X....
..X..X...X....XXXX.........X..X.6X.
..XXXX....XXXX...XXXXXXXXXXX..X..X.
.............X.4.X....X.5.X...XXXX.
.............X...X....X...X........
..............XXX......XXX.........
...................................
Dieses Raster enthält 3 gültige Portale:
- Portal 1 ist 2 mal 3 Einheiten groß, völlig leer und in Obsidian eingefasst. Deshalb ist es gültig.
- Portal 2 ist 4 mal 3, völlig leer und in Obsidian eingefasst. Deshalb ist es gültig.
- Portal 3 ist nicht ganz leer. Daher ist es ungültig.
- Portal 4 ist 3 mal 3, völlig leer und in Obsidian eingefasst. Deshalb ist es gültig.
- Portal 5 ist 3 mal 2 Einheiten, was zu klein ist. Daher ist es ungültig.
- In Portal 6 fehlt ein Teil der Grenze. Daher ist es ungültig.
Herausforderung
Schreiben Sie ein Programm oder eine Funktion, die diese Zeichenfolgendarstellungen von Gittern aus Obsidian und Leere aufnimmt und die Anzahl der gültigen Unterportale ausgibt oder zurückgibt.
- Die Eingabe kann von stdin oder einem Datei- oder Funktionsargument erfolgen.
Sie können davon ausgehen, dass die Eingabe immer gut strukturiert ist - dh ein perfekt rechteckiges Textgitter, das mindestens 1 Zeichen breit und hoch ist und nur
X
und enthält.
. Optional können Sie davon ausgehen, dass nach der letzten Zeile eine nachgestellte Zeile steht.Falls gewünscht, können Sie anstelle von und zwei beliebige druckbare ASCII- Zeichen verwenden .
X
.
Obsidian kann sich an den Rändern des Gitters befinden. Alles jenseits der Grenzen gilt als leer.
Beispiel Eingabe - die Ausgabe sollte sein 4
:
................................................................
...................................XXXXXXXXXXXXXXXXXXXXXXXXX....
..XXXX....XXXX....XXXXXXXXX........X.......................X....
..X..X...X....X..X.........X..XXXX.X.......................X....
..X..X...X....X..X.......X.X..X....X.......................X....
..X..X...X....XXXX.........X..X..X..XXXXXXXXXXXXXXXXXXXXXXXX....
..XXXX....XXXX...XXXXXXXXXXX..X..X.X......................X..XXX
.............X...X....X...X...XXXX.X......................X..X..
.............X...X....X...X........X......................X..X..
..............XXX......XXX........XXXXXXXXXXXXXXXXXXXXXXXX...X..
..................................XX.........................XXX
Wertung
Die Einsendung mit den wenigsten Bytes gewinnt.
Antworten:
Perl,
81-86Verwenden von mehr als einem regulären Ausdruck.
Die regexp für eine bestimmte Breite eines Portals ist viel einfacher als Standardversion :
X{$m}..{$n}(X\.{$m}X.{$n}){3,22}.X{$m}
wom
die Breite des Portals ist undn
isttotal width - 1 - m
. Der reguläre Ausdruck muss in eine Forward-Assertion mit(?=...)
der Breite Null gestellt werden, da sich die Übereinstimmungen überlappen können. Dann iteriere ich 21 mal über diese Regexp-Einstellung$n
und$.
."@-"
Wertet die Startposition der letzten Übereinstimmung (/.\n/
) aus, die zufällig die Gesamtbreite - 1$.
hat. Wird als die andere Variable verwendet, auf die sie1
bei Verwendung mit initialisiert wird-p0
.quelle
.
für leere Zellen verwenden (damit Sie es nicht maskieren müssen).Regex (.NET-Version),
182181145132126114104100989796 Byte2D ASCII Kunstmustererkennung? Klingt nach einem Job für Regex! (Tut es nicht.)
Ich weiß, dass dies zu endlosen Diskussionen darüber führen wird, ob Regex-Einreichungen gültige Programme sind oder nicht, aber ich bezweifle, dass dies APL oder CJam ohnehin schlagen wird, sodass ich keinen Schaden sehe. ( Aber sagen, dass sie tun unser hartnäckiger Test bestehen für „Was ist eine Programmiersprache?“ .)
Dies nimmt Eingaben als die zu vergleichende Zeichenfolge und das Ergebnis ist die Anzahl der gefundenen Übereinstimmungen. Es wird
_
anstelle von verwendet.
, weil ich letzterem entkommen müsste. Es erfordert auch einen nachgestellten Zeilenumbruch.Sie können es live bei RegexHero oder RegexStorm testen . Die Übereinstimmungen sind die obersten Obsidianreihen der Portale. Wenn Sie einen Testfall finden, bei dem dies fehlschlägt, lassen Sie es mich bitte wissen!
Was ist das für eine Zauberei?
Die folgende Erklärung setzt ein grundlegendes Verständnis der .NET- Bilanzkreise voraus . Das Wesentliche ist, dass Captures in .NET Regex Stapel sind - jedes neue Capture mit demselben Namen wird auf den Stapel verschoben, aber es gibt auch eine Syntax zum erneuten Abrufen von Captures aus diesen Stapeln sowie eine Syntax zum Abrufen von Captures aus einem Stapel und zum Übertragen von Captures zur gleichen Zeit auf einen anderen. Für ein vollständigeres Bild können Sie sich meine Antwort auf Stack Overflow ansehen, die alle Details abdecken sollte.
Die Grundidee ist, ein Muster wie das folgende zu finden:
Wo
n
ist zwischen 2 und 22 (inklusive). Das Knifflige ist, dass allen
s und allem
s gleich sind. Da die tatsächlichen Zeichen nicht identisch sind, können wir nicht einfach einen Rückverweis verwenden.Beachten Sie, dass der reguläre Ausdruck Zeilenumbrüche enthalten muss, die ich wie
\n
folgt schreiben werde .C # 185 Bytes
Hier ist eine vollständige C # -Funktion, nur um dies zu einem gültigen Eintrag zu machen. Es ist Zeit, dass ich einen Befehlszeilen- "Interpreter" für reguläre .NET-Ausdrücke schreibe ...
quelle
^
(oder ein beliebiges nicht verwendetes Zeichen) für verwenden(?!)
.Python, 219 Bytes
Besser als Java, aber Junge, das Fünffache der verschachtelten Schleifen tut weh. Das
for/in
könnte durch%s
Substitution leicht komprimierbar sein , aber es würde nicht viel sparen.Erweitert:
quelle
Java, 304 Bytes
Dies ist viel länger als ein regulärer Ausdruck. Es wird einfach über jedes mögliche Quadrat in der Eingabe iteriert. Wenn es sich um ein gültiges Portal handelt, wird ein Zähler um 1 erhöht. Anschließend wird der Zähler zurückgegeben. Dies kann wahrscheinlich viel weiter golfen werden. Anregungen sind willkommen.
Eingerückt:
Volles Programm:
quelle