Siatkówka oka , 293 + 15 = 308 314 385 bajtów
;`\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>
Każda linia przechodzi w osobny plik, więc dodałem 13 do liczby bajtów. Możesz też umieścić to wszystko w jednym pliku i użyć -s
flagi. <empty>
Oznaczają faktycznie pustych plików lub linii.
Niestety, potrzebuję 187 bajtów, aby przekonwertować wynik z jednostkowego na dziesiętny. Chyba powinienem to niedługo zaimplementować .
Wyjaśnienie
Retina jest językiem opartym na wyrażeniach regularnych (który napisałem właśnie po to, aby móc robić takie rzeczy przy pomocy wyrażeń regularnych). Każda para plików / linii definiuje etap zastępowania, przy czym pierwsza linia to wzorzec, a druga linia ciąg zastępujący. Wzorce mogą być poprzedzone `
-delimitowanym ciągiem konfiguracji, który może zawierać zwykłe modyfikatory wyrażeń regularnych, a także niektóre opcje specyficzne dla Retina. Dla powyższego programu odpowiednie opcje to ;
, które tłumią wyjście tego etapu i +
które stosują zamianę w pętli, aż wynik przestanie się zmieniać.
Ideą rozwiązania jest policzenie każdej linii osobno, ponieważ zawsze możemy zdecydować na podstawie znaków, które już napotkaliśmy, czy jesteśmy wewnątrz wielokąta, czy poza nim. Oznacza to również, że mogę połączyć całość w jedną linię, ponieważ przejście do początku i końca linii zawsze znajduje się poza wielokątem. Możemy również zauważyć, że _
i przestrzeń są całkowicie identyczne dla algorytmu przesuwania linii, a także \
i/
. Tak jak w pierwszym etapie zastąpić wszystkie znaki nowej linii i przestrzenie autorem _
a wszystko \
przez/
uproszczenie kodu później.
Śledzę bieżący stan wewnątrz / na zewnątrz z postaciami i
i o
jednocześnie używam i
s do zliczania obszaru. Aby to zrobić, zaczynam od dodania o
do połączonej linii, aby zaznaczyć, że jesteśmy poza wielokątem. Dodam też iio
na samym końcu danych wejściowych, których użyję jako odnośnik do generowania nowych znaków.
Następnie pierwsza duża zamiana po prostu zastępuje jedną i
lub o
następną jedną /V_L
z następną serią znaków, zalewając w ten sposób całość. Tabela wymiany wygląda następująco: kolumny odpowiadają ostatniemu znakowi w tej linii, a wiersze do następnego znaku (gdzie S
jest miejsce na spację i <>
pusty ciąg znaków). Uwzględniłem wszystkie znaki wejściowe, aby pokazać ekwiwalenty, których już użyłem:
i o
/ io i
\ io i
L o ii
V i io
_ ii <>
S ii <>
Zauważ, że końcowy znak zawsze wskazuje, czy po znaku jesteśmy wewnątrz czy poza wielokątem, podczas gdy liczba i
s odpowiada obszarowi, który należy dodać do wielokąta. Jako przykład podajemy wyniki pierwszych czterech iteracji z ostatniego przykładowego wejścia (zostało to wygenerowane przez starą wersję, która faktycznie zalała każdą linię osobno, ale zasada jest nadal taka sama):
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
Wreszcie, po prostu pozbyłem się wszystkich o
s i linia łamie się, usuwając wszystko, co pasuje [^i]
, a reszta to konwersja dziesiętna na unarską, która jest raczej nudna.