Сетчатка , 293 + 15 = 308 314 385 байт
;`\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>
Каждая строка идет в отдельном файле, поэтому я добавил 13 к числу байтов. Кроме того, вы можете поместить все это в один файл как есть и использовать -s
флаг. <empty>
Стенд на самом деле пустые файлы или строки.
К сожалению, мне нужно 187 байтов, чтобы преобразовать результат из унарного в десятичное. Я думаю, что я действительно должен реализовать это в ближайшее время .
объяснение
Retina - это язык на основе регулярных выражений (который я написал именно для того, чтобы иметь возможность делать подобные вещи с помощью регулярных выражений). Каждая пара файлов / строк определяет этап замены, причем первая строка является шаблоном, а вторая строка - строкой замены. `
Шаблонам может предшествовать строка конфигурации -delimited, которая может содержать обычные модификаторы регулярных выражений, а также некоторые специфичные для Retina параметры. Для вышеприведенной программы применимы соответствующие параметры ;
, которые подавляют вывод этого этапа и +
применяют замену в цикле, пока результат не перестанет изменяться.
Идея решения состоит в том, чтобы посчитать каждую строку отдельно, потому что мы всегда можем решить по символам, с которыми уже столкнулись, находимся ли мы внутри или вне полигона. Это также означает, что я могу объединить все это в одну линию, потому что начало и конец линии всегда находятся за пределами многоугольника. Также можно отметить, что _
и пробел полностью идентичны для алгоритма развертки строки, а также \
и /
. Поэтому в качестве первого шага я заменяю все символы новой строки и пробелы на _
все \
, /
чтобы потом немного упростить код.
Я отслеживаю текущее состояние внутри / снаружи с помощью символов i
и o
, в то же время, использую i
s для подсчета области. Для этого я начинаю с добавления o
к соединенной линии, чтобы отметить, что мы находимся за пределами многоугольника. Я также добавляю iio
в самый конец ввода, который я буду использовать для поиска новых персонажей.
Затем первая большая замена просто заменяет i
или o
сопровождается одним из /V_L
следующего набора символов, тем самым затопляя и подсчитывая всю вещь. Таблица замены выглядит следующим образом, где столбцы соответствуют последнему символу в этой строке, а строки - следующему символу (где S
для пробела и <>
для пустой строки). Я включил все символы ввода, чтобы показать эквивалентности, которые я уже использовал:
i o
/ io i
\ io i
L o ii
V i io
_ ii <>
S ii <>
Обратите внимание, что последний символ всегда указывает, находится ли после символа внутри или вне многоугольника, а число i
s соответствует области, которую необходимо добавить в многоугольник. В качестве примера здесь приведены результаты первых четырех итераций на последнем входном примере (это было сгенерировано старой версией, которая фактически заливала каждую строку отдельно, но принцип все тот же):
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
Наконец, я просто избавляюсь от всех o
s и разрывов строк, удаляя все, что соответствует [^i]
, а остаток - десятичное в унарное преобразование, которое довольно скучно.