はじめに
こちらは、「オフラインリアルタイムどう書く」のBrinF**kによる実装例です。
- 問題の名前 : アンエスケープ
- 問題 : http://nabetani.sakura.ne.jp/hena/orde29unes/
- 実装リンク集 : https://qiita.com/Nabetani/items/f2db9b916c0a301b744f
コード
githubのレポジトリより。
solve.bf
->+>>+>>,+[
[
[->+>[->>>]<[>+++++++>+>]<<<<]
>>>--[---
<<-<<+<[-[-[-
** 3 **
<<[-
** e==1 **
>>>->>>[-]+>-[+[-]
** not slash **
<->
]
<[-
** slash **
<<<<+>>>>
]
<<<<<<]
>>>[-
** e==0 **
>>>>>+<[-[[-]
** other **
>-<<[-]<<<<+>>>[->+<]<++++[->+++++++++++<]>>>
]>[-
** slash **
<<<<<<+>>>>>>
]
<]>[-
** quote **
<<[-<<<<<+>>>>>]<[-]<++++[->+++++++++++<]<<++<<+>>>>>>>>
]
<<<<<]
]>[-
** 2 **
<<[->+>>>>-<<<<<]>[-<+>]
>>>>[+++++[-]>+<]+>[[-]
** not q **
<-<<<<++<<[-]>>>>>>>
]<[-
** q **
<[-]<<<<[-]>+>>>>
]
<<]
<]>[-
** 1 **
>>>>>+<[-[[-]
** other **
>-<<[-]<<<<+<<[-]>>>>>>>
]>[-
** slash **
<<<[-]<<<+++>>>>>>
]
<]>[-
** quote **
<<[-<<<<<+>>>>>]<[-]<<<++>>>>>>
]
<<<<]
<]>[-
** 0 **
>>[-]>[-]>[-]
<<<]
>[<<<[->+<]<[->+<]<[->+<]>>>>>[-<<<<<+>>>>>]>]
<,+>>>]
<[
** newline **
[-]<[-]>
]
<<]
<<<[-]<[->>+<<]>+>-[+[-]
** wrong **
<++++[-<+++++++++>]<.
>>]
<[-
** correct **
<-<+[-<+]->+[-.>+]
]
+[[-]<+]++++++++++.[-]
->+>>+>>,+]
実行例
次のように、問題のパラメータを1行ずつファイルに登録して食わせると、答えを1行ずつ出力するようになっています。
実行例
$ cat input.txt
foo/bar/baz
/foo/bar/baz'/
"
(略)
/"/'//'/"""''//'/"'''
0gK"koYUb""S/p''z/"Et
Foo/Bar/"Hoge'/'Fuga"
$ bff solve.bf < input.txt
foo,bar,baz
-
-
(略)
-
0gKkoYUbS/p''z/Et
Foo,Bar,Hoge'/'Fuga
概要
上のコードは、次のような有限状態機械を想定して作ったものです。
本当に細かく状態を細分化すると、Start,End,Abort以外に8種類の状態となるのですが、一部を変数とすることでN,Q,Sの3状態に絞り込みました。
コード中では、Abort,N,Q,Sにそれぞれ0~3の数字を割り当てて管理しています。
※Abortを管理する必要があるのは、一旦Abortになったら延々読み捨てる必要があるから
そして変数としたのはe,qで、それぞれ次のような意味を持ちます。
- e : 最近のスラッシュ以降、エレメントになる文字列が今の所空である ( 0: 空でない、1: 空 )
- q : クォートの開始文字 ( シングルかダブルか )
※実際の処理では、文字は変則divmod8の結果で識別しており、qにはその余り部分を保持します
そのため、コード中では、文字を処理するところの左に e,q,s ( s は状態 ) の3変数を常に持ちまわるようにします。
出力する文字 ( スラッシュのところはカンマに変える ) は、順次左端に送っていって、最後に一括で出力できるようにしています。
おわりに
正規表現で処理できるんだから、BrainF**kでも書けるよね! ということで、実装してみました。