Prolog
どう書く

オフラインリアルタイムどう書く F09 の問題

問題はこちら->http://nabetani.sakura.ne.jp/hena/ordf09rotbox/
解き方自体は素直に、ルールに従って升目の変化を順次追うものですが、
ルールをそのまま書きますと12列必要になりますので、どうやって減らすかを考えました。

%swi-prolog

rot(X,L,R):-X<3,!,nth0(X,L,[A,B,C],L1),nth0(X,R,[B,C,A],L1).
rot(X,L,R):-X<6,!,tra(L,L0),X1 is X-3,nth0(X1,L0,[A,B,C],L1),nth0(X1,L2,[C,A,B],L1),tra(R,L2).
rot(X,L,R):-X<9,!,X1 is 8-X,nth0(X1,L,[A,B,C],L1),nth0(X1,R,[C,A,B],L1).
rot(X,L,R):-tra(L,L0),X1 is 11-X,nth0(X1,L0,[A,B,C],L1),nth0(X1,L2,[B,C,A],L1),tra(R,L2).

tra([[A,B,C],[D,E,F],[G,H,I]],[[A,D,G],[B,E,H],[C,F,I]]).

start:-str(S),split_string(S,"\n,\s","\s",L0),pre(L0).

solve([],[[1,2,3],[4,5,6],[7,8,9]]).
solve([H|T],L1):-solve(T,L),atom_codes(H,X),X1 is X-97,rot(X1,L,L1).

pre([]):-!.
pre([_,A,B|T]):-atom_chars(A,L0),reverse(L0,L),solve(L,R),disp(B,R),pre(T).

disp(B,[X,Y,Z]):-
     concat_atom(X,X1),concat_atom(Y,Y1),concat_atom(Z,Z1),
     concat_atom([X1,Y1],/,S0),concat_atom([S0,Z1],/,S),atomics_to_string([S],"",S1),
     (S1==B->write("yes ");write(" no ")),writeln(S).

%start.

str("0       aegj    286/435/971
1       a       231/456/789
2       e       183/426/759
3       g       123/456/978
4       j       126/459/783
5       bb      123/645/789
6       jjj     123/456/789
7       bd      723/164/589
8       ah      231/645/789
9       bj      124/569/783
10      db      723/561/489
11      dh      723/615/489
12      dl      123/456/789
13      hc      123/645/897
14      gf      128/453/976
15      hl      623/745/189
16      ja      261/459/783
17      ld      123/456/789
18      ki      315/486/729
19      lfa     294/753/186
20      kga     531/486/972
21      dbi     372/561/489
22      che     193/625/847
23      iea     823/416/759
24      gbl     523/964/178
25      egj     186/425/973
26      jcf     127/456/839
27      djh     726/915/483
28      hld     123/645/789
29      leeh    453/678/129
30      heja    851/629/743
31      cakh    251/649/837
32      bhjik   652/489/713
33      eabji   483/269/751
34      cdbch   823/156/974
35      ckgajc  536/492/817
36      ggchha  231/564/978
37      gfbkeg  128/534/697
38      agfbcbf         239/148/765
39      ekahijf         123/645/789
40      hajdjbe         789/432/615
41      elgililj        976/325/814
42      chffefif        317/629/845
43      ilbbihak        462/587/319
44      abcdefghijkl    123/456/789
45      hkijbglfaced    768/125/493
46      dfkbjiechlga    256/387/419
47      hgfkbidlajce    186/745/239
48      baciefjhgkdl    153/482/796").

2018.2.2追加
私は場合分けを3以下に減らせませんでしたが、
鍋谷氏の解答->https://qiita.com/Nabetani/items/241fe58c40083e8d44c1
の二番目が簡単な方法で場合分けを回避しているようで感心しましたので、Prologで書いてみました。
多分、行列と文字を回転させ、文字を左側に持っていくことで、同じ手続きを使えるのだと思います。

move(X,Y,L,R):-rot0(X,L,L1),nth0(Y,L1,[A,B,C],L2),nth0(Y,L3,[B,C,A],L2),rot0(X,R,L3).

rot0(0,L0,L0):-!.
rot0(N1,L0,L1):-N is N1-1,rot0(N,L0,L),rot(L,L1).
rot([[A,B,C],[D,E,F],[G,H,I]],[[G,D,A],[H,E,B],[I,F,C]]).

start:-str(S),split_string(S,"\n,\s","\s",L0),pre(L0).

solve([],[[1,2,3],[4,5,6],[7,8,9]]).
solve([H|T],L1):-
        solve(T,L),atom_codes(H,N),N1 is N-97,X is N1 div 3,Y is N1 mod 3,move(X,Y,L,L1).

pre([]):-!.
pre([_,A,B|T]):-atom_chars(A,L0),reverse(L0,L),solve(L,R),disp(B,R),pre(T).

disp(B,[X,Y,Z]):-
        concat_atom(X,X1),concat_atom(Y,Y1),concat_atom(Z,Z1),
        concat_atom([X1,Y1],/,S0),concat_atom([S0,Z1],/,S),atomics_to_string([S],"",S1),
        (S1==B->write("yes ");write(" no ")),writeln(S).