お題は こちら http://qiita.com/items/4364285801d1c9f370a1
Haskellでパタンマッチングで書くことができたので、Prologに翻訳してみました(Haskellで投稿したものからちょっとだけ手を加えてあります、番兵のところ)。
テストの実行には https://github.com/hiratara/offline-DOUKAKU-skeletons のtest.prolog を利用してください。
answer.prolog
sitdown3([0'+, 0'-, 0'-|CS], P, [0'+, P, 0'-|CS]).
sitdown3([0'-, 0'-, 0'-|CS], P, [0'-, P, 0'-|CS]).
sitdown3([C|CS], P, [C|RS] ) :- sitdown3(CS, P, RS).
sitdown2([0'+, 0'-|CS], P, [0'+, P|CS]).
sitdown2([0'-, 0'-|CS], P, [P, 0'-|CS]).
sitdown2([C|CS], P, [C|RS] ) :- sitdown2(CS, P, RS).
sitdown1([0'-|CS], P, [P|CS] ).
sitdown1([C|CS], P, [C|RS] ) :- sitdown1(CS, P, RS).
sitdown(CS, P, RS) :- sitdown3(CS, P, RS), !.
sitdown(CS, P, RS) :- sitdown2(CS, P, RS), !.
sitdown(CS, P, RS) :- sitdown1(CS, P, RS), !.
leave([P|CS], P, [0'-|CS]).
leave([C|CS], P, [C|RS] ) :- leave(CS, P, RS).
traffic([], CS, CS).
traffic([P|PS], CS, RS) :- between(0'A, 0'Z, P), sitdown(CS, P, NS), traffic(PS, NS, RS).
traffic([P|PS], CS, RS) :- between(0'a, 0'z, P), to_upper(P, Q), leave(CS, Q, NS), traffic(PS, NS, RS).
sentinel(XS, H, T, [H|YS]) :- sentinel(XS, T, YS).
sentinel([], T, [T]).
sentinel([X|XS], T, [X|YS]) :- sentinel(XS, T, YS).
split(D, [D|XS], [], XS).
split(D, [X|XS], [X|YS], ZS) :- D \= X, split(D, XS, YS, ZS).
get_source(Input, Count, Source) :- split(0':, Input, NS, Source), number_chars(Count, NS).
replicate(0, _, []).
replicate(N, C, [C|CS]) :- N1 is N - 1, replicate(N1, C, CS).
solve(Input, Actual) :-
get_source(Input, Count, Source),
replicate(Count, 0'-, CS0),
sentinel(CS0, 0'+, 0'-, CS1),
traffic(Source, CS1, CS2),
sentinel(Actual, 0'+, 0'-, CS2),
format("~s~n", [Actual]).