Retina , 293 + 15 = 308 314 385 Bytes
;`\s
_
;`\\
/
;`.+
o$0iio
;+`(o(?=/.*(i)|L.*(ii)|V.*(io)|_)|i(?=/.*(io)|L.*(o)|_.*(ii)|V.*(i))).
$1$2$3$4$5$6$7$8
;`o
<empty>
;`ii$
#:0123456789
;+`^(?=i)(i*)\1{9}(?=#.*(0)|i#.*(1)|ii#.*(2)|iii#.*(3)|iiii#.*(4)|iiiii#.*(5)|iiiiii#.*(6)|iiiiiii#.*(7)|iiiiiiii#.*(8)|iiiiiiiii#.*(9))
$1#$2$3$4$5$6$7$8$9$10$11
:.*|\D
<empty>
Jede Zeile wird in einer eigenen Datei abgelegt, daher habe ich die Bytezahl um 13 erhöht. Alternativ können Sie alles in einer einzigen Datei speichern und das -s
Flag verwenden. Die <empty>
stehen für tatsächlich leere Dateien oder Zeilen.
Leider brauche ich nur 187 Bytes, um das Ergebnis von unär in dezimal umzuwandeln. Ich denke, ich sollte es wirklich tun das bald umsetzen .
Erläuterung
Retina ist eine auf Regex basierende Sprache (die ich genau geschrieben habe, um solche Dinge mit Regex machen zu können). Jedes Paar von Dateien / Zeilen definiert eine Ersetzungsstufe, wobei die erste Zeile das Muster und die zweite Zeile die Ersetzungszeichenfolge ist. `
Mustern kann eine durch -begrenzte Konfigurationszeichenfolge vorangestellt werden , die die üblichen Regex-Modifikatoren sowie einige Retina-spezifische Optionen enthalten kann. Für das obige Programm sind die relevanten Optionen ;
, die die Ausgabe dieser Stufe und unterdrücken+
die Ersetzung in einer Schleife anwenden, bis sich das Ergebnis nicht mehr ändert.
Die Idee der Lösung ist, jede Zeile einzeln zu zählen, da wir immer anhand der Zeichen entscheiden können, ob wir innerhalb oder außerhalb des Polygons sind. Dies bedeutet auch, dass ich das Ganze zu einer einzigen Linie zusammenfügen kann, da der Anfang und das Ende einer Linie immer außerhalb des Polygons liegen. Wir können auch feststellen, dass _
und der Raum für einen Linien-Sweep-Algorithmus ebenso wie \
und völlig identisch sind /
. Als ersten Schritt ersetze ich also alle Zeilenumbrüche und Leerzeichen durch _
und durch\
nach /
, um später den Code zu vereinfachen.
Ich verfolge den aktuellen Innen- / Außenstatus mit den Zeichen i
und verwende o
gleichzeitig das i
s, um den Bereich zu erfassen. Dazu beginne ich mit einem vorangestellteno
, der verbundenen Linie um zu markieren, dass wir außerhalb des Polygons sind. Außerdem füge ich iio
ganz am Ende der Eingabe ein hinzu, das ich zum Nachschlagen verwenden werde, um neue Zeichen zu generieren.
Dann ersetzt der erste große Ersatz einfach einen i
oder o
gefolgt von einem /V_L
der folgenden Zeichensätze, wodurch das Ganze überflutet und gezählt wird. Die Ersetzungstabelle sieht wie folgt aus: Die Spalten entsprechen dem letzten Zeichen in dieser Zeile und die Zeilen dem nächsten Zeichen (wobei S
Leerzeichen und <>
eine leere Zeichenfolge verwendet werden). Ich habe alle Zeichen der Eingabe eingefügt, um die Entsprechungen anzuzeigen, die ich bereits verwendet habe:
i o
/ io i
\ io i
L o ii
V i io
_ ii <>
S ii <>
Beachten Sie, dass das letzte Zeichen dann immer gibt an, ob nach dem Charakter , wir sind innerhalb oder außerhalb des Polygons, während die Zahl der i
s entspricht der Fläche , dass der Bedarf an dem Polygon hinzugefügt werden. Als Beispiel hier sind die Ergebnisse der ersten vier Iterationen der letzten Beispieleingabe (diese wurde von einer alten Version generiert, die tatsächlich jede Zeile separat geflutet hat, aber das Prinzip ist immer noch dasselbe):
o /V\
o / \___
o L _/
o/\/ /V
oL__ _/
o V
o /V\
o / \___
o L _/
oi\/ /V
oii__ _/
o V
o /V\
o/ \___
oL _/
oiio/ /V
oiiii_ _/
o V
o/V\
oi \___
oii _/
oiioi /V
oiiiiii _/
oV
oiV\
oiii \___
oiiii _/
oiioiii /V
oiiiiiiii_/
oio
Zuletzt o
entferne ich einfach alle s und die Zeilenumbrüche, indem ich alles entferne, was passt [^i]
, und der Rest ist die Umwandlung von Dezimal zu Unär, die ziemlich langweilig ist.