ReRegex , 294 275 байт
Збережено 19 байт, використовуючи кращі визначення функції
Я б сказав, що це досить добре для мови, що відповідає лише Regex.
Базова вкладка дозволяє перетворювати між Unary та Decimal (Що потрібно, оскільки специфікація виклику чітко зазначає десятковий), але не підтримує Binary; Тому мені довелося написати це як частину сценарію, додавши до нього 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>назад у десятковий. Це тому, що для виклику потрібен IO в базі10.
Тоді ми визначаємо жменю регулярних виразів, які перетворюють унарне в бінарне.
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бажанням - кілька двійкових цифр, потім - а :, потім будь-яка кількість підкреслень, а потім точно така ж кількість підкреслень плюс одна, і нарешті інша 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/перевіряє, чи немає більше двійкових цифр, і якщо так розгортається одинарний. На відміну від його антитези, для цього не потрібен спеціальний випадок 0.
Далі ми визначаємо 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 двійкових цифр, а потім решта двійкового числа, а потім :. Перша з 8 цифр додається до інкременту, збільшуючи його, тоді все, крім цих 8 цифр від двійкового вводу, додається після :наступного a ,. Тож (якби ми використовували 2 цифри замість 8), j,1001:це стане j1:1001:,01тоді j10:1001,01,11. Крім того, додані елементи масиву загортаються в Bs, щоб перетворити їх назад в одинакові.
Інший, 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:Потім розбиває двійковий (який не працює для прикладу), отримує найбільший елемент, перетворює повернутися до десяткової, і зроблено.