ReRegex , 294 275 байт
Сохранено 19 байт, используя лучшие определения 'function'
Я бы сказал, что это очень хорошо для языка Regex.
Базовая библиотека допускает преобразование между унарным и десятичным (что необходимо, поскольку в спецификации вызова явно указывается десятичное число), но не поддерживает двоичный код; Поэтому мне пришлось написать это как часть скрипта, добавив в него 120 байтов.
#import base
b(\d*):(_*)\2_b/b1$1:$2b/b(\d*):(_+)\2b/b0$1:$2b/b(\d+):b/$1/b:b/0/B(_*):1/B$1$1_:/B(_*):0/B$1$1:/B(_*):B/$1/j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/j(\d*),\1\d{0,7}:,?(.*)/,$2,/,((_+)_+),(\2),/,$1,/,(_+),(\1_*),/,$2,/^,(_*),$/d<$1>/j,b:u<(?#input)>b:
Попробуйте онлайн!
По отдельным регулярным выражениям.
#import base
b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
^,(_*),$/d<$1>/
j,b:u<(?#input)>b:
меры
Во-первых, мы импортируем «базовую» библиотеку, которая дает два регулярных выражения. Тот, который превращается u<numbers>
в одинарный. И тот, который преобразуетd<unary_underlines>
обратно в десятичную. Это потому, что проблема требует ввода-вывода в base10.
Затем мы определяем несколько регулярных выражений, которые преобразуют унарные в двоичные.
b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/
Первый из них - b(\d*):(_*)\2_b/b1$1:$2b/
поиск, за которым b
, возможно, следуют несколько двоичных цифр, затем a :
, затем любое количество подчеркиваний, за которым следует точно такое же количество подчеркиваний плюс один и, наконец, еще один b
.
Затем мы заменяем b1
его на следующие двоичные цифры :
и только первую половину подчеркивания и, наконец, последнюю b
.
Таким образом, это проверяет, не является ли унарное число делимым на два, и если это так, добавляет 1 к двоичным цифрам, а затем делит его на минус один на два.
Второй b(\d*):(_+)\2b/b0$1:$2b/
почти идеальный, но не проверяет лишнее _
, что означает, что он совпадает только в том случае, если он делится на два, и в этом случае 0
вместо него добавляется символ .
Третий проверяет, нет ли у нас одинарных цифр, и, если это так, удаляет отступы, чтобы просто оставить двоичные цифры.
Последний проверяет, не было ли когда-либо предоставлено двоичных цифр, и в этом случае просто уходит 0
.
Следующая группа регулярных выражений, которую мы определили, должна преобразовать двоичный код обратно в унарный и немного более простой.
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
Первая из этой группы, так же B(_*):1/B$1$1_:/
, как и ее антитеза, обнаруживает a B
, затем следует любое количество унарных цифр :1
. В B
этом случае он не проверяет соответствие , так как ищет только одну цифру за раз. Если это соответствует, это удваивает ранее сопоставленное количество унарных цифр и добавляет один, а затем удаляет один.
Второй, B(_*):0/B$1$1:/
почти идеальный к первому, за исключением совпадений 0
а 1
, а не добавляет дополнительную унарную цифру.
Последний из них, B(_*):B/$1/
проверяет, нет ли больше двоичных цифр и разворачивает ли унарный символ. В отличие от своей противоположности, для этого не требуется особый случай.
Далее мы определяем j
регулярные выражения, которые действуют как функция расщепления.
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
Первое, j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
делает большую часть тяжелой работы. Он выполняет поиск j
, за которым могут следовать двоичные цифры, которые являются «инкрементами», затем запятая, за которой следует инкрементатор, затем ровно 8 двоичных цифр, за которыми следует остальная часть двоичного числа, а затем a :
. Первая из 8 цифр добавляется к инкременту, увеличивая его, затем все, кроме этих 8 цифр из двоичного входа, добавляется после :
следующего a ,
. Так что (если бы мы использовали 2 цифры вместо 8) j,1001:
стало бы j1:1001:,01
тогда j10:1001,01,11
. Кроме того, добавленные элементы массива заключаются в B
s, чтобы преобразовать их обратно в унарный.
Другой - j(\d*),\1\d{0,7}:,?(.*)/,$2,/
проверяет, осталось ли менее 8 двоичных цифр для проверки после инкремента, и, если это так, удаляет все, кроме массива, заключенного в ,
s. Например.,_,___,
Во время и после создания массива мы определяем регулярные выражения сравнения.
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
В первом случае ,((_+)_+),(\2),/,$1,/
проверяется запятая, за которой следует некоторое количество подчеркиваний, затем еще несколько, за которыми следует запятая, затем первое количество подчеркиваний, а не запятая. Затем он заменяет его на общее количество подчеркиваний в первом элементе, окруженном символом ,
s.
Последний, ,(_+),(\1_*),/,$2,/
проверяет запятую, за которой следует некоторое количество подчеркиваний, за которыми следует еще одна запятая, затем то же количество или более подчеркиваний и последняя запятая. Это вместо этого оставит правильный элемент.
Наконец, когда есть соответствующий элемент слева ^,(_*),$
, мы удаляем окружающие запятые и преобразуем обратно в десятичную форму с помощью d<>
. Тогда больше не может регулярных выражений, и выходные данные представлены.
Входные данные изначально помещаются в шаблон j,b:u<(?#input)>b:
, который сначала преобразует десятичный ввод в унарный, например, 5
-> j,b:_____b:
, затем получающийся унарный в двоичный, j,101:
затем разбивает двоичный файл (что не работает для примера), получает самый большой элемент, преобразует вернуться к десятичной дроби, и готово.