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>
Cada linha entra em um arquivo separado, então adicionei 13 à contagem de bytes. Como alternativa, você pode colocar tudo isso em um único arquivo como está e usar o -s
sinalizador. O <empty>
suporte para arquivos ou linhas realmente vazios.
Infelizmente, preciso de 187 bytes apenas para converter o resultado de unário para decimal. Eu acho que realmente deveria implementar isso em breve .
Explicação
Retina é uma linguagem baseada em regex (que eu escrevi exatamente para poder fazer coisas assim com regex). Cada par de arquivos / linhas define um estágio de substituição, sendo a primeira linha o padrão e a segunda linha a sequência de substituição. Os padrões podem ser precedidos por uma `
cadeia de configuração delimitada, que pode conter os modificadores habituais de regex, além de algumas opções específicas da Retina. Para o programa acima, as opções relevantes são ;
: suprime a saída desse estágio e +
aplica a substituição em um loop até que o resultado pare de mudar.
A idéia da solução é contar cada linha separadamente, porque sempre podemos decidir pelos caracteres já encontrados se estamos dentro ou fora do polígono. Isso também significa que posso unir a coisa toda em uma única linha, porque o início e o fim de uma linha estão sempre fora do polígono. Também podemos observar que _
e espaço são completamente idênticos para um algoritmo de varredura de linha, assim como \
e /
. Então, como um primeiro passo eu substituir todas as novas linhas e espaços, _
e todos \
por /
simplificar algum código mais tarde.
Estou acompanhando o atual estado interno / externo com os personagens i
e o
, ao mesmo tempo, usando os i
s para registrar a área. Para fazer isso, começo acrescentando um o
à linha unida para marcar que estamos fora do polígono. Também estou adicionando um iio
no final da entrada, que usarei como uma pesquisa para gerar novos caracteres.
Então, o primeiro substituto grande simplesmente substitui um i
ou o
seguido por um /V_L
com o próximo conjunto de caracteres, inundando e contabilizando a coisa toda. A tabela de substituição é a seguinte, onde as colunas correspondem ao último caractere nessa linha e as linhas ao próximo caractere (onde S
é para espaço e <>
para uma sequência vazia). Incluí todos os caracteres da entrada para mostrar as equivalências das quais já usei:
i o
/ io i
\ io i
L o ii
V i io
_ ii <>
S ii <>
Observe que o caractere final sempre indica se, após o caractere, estamos dentro ou fora do polígono, enquanto o número de i
s corresponde à área que precisa ser adicionada ao polígono. Como exemplo, aqui estão os resultados das quatro primeiras iterações na entrada do último exemplo (isso foi gerado por uma versão antiga que realmente inundou cada linha separadamente, mas o princípio ainda é o mesmo):
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
Por fim, acabo de me livrar de todos os o
sebras de linha removendo tudo o que corresponde [^i]
, e o restante é a conversão de decimal para unário, o que é bastante chato.