より良い「関数」定義を使用して19バイトを節約
これは正規表現のみの言語にはかなり良いと思います。
基本ライブラリは、単項と小数の間の変換を許可します(チャレンジ仕様で明示的に小数が指定されているため必要です)が、バイナリはサポートしていません。そのため、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:
手順
最初に、2つの正規表現を提供する「ベース」ライブラリをインポートします。u<numbers>
単項に変換するもの。そして変換するものd<unary_underlines>
、10進数に戻すもの。これは、チャレンジがbase10のIOを必要とするためです。
次に、単項をバイナリに変換する少数の正規表現を定義します。
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
、オプションでいくつかの2進数が続き、a :
、その後、任意の量の下線、正確に同じ量の下線+ 1、最後に別のb
。
次に、それをb1
、前からの2進数:
、、アンダースコアの前半部分、最後に最後のに置き換えb
ます。
したがって、これは、単項が2で割り切れないかどうかをチェックし、割り切れる場合は、1を2進数の前に追加し、マイナス1を2で除算します。
2つ目b(\d*):(_+)\2b/b0$1:$2b/
はほぼ同じですが、余分なをチェックしません_
。つまり、2で割り切れる場合にのみ一致し、この場合は0
代わりにaを追加します。
3番目のものは、単項数字がないかどうかをチェックし、そうでない場合は、パディングを取り除き、2進数字だけを残します。
最後の1つは、2進数字が提供されていないかどうかをチェックし、その場合はそのままになり0
ます。
定義する正規表現の次のグループは、バイナリを単項に戻すことであり、もう少し単純です。
B(_*):1/B$1$1_:/
B(_*):0/B$1$1:/
B(_*):B/$1/
このグループの最初のグループはB(_*):1/B$1$1_:/
、そのアンチテーゼによく似ており、aを検出しB
、その後に任意の量の単項数字が続き:1
ます。一致をチェックしませんB
一度に1桁のみを検索するため、この場合を。これが一致する場合、以前に一致した単項数字の量を2倍にして1を追加し、1を削除します。
2番目の、はB(_*):0/B$1$1:/
、a 0
ではなくaに一致することを除いて、最初とほぼ同一1
であり、追加の単項数字を追加しません。
これらの最後B(_*):B/$1/
ので、2進数がもうないかどうかを確認し、ない場合は単項をアンラップします。そのアンチテーゼとは異なり、これは特別な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,/
1つ目は、j(\d*),\1(\d)(\d{7})(\d*):/j$1$2,$1$2$3$4:,B:$1$4B/
ほとんどの重い作業を行います。を検索しj
、オプションで「インクリメント」である2進数が続き、次にコンマ、インクリメントが続き、正確に8桁のバイナリ、残りの2進数、aが続き:
ます。8桁の最初の数字はインクリメンターに追加され、インクリメントされます。その後、バイナリ入力からの8桁以外のすべてが、:
次のaの後に追加されます,
。したがって(8の代わりに2桁を使用している場合)j,1001:
はj1:1001:,01
thenになりj10:1001,01,11
ます。さらに、追加された配列要素はB
sにラップされて、単項に変換されます。
もう1つはj(\d*),\1\d{0,7}:,?(.*)/,$2,/
、インクリメンタの後にチェックするバイナリ桁が8桁未満かどうかをチェックし、残っている場合は、,
sでラップされた配列以外をすべて削除します。例えば。,_,___,
配列の作成中および作成後に、比較正規表現を定義します。
,((_+)_+),(\2),/,$1,/
,(_+),(\1_*),/,$2,/
これらの最初は,((_+)_+),(\2),/,$1,/
、コンマの後にいくつかのアンダースコアが続き、さらにいくつかが続き、コンマが続き、最初のアンダースコアがコンマよりも先にチェックされます。次に、,
sで囲まれた最初の要素のアンダースコアの合計量に置き換えます。
後者は,(_+),(\1_*),/,$2,/
、コンマの後にいくつかのアンダースコアが続き、さらに別のコンマが続き、同じ量以上のアンダースコア、最後のコンマがあるかどうかをチェックします。代わりに、正しい要素が残されます。
最後に、一致する要素が残っている場合^,(_*),$
、周囲のコンマを削除し、を介して10進数に戻しますd<>
。その後、これ以上正規表現を実行できなくなり、出力が表示されます。
入力は最初にテンプレートj,b:u<(?#input)>b:
に配置され、最初に10進数の入力を単項に変換します(例:5
-> j,b:_____b:
、次に結果の単項をバイナリj,101:
に変換) 10進数に戻り、完了です。