ReRegex , 294 275 bajtów
Zaoszczędzono 19 bajtów dzięki lepszym definicjom „funkcji”
Powiedziałbym, że jest to całkiem dobre dla języka opartego tylko na Regex.
Podstawowa biblioteka lib pozwala na konwersję między jednostkową i dziesiętną (co jest potrzebne, ponieważ specyfikacja wyzwania wyraźnie określa dziesiętną), ale nie obsługuje wersji binarnej; Musiałem więc napisać to jako część skryptu, dodając do niego 120 bajtów.
#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:
Wypróbuj online!
Według poszczególnych regeksów.
#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:
Kroki
Po pierwsze, importujemy bibliotekę „podstawową”, która daje dwa wyrażenia regularne. Ten, który konwertujeu<numbers> w jedność. I taki, który konwertuje z d<unary_underlines>powrotem na dziesiętne. Wynika to z faktu, że wyzwanie wymaga IO w bazie 10.
Następnie definiujemy garść wyrażeń regularnych, które przekształcają jednoargumentowy na binarny.
b(\d*):(_*)\2_b/b1$1:$2b/
b(\d*):(_+)\2b/b0$1:$2b/
b(\d+):b/$1/
b:b/0/
Pierwsza z nich b(\d*):(_*)\2_b/b1$1:$2b/wyszukuje b, opcjonalnie następuje kilka cyfr binarnych, następnie a :, Następnie dowolna liczba podkreśleń, następnie dokładnie taka sama ilość podkreśleń plus jeden, a na końcu kolejnyb .
Następnie zamieniamy to na b1poprzedzone cyframi binarnymi z poprzedniej :, i tylko pierwszą połowę podkreślenia, a na koniec ostatniąb .
Sprawdza to, czy jednostka jednoargumentowa nie jest podzielna przez dwa, a jeśli tak, wstawia 1 do cyfr binarnych, a następnie dzieli ją minus jeden przez dwa.
Drugi b(\d*):(_+)\2b/b0$1:$2b/jest prawie identyczny, jednak nie sprawdza dodatkowych _, co oznacza, że pasuje tylko wtedy, gdy można go podzielić przez dwa, aw tym przypadku wstawia0 zamiast niego.
Trzeci sprawdza, czy brakuje nam jednoznacznych cyfr, a jeśli tak, to usuwa dopełnienie, aby po prostu zostawić cyfry binarne.
Ostatni sprawdza, czy nigdy nie podano żadnych cyfr binarnych, i w takim przypadku po prostu wychodzi 0 .
Następna grupa Regexów, którą definiujemy, polega na konwersji plików binarnych z powrotem na jednoargumentowe i są nieco prostsze.
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
Pierwsza z tej grupy, B(_*):1/B$1$1_:/podobnie jak jej antyteza, wykrywa a B, a następnie dowolną liczbę Unary cyfr :1. Nie sprawdza dopasowaniaB tym przypadku , ponieważ szuka tylko jednej cyfry na raz. Jeśli jest to dopasowane, podwaja poprzednio dopasowaną liczbę jednoargumentowych cyfr i dodaje jedną, a następnie usuwa jedną.
Drugi B(_*):0/B$1$1:/,, jest prawie identyczny z pierwszym, z wyjątkiem dopasowań 0raczej niż a1 i nie dodaje dodatkowej jednoznacznej cyfry.
Ostatni z nich B(_*):B/$1/ sprawdza, czy nie ma już cyfr binarnych, a jeśli tak, to rozpakowuje unary. W przeciwieństwie do jego antytezy, nie wymaga specjalnego przypadku 0.
Następnie definiujemy jwyrażenia regularne, które działają jak funkcja dzielenia.
j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
j(\d*),\1\d{0,7}:,?(.*)/,$2,/
Pierwszy j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/robi większość ciężkiego podnoszenia. Wyszukuje j, opcjonalnie po nich cyfry binarne, które są „inkrementatorem”, następnie przecinek, po którym następuje inkrementator, a następnie dokładnie 8 cyfr binarnych, po których następuje reszta liczby binarnej, a następnie a :. Pierwsza z 8 cyfr jest dołączana do inkrementatora, zwiększając go, a następnie wszystko oprócz tych 8 cyfr z wejścia binarnego jest dołączane po :następującym a ,. Tak więc (gdybyśmy używali 2 cyfr zamiast 8) j,1001:stałoby się j1:1001:,01wtedy j10:1001,01,11. Dodatkowo dołączone elementy tablicy są owinięte w Bs, aby przekonwertować je z powrotem na jednoargumentowe.
Drugi j(\d*),\1\d{0,7}:,?(.*)/,$2,/sprawdza, czy pozostało mniej niż 8 cyfr binarnych do sprawdzenia za inkrementatorem, a jeśli tak, usuwa wszystko inne niż tablicę owiniętą w ,s. Na przykład.,_,___,
Podczas i po utworzeniu tablicy definiujemy wyrażenia regularne porównania.
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
Pierwszy z nich ,((_+)_+),(\2),/,$1,/sprawdza przecinek, po którym następuje pewna liczba znaków podkreślenia, potem jeszcze kilka, następnie przecinek, a następnie pierwsza liczba znaków podkreślenia, niż przecinek. Następnie zastępuje go całkowitą liczbą znaków podkreślenia w pierwszym elemencie otoczonym przez ,s.
Ten ostatni ,(_+),(\1_*),/,$2,/sprawdza przecinek, po którym następuje pewna liczba znaków podkreślenia, po których następuje kolejny przecinek, następnie ta sama liczba lub więcej znaków podkreślenia i ostatni przecinek. To zamiast tego pozostawi właściwy element.
Na koniec, gdy pozostanie element pasujący w ten sposób ^,(_*),$, usuwamy otaczające go przecinki i przekształcamy z powrotem na dziesiętny przezd<> . Wtedy nie będzie już więcej wyrażeń regularnych, a wynik zostanie przedstawiony.
Dane wejściowe są początkowo umieszczane w szablonie j,b:u<(?#input)>b:, który najpierw przekształca dane dziesiętne na jednoargumentowe, np. 5-> j,b:_____b:, a następnie wynikowe jednostkowe na binarne, a j,101:następnie dzieli binarne (co nie działa w tym przykładzie), pobiera największy element, konwertuje powrót do miejsca po przecinku i gotowe.