Retina , 293 + 15 = 308 314 385 byte
;`\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>
Ogni riga va in un file separato, quindi ho aggiunto 13 al conteggio dei byte. In alternativa, puoi mettere tutto in un unico file così com'è e usare il -s
flag. Il <empty>
supporto per file o righe effettivamente vuoti.
Sfortunatamente, ho bisogno di 187 byte solo per convertire il risultato da unario a decimale. Immagino che dovrei davvero implementarlo presto .
Spiegazione
Retina è un linguaggio basato su regex (che ho scritto esattamente per essere in grado di fare cose come questa con regex). Ogni coppia di file / linee definisce una fase di sostituzione, con la prima riga come modello e la seconda riga la stringa di sostituzione. I pattern possono essere preceduti da una `
stringa di configurazione delimitata, che può contenere i soliti modificatori regex, nonché alcune opzioni specifiche di Retina. Per il programma di cui sopra, sono le opzioni pertinenti ;
, che sopprime l'output di quello stadio e +
, che applica la sostituzione in un ciclo fino a quando il risultato non smette di cambiare.
L'idea della soluzione è di contare ogni riga separatamente, perché possiamo sempre decidere dai personaggi già incontrati se siamo all'interno o all'esterno del poligono. Questo significa anche che posso unire l'intera cosa in un'unica riga, perché l'inizio e la fine di una riga sono sempre al di fuori del poligono. Possiamo anche notare che _
e lo spazio è completamente identico per un algoritmo di sweep di linea, così come \
e /
. Quindi, come primo passo ho sostituire tutte le nuove righe e gli spazi per _
e tutto \
per /
semplificare un certo codice in seguito.
Sto tenendo traccia dell'attuale stato interno / esterno con i personaggi i
e o
, usando anche la i
s per calcolare l'area. Per fare ciò, comincio anteponendo una o
alla linea unita per contrassegnare che siamo fuori dal poligono. Sto anche aggiungendo un iio
alla fine dell'input, che userò come ricerca per generare nuovi personaggi.
Quindi, il primo sostituto di grandi dimensioni sostituisce semplicemente uno i
o o
seguito da uno dei /V_L
con il successivo set di caratteri, inondando e calcolando così l'intera cosa. La tabella di sostituzione ha il seguente aspetto, in cui le colonne corrispondono all'ultimo carattere di quella riga e le righe al carattere successivo (dove si S
trova lo spazio e <>
una stringa vuota). Ho incluso tutti i caratteri dell'input per mostrare le equivalenze di cui ho già fatto uso:
i o
/ io i
\ io i
L o ii
V i io
_ ii <>
S ii <>
Nota che il carattere finale indica sempre se dopo il personaggio ci troviamo all'interno o all'esterno del poligono, mentre il numero di i
s corrisponde all'area che deve essere aggiunta al poligono. A titolo di esempio, ecco i risultati delle prime quattro iterazioni sull'ultimo input di esempio (questo è stato generato da una versione precedente che ha effettivamente inondato ciascuna riga separatamente, ma il principio è sempre lo stesso):
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
Infine, mi sbarazzo di tutte le o
s e le interruzioni di riga rimuovendo tutto ciò che corrisponde [^i]
, e il resto è la conversione da decimale a unaria che è piuttosto noiosa.