正規表現のコンパイル(置換による)


21

あなたの仕事は、正規表現の各文字の置換を指定することにより、正規表現をコンパイルすることです...

正規表現

正規表現はこれらをサポートします

REGEX       = (LITERAL REGEX / GROUP REGEX / STAR REGEX / ALTERNATIVE)
LITERAL     = 1 / 0
GROUP       = '(' REGEX ')'
STAR        = (LITERAL / GROUP) '*'
ALTERNATIVE = '('REGEX ('|' REGEX)*')'

なぜ1または0だけなのですか?単純化のためです。したがって、正規表現には次の文字のみが含まれます。

*()|10

次のように解釈されます。

  1. * Kleene starです(左のグループまたはリテラルを0回以上繰り返します)。
  2. | 代替です(左側の正規表現または右側の正規表現のいずれかが一致する場合に一致します)。
  3. () グループ化しています。
  4. 1 文字1に一致します。
  5. 0 文字0に一致します。

コンパイル方法

6つのコードスニペットを指定します。1つは各正規表現文字を置き換えます。たとえば、あなたの答えが:

*FSAGFSDVADFS
|GSDGSAG
(GSDG
)GDSIH
1RGIHAIGH
0GIHEBN

次に、各正規表現をそれぞれのコードスニペットに置き換えます。

(0|11)*

に変換されます:

GSDGGIHEBNGSDGSAGRGIHAIGHRGIHAIGHGDSIHFSAGFSDVADFS

結果のプログラムは何をすることになっていますか?

あなたのプログラムは:

  1. 入力してください。
  2. 正規表現が入力全体に一致する場合、真偽値を出力します。
  3. そうでなければ、偽の値を出力します。

外部からの入力01は、未定義の動作と見なされます。入力は空にすることができます。

追加のルール

  1. 特定の正規表現文字に対して、結果のスニペットは常に同じでなければなりません。
  2. その後に追加される接頭辞または接尾辞はありません。
  3. 正規表現は空でないことが保証されています。

得点

最小の組み合わせスニペットが勝者です。したがって、この例のスコアは次のように計算されます。

FSAGFSDVADFS+ GSDGSAG+ GSDG+ GDSIH+ RGIHAIGH+GIHEBN

12 + 7 + 4 + 5 + 8 + 6 = 42


各スニペットの長さは少なくとも1文字ですか?
trichoplax

スニペットの長さはゼロにすることができます。編集はOKです。
アカンカ

言語の正規表現はこのチャレンジに有効ですか?:P
Loovjo

RegExにはRegExが組み込まれていると思います。私はこれを強制されます。Retinaと正規表現を除外したいのですが、Megoによると、許可されていません。それでも、カタツムリと友達については知りません。
アカンカ

@ChristianIrwan興味深いことに、これがRetinaで解決できるかどうかはまだわかりません。
マーティンエンダー

回答:


7

カタツムリ、48バイト

0 -> )0(\0!(l.)(~

1 -> )0(\1!(l.)(~

( -> )0({{(

) -> )0}}(~

| -> )0}|{(

* -> )0),(~

入力全体のみを照合するのではなく、部分一致を検索する必要がある場合、それは非常に簡単です。0になる\01になる\1*になる,、そして他の人は自分自身にマップします。代わりに、開始以外の場所でマッチが開始したり、終了以外の場所でマッチが終了したりするのを防ぐためのシェナンガンがたくさんあります。!(l.)一致の開始が入力の開始にない場合に失敗するアサーションです。~入力外のセルに一致するため、正規表現の末尾にあることが許可されているすべての文字に追加されます。後続の別の正規表現文字がある場合、数値限定子によってキャンセルされます00回一致させる必要があり、基本的にコメント化されます。できるようにするには*,)が途中にあるダミー範囲外のテストにもかかわらず、正常に動作するために、言語のブラケットのマッチングルールが頻繁に使用されています。ドキュメントから:

一致する括弧()または中括弧のペアは{}期待どおりに動作します(正規表現の括弧のように)が、ペアの半分を省略して、次の規則に従って推論させることもできます。)または}、同じタイプ((または{それぞれ)の最も近い閉じられていないグループ開始命令まで、または存在しない場合はパターンの先頭まで、すべてを左にグループ化します。これは、この範囲の中間にある反対のタイプの閉じられていない開始命令を閉じます。それ以外は一致しない({、パターンの終わりまでに閉じられます。

泥だらけですよね?


ため息、正規表現以外にも一致する言語があることを忘れています。いい仕事ですが、申し訳ありませんが、アップ投票はありません(ダウン投票もありません)
Akangka

@ChristianIrwanは、実際にはこのサイトで2dマッチング言語を開発するための全体的な挑戦があります。codegolf.stackexchange.com/questions/47311/...
SPARR

7

CJam、151バイト

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

行は文字に対応します01(|)*(この順序で)。オンラインでお試しください!

これは、組み込みの正規表現または他のタイプのパターンマッチングを使用しません。実際、CJamにはこれらの機能はありません。代わりに、それはそれはすべての可能な文字列を表し、構築する正規表現から始まることができ、ユーザの入力がそれらのいずれかである場合、最後にチェックするために、一致します。

テスト実行

以下は、STDINから正規表現を読み取り、各文字を適切なスニペットで置き換え、最終的に生成されたコードを評価して、コマンドライン引数で指定された入力と一致するかどうかを確認するプログラムを使用します。

$ cat regex.cjam
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+ea`,m*\"T

"N%ers~
$ cjam regex.cjam '' <<< '(|)'
1
$ cjam regex.cjam '0' <<< '(|)'
0
$ cjam regex.cjam '' <<< '0(|)'
0
$ cjam regex.cjam '0' <<< '0(|)'
1
$ cjam regex.cjam '' <<< '(0|11)*'
1
$ cjam regex.cjam '0' <<< '(0|11)*'
1
$ cjam regex.cjam '11' <<< '(0|11)*'
1
$ cjam regex.cjam '011011000' <<< '(0|11)*'
1
$ cjam regex.cjam '1010' <<< '(0|11)*'
0

残念ながら、これは特に高速ではありません。入力に9文字以上ある場合、または正規表現に1つ以上のKleeneスターがある場合、かなり速くチョークします。

合計156バイトの5バイトの追加コストで、潜在的な入力と一致する重複のない短い文字列を生成できます。これにより、コードの動作は変わりません。より効率的になります。

$ cat regex-fast.cjam 
l"01(|)*""

{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM0sa`T
{]Na/Saf+{:m*:sSf-~}%}:J{+:MU{]W=~Jea&,}|}:TM1sa`T
M{{+:M];eas!}:T}|U):UM'[T
MN`T
U(:UM'JT
M\"S+eas,)m*:sSf-L|\"T

"N%ers~
$ cjam regex-fast.cjam '0101001010' <<< '(01|10)*'
0
$ cjam regex-fast.cjam '011001101001' <<< '(01|10)*'
1
$ cjam regex-fast.cjam '0' <<< '(0*1)*'
0
$ time cjam regex-fast.cjam '101001' <<< '(0*1)*'
1

どうすればこれを短くしたり速くしたりできるか、まだ考えがあります。結果に満足したら説明を追加します。
デニス

`-escaping of the のパターンには余分な「 ` があるようです*。それにもかかわらず、正規表現がaのみで構成される最も単純な場合でも、このプログラムに入力を許可することはできませんでした0オンラインインタープリターのテストを参照)。私はそれを間違っていますか?
-matz

1
@matz私のコードはコマンドライン引数を使用しますが、そのインタープリターには実装されていません。代わりにこれを試してください。
デニス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.