オフラインリアルタイムどう書くE27の参考問題をPrologで解いた。

```:orde27ligmir.prolog
% 処理系は GNU-Prolog です。
%
% $ gprolog --consult-file orde27ligmir.prolog --query-goal "main"

% 現在のマスの内容にそって方向転換する
turn(0'0, -6, -1).
turn(0'0,  1,  6).
turn(0'0,  6,  1).
turn(0'0, -1, -6).

turn(0'1, -6,  1).
turn(0'1,  1, -6).
turn(0'1,  6, -1).
turn(0'1, -1,  6).

turn(_, Dir, Dir).

% ひとマス進む
succ(0'/, _, _, _, _, []).
succ(0'x, _, _, _, _, []).
succ(_, Pos, Dir, Steps, _, []) :-
  member((Pos, Dir), Steps).
succ(Cell, Pos, Dir, Steps, Cells, [P | Path]) :-
  P is ((Pos div 6) - 1) * 5 + (Pos mod 6) + 0'a,
  turn(Cell, Dir, NextDir),
  NextPos is Pos + NextDir,
  nth(NextPos, Cells, NextCell),
  succ(NextCell, NextPos, NextDir, [(Pos, Dir) | Steps], Cells, Path).

% 問題を解く
solve(Input, Actual) :-
  append("/////", Input, I1),
  append(I1, "/////", Cells),
  nth(Pos, Cells, 0'Y),
  succ(0'Y, Pos, -6, [], Cells, Path),
  sort(Path, Actual).

% 以下、テストを実行し判定する部分

judge(_, E, E) :- format(".", []).
judge(I, E, A) :- format("~nfailed  input: ~s, expected: ~s, actual: ~s~n", [I, E, A]).

test(Input, Expected) :-
  solve(Input, Actual),
  judge(Input, Expected, Actual),
  !.

% 以下、ここのテストの実行

main :-
  test( "x...x/.1.0./..0../.Y.../0..x.", "ghilnqs" ),
  test( "..Y../...../...../...../.....", "c" ),
  test( "..x../..Y../...../...../.....", "h" ),
  test( "..Y.x/..1x0/11.../....0/1..1.", "c" ),
  test( "....1/....Y/...../...../.....", "ej" ),
  test( ".10../x.1../x.1x./.Y.1./...0.", "bcghlq" ),
  test( "0.x10/00..x/x0x.0/....0/...Y1", "deinsx" ),
  test( "1.01./01Y.1/..1.1/..10./0.0..", "abcfgh" ),
  test( "x..../x1x../0...0/....Y/.1..0", "klmnot" ),
  test( "...../..10./.1Y1./.01../.....", "hilmnqr" ),
  test( "...../..10./x.11./...../..Y..", "hilmnrw" ),
  test( "...../x.10x/...../x.Y1x/.....", "himnqrs" ),
  test( "..010/...Y1/..0../0.x../.....", "defghij" ),
  test( "1.0../...../.0x../Y.1x./..1..", "abcfhkp" ),
  test( "...../101../0.0../..Y../.....", "fgklmqrv" ),
  test( "1.0../00.../.x..0/0.Y1./...10", "abcfghmr" ),
  test( "x101./1..../.Y.x./..01./.00.1", "bcghlmrs" ),
  test( "x11../x.x../.0.01/..x../...Y.", "bcglmnsx" ),
  test( "..1.0/x0.x./0.0../x...Y/.10.1", "cdehjmnot" ),
  test( "..x.0/.0.../1..0x/1..1./Y.00.", "klmnpqrsu" ),
  test( "0.1.0/.0.xY/0...0/01..1/x00.x", "cdehjmrwx" ),
  test( "...0./.0.0./..101/...10/..01Y", "mnpqrstwxy" ),
  test( "10..0/.Y.0./0..1./....x/000..", "abfghiklmn" ),
  test( "10..1/...../.1010/110.1/x..Yx", "lmnopqrstx" ),
  test( "110../....1/x1..x/0.0.0/....Y", "bcghlmrsty" ),
  test( "x.101/1..../..001/010Yx/..1.1", "cdehijmnos" ),
  test( "x.111/x10../...0./00.1x/x.Y.1", "ghklmnqrsw" ),
  test( "11.../....0/11..1/1.1../.Y..1", "fghijlmnoqv" ),
  test( "...x1/.1.0./11.1./.01../Y..x.", "cghiklmnpqru" ),
  test( ".0.../110x./11..0/01.x./..Y.x", "ghklmnopqrtw" ),
  test( ".01.0/.110x/0...0/.01Y./x.1x.", "cdeghilmnqrs" ),
  test( ".1100/..1.0/1.11Y/0..1./.0..0", "hijklmnopqrs" ),
  test( "1..00/..11./.100./1..Y1/.....", "abcdfhikmnps" ),
  test( "1.0../.11x0/.00.x/Y.10./.10x0", "abcfghklmpqr" ),
  test( "11110/11.../.x.../.0111/0.Y0.", "deijnorstwxy" ),
  test( "...1./.1.0x/10..0/0Y.11/.0.x0", "ghiklmnopqrst" ),
  test( "...10/x111./0x.11/.0.../0.0Y.", "dehijmnorswxy" ),
  test( ".1x../.x1.0/0x.x./x11.1/x0Y.1", "hijmoqrstvwxy" ),
  test( "x.x../x110./1.1.0/0.Y.1/0.00x", "hiklmnopqrstx" ),
  test( "...0./11.00/10..x/..0.1/Y0.10", "ghiklmnpqsuvwx" ),
  test( ".110./....0/x..../.0001/11.Y.", "cdfghijmnorstx" ),
  test( "1.00./....1/.1.../0...0/0..1Y", "abcfhkmpqrstwy" ),
  test( ".1.01/..x../..100/..Y../...01", "bcdgilmnoqrstvxy" ),
  test( "1...0/Y..../...../...../0...1", "abcdefjkoptuvwxy" ),
  test( "x1..0/1..0./.Yx../0...1/.0.1.", "bcdefghijklnopqrstvwx" ),
  test( "1...0/.1.0./..1../..01./Y0..1", "abcdefghijklmnopqrstuvwxy" ),
  format("~n", []),
  halt.
```