問題はこちら->http://nabetani.sakura.ne.jp/hena/orde29unes/
この問題は正規表現に詳しければさっと解けるのでしょうか。
私は正規表現はちょっとかじった程度ですので地道に解きました。
基本的な構想はすぐ浮かびましたが、Prologが問題の文字列を読み込んでくれないのに困りました。
「"」が含まれているためで、いろいろ試した後結局テキストエディタを使ってエスケープしました。
プログラムの基本は、find/5でリストの先頭から
①「"」や「'」が現れるまで、文字を、L2に入れます。
②「"」や「'」が現れたら、それをFに入れて、L2の要素をfind1/4で整形してL3に加えます。
③L2を空にして次にFの中の記号と同じ記号が現れるまで、文字をL2に入れます。
④Fの中の記号と同じ記号が現れたら、L2の要素をL3に加え、L2とFをリセットします。
⑤あとは①からの操作を繰り返します。
find1/4では、「/」の処理をしています。「//」->「/」,「/X」(X\=/)->「,X」です。
無効例の検出は、論理でなくテストケースの結果を見ながら潰していく結果になったのは残念でした。
そういうわけで、他のテストケースでも通る自信はありません。
%swi-Prolog version 7.4.2
%start.
%:-initialization(start). %ideone
find1([],'',L,R):-!,reverse(L,R).
find1([],'/',L,R):-
L1=[','|L],reverse(L1,R).
find1(['/'|T],F,R,FR):-
!,(F=='/'->(R1=['/'|R],F1='');(F1='/',R1=R)),find1(T,F1,R1,FR).
find1([C|T],F,R,FR):-
(F=='/'->(R2=[','|R],R1=[C|R2],F1='');(R1=[C|R],F1=F)),find1(T,F1,R1,FR).
find([],F,_,_,[]):-F\=''.
find([],_,L2,L3,R):-
L2==[]->R=L3;(find1(L2,'',[],L21),append(L3,L21,R)).
find([C|T],F,L2,L3,R):-
(C=='\'';C=='\"'),!,
(F==C->(F1='',append(L3,L2,L31),L21=[]);
(F==''->(F1=C,(L2==[]->(L21=L2,L31=L3);
(L21=[],find1(L2,'',[],L22),append(L3,L22,L31))));
(append(L2,[C],L21),F1=F,L31=L3))),find(T,F1,L21,L31,R).
find([C|T],F,L2,L3,R):-append(L2,[C],L21),find(T,F,L21,L3,R).
err(_,[],L,L).
err(_,[','],_,"-"):-!.
err(N,[',',X|_],_,R):-(N=:=0;X==','),!,R="-".
err(N,[_|T],L,R):-N1 is N+1,err(N1,T,L,R).
solve(L,R):-
find(L,'',[],[],R1),((R1=[];err(0,R1,R1,"-"))->
R="-";atomics_to_string(R1,R)).
start:-str(S),split_string(S,"\s\n","\s",L),pre(L),!.
pre([]):-!.
pre([_,B,C|T]):-
atom_chars(B,L),solve(L,R),disp(R,C),pre(T).
disp(R,C):-(R==C->Str="pass ";Str="fail "),write(Str),writeln(R).
str("0 foo/bar/baz foo,bar,baz
1 /foo/bar/baz'/ -
2 \" -
3 ' -
4 / -
5 \"\" -
6 '\' -
7 // /
8 \"/' -
9 '/\" -
10 Qux Qux
11 Foo/Bar Foo,Bar
12 foo\"bar -
13 foo'bar -
14 /foo/bar -
15 Foo//Bar Foo/Bar
16 foo/bar/ -
17 '\"'a'\"'/b \"a\",b
18 Foo\"/\"Bar Foo/Bar
19 foo\"'\"bar foo'bar
20 foo'\"'bar foo\"bar
21 foo///bar foo/,bar
22 \"Z\"\"tO\"uFM ZtOuFM
23 ''/foo/bar -
24 ////'/\"//' ///\"//
25 File/'I/O' File,I/O
26 Foo'//'Bar Foo//Bar
27 foo/''/bar -
28 foo/bar/\"\" -
29 '/////'//// ///////
30 'foo\"\"\"bar' foo\"\"\"bar
31 //'int'/V/c /int,V,c
32 foo/bar/baz foo,bar,baz
33 'H//Sg//zN'/ -
34 //'//\"/'/'\"' ///\"/,\"
35 foo//bar/baz foo/bar,baz
36 \"\"\"///\"/'/'// ///,//
37 58\"\"N\"//nIk'd -
38 foo\"/\"bar/baz foo/bar,baz
39 /////'\"/'/'\"/' //,\"/,\"/
40 f\"//J\"/O9o\"//' -
41 foo\"//\"bar/baz foo//bar,baz
42 foo/bar////baz foo,bar//baz
43 \"\"\"'/'//'''/\"// '/'//'''//
44 8//'/k///\"3da\"' 8//k///\"3da\"
45 foo/'/bar/'/baz foo,/bar/,baz
46 ///''\"//\"\"///\"\"\" /,/////
47 //wUJ8KNAk'n0//\" -
48 What/is/'\"real\"' What,is,\"real\"
49 \"//'/////\"''/'//' //'/////,//
50 \"8hKE\"3Fx/4//Hk/J 8hKE3Fx,4/Hk,J
51 '////''\"'//'/\"///' ////\"//\"///
52 Ro\"/j''/2u/f/r/\"3n Ro/j''/2u/f/r/3n
53 hoge\"//\"fuga//piyo hoge//fuga/piyo
54 'foo//bar'//baz/qux foo//bar/baz,qux
55 //'//\"'/\"///'\"/''// ///\",///',/
56 2/L'3'A8p/7//wP49Jb 2,L3A8p,7/wP49Jb
57 \"foo'\"/\"bar'\"/\"baz'\" foo',bar',baz'
58 '//'\"//'///'///''\"// ////'///'///''/
59 F6vX/q/Zu//5/'/H\"/'w F6vX,q,Zu/5,/H\"/w
60 \"foo'bar\"/'hoge\"fuga' foo'bar,hoge\"fuga
61 /\"/'//'/\"\"\"''//'/\"''' -
62 0gK\"koYUb\"\"S/p''z/\"Et 0gKkoYUbS/p''z/Et
63 Foo/Bar/\"Hoge'/'Fuga\" Foo,Bar,Hoge'/'Fuga").
最初はfind/5で文字列を出していたのですが、必要があって、それをリストに変換しようとしたら、
エラーになりました。「"」が問題のようでした。
原因は別にあったのかもしれません。