Rétine , 293 + 15 = 308 314 385 octets
;`\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>
Chaque ligne va dans un fichier séparé, j'ai donc ajouté 13 au nombre d'octets. Alternativement, vous pouvez mettre tout cela dans un seul fichier et utiliser l' -s
indicateur. Le <empty>
support pour les fichiers ou lignes réellement vides.
Malheureusement, j'ai besoin de 187 octets juste pour convertir le résultat de unaire en décimal. Je suppose que je devrais vraiment l' implémenter très bientôt .
Explication
Retina est un langage basé sur l'expression régulière (que j'ai écrit exactement pour pouvoir faire des choses comme ça avec l'expression régulière). Chaque paire de fichiers / lignes définit une étape de remplacement, la première ligne étant le modèle et la deuxième ligne la chaîne de remplacement. Les modèles peuvent être précédés d'une `
chaîne de configuration délimitée, qui peut contenir les modificateurs d'expression régulière habituels, ainsi que certaines options spécifiques à Retina. Pour le programme ci-dessus, les options pertinentes sont ;
, ce qui supprime la sortie de cette étape et +
, qui applique le remplacement dans une boucle jusqu'à ce que le résultat cesse de changer.
L'idée de la solution est de compter chaque ligne séparément, car nous pouvons toujours décider par les caractères déjà rencontrés si nous sommes à l'intérieur ou à l'extérieur du polygone. Cela signifie également que je peux joindre le tout en une seule ligne, car le début et la fin d'une ligne sont toujours en dehors du polygone. Nous pouvons également noter que _
et l'espace sont complètement identiques pour un algorithme de balayage de ligne, ainsi que \
et /
. Donc , dans un premier temps je remplace tous les espaces et les sauts de ligne par _
et tout \
en /
simplifier un code plus tard.
Je garde une trace de l'état intérieur / extérieur actuel avec les personnages i
et o
, tout en utilisant le i
s pour cadrer la zone. Pour ce faire, je commence par ajouter un o
à la ligne jointe pour marquer que nous sommes en dehors du polygone. J'ajoute également un iio
à la toute fin de l'entrée, que j'utiliserai comme recherche pour générer de nouveaux caractères.
Ensuite, le premier grand remplacement remplace simplement un i
ou o
suivi par un /V_L
avec le jeu de caractères suivant, inondant et comptant ainsi le tout. La table de remplacement se présente comme suit, où les colonnes correspondent au dernier caractère de cette ligne et les lignes au caractère suivant (où S
est pour l'espace et <>
pour une chaîne vide). J'ai inclus tous les caractères de l'entrée pour montrer les équivalences que j'ai déjà utilisées:
i o
/ io i
\ io i
L o ii
V i io
_ ii <>
S ii <>
Notez que le caractère final indique alors toujours si après le caractère nous sommes à l'intérieur ou à l'extérieur du polygone, tandis que le nombre de i
s correspond à la zone qui doit être ajoutée au polygone. À titre d'exemple, voici les résultats des quatre premières itérations sur le dernier exemple d'entrée (cela a été généré par une ancienne version qui inondait réellement chaque ligne séparément, mais le principe est toujours le même):
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
Enfin, je me débarrasse de tous les o
s et des sauts de ligne en supprimant tout ce qui correspond [^i]
, et le reste est la conversion décimale-unaire qui est plutôt ennuyeuse.