どう書く過去問(第12回参考問題),CodeIQメビウスの亀

同じ出題者の「どう書く」と「CodeIQ]の似た問題シリーズ?です。

道なりの亀 ? 横へな 2013.7.6 参考問題
問題はこちら->http://nabetani.sakura.ne.jp/hena/ord12aloroturtle/
　かなり前に解いたものに入出力を付けました。
　普通に解くと地図を一周する間に方向と地図の座標の関係の変更の処理が必要となりますが、
　半円の部分を切って左右に分けて、半回転したものをもとの図形の下に接続すると、
 　 xy座標と升目の文字の間の対応を工夫すれば、向きの調節をせずにスムーズに移動でき、
　元の図形内の移動と変わりません。
　各升をXY座標で表し、リストに入れ、dirに従って次のXY座標を探します。
　座標がリストの中にあれば、ptoatom/2で文字に変換します。なければ"?"を付け加えて終了します。

```Prolog
%SWI-Prolog version 7.4.2
%start.
%:-initialization(start).    %ideone

turtle(S,R):-
     atom_chars(S,L0),make0(F),move(L0,[(1,1),(1,0)],F,['A'],Rout),
     reverse(Rout,L),atomics_to_string(L,R).

make0(RL):-
     numlist(1,11,L1),numlist(1,3,L2),numlist(4,12,L3),numlist(9,11,L4),numlist(13,15,L5),
     make1(L1,L2,R1),make1(L2,L3,R2),make1(L4,L3,R3),make1(L1,L5,R4),
     append(R1,R2,R5),append(R5,R3,R6),append(R6,R4,RL).
make1(L1,L2,R):-findall(P,(member(X,L1),member(Y,L2),P=(X,Y)),R).

move([],_,_,Rout,Rout):-!.
move([S|St],P,F,Rout,Res):-
     [(X,Y),(Dox,Doy)]=P,(member(S,['R','L'])->
     (dir([S,(Dox,Doy),(Dnx,Dny)]),move(St,[(X,Y),(Dnx,Dny)],F,Rout,Res));
     (Nx is X+Dox,Ny is Y+Doy,(member((Nx,Ny),F)->ptoatom((Nx,Ny),Atom),
     (Rout1=[Atom|Rout],char_type(S,xdigit(N)),N1 is N-1,
     (N1=0->move(St,[(Nx,Ny),(Dox,Doy)],F,Rout1,Res);
     (char_type(S1,xdigit(N1)),move([S1|St],[(Nx,Ny),(Dox,Doy)],F,Rout1,Res))));Res=[?|Rout]))). 
           
ptoatom((Nx,Ny),Atom):-
     Ny<4,!,N is (Ny-1)*11+Nx,(N<27->N1 is N+64; N1 is N+70),atom_codes(Atom,[N1]).
ptoatom((Nx,Ny),Atom):-
     Ny>12,!,N is (15-Ny)*11+(12-Nx),(N<27->N1 is N+64; N1 is N+70),atom_codes(Atom,[N1]).
ptoatom((Nx,Ny),Atom):-
     Nx<4,!,N is (Ny-4)*3+Nx,(N<20->N1 is N+103;N1 is N+28),atom_codes(Atom,[N1]).
ptoatom((Nx,Ny),Atom):-
     N is (12-Ny)*3+(12-Nx),(N<20->N1 is N+103;N1 is N+28),atom_codes(Atom,[N1]).

dir(['R',(-1,0),(0,-1)]).  %[direction,old dirc new direc]
dir(['R',(0,-1),(1,0)]).
dir(['R',(1,0),(0,1)]).
dir(['R',(0,1),(-1,0)]).   
dir(['L',F,T]):-dir(['R',T,F]).

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

pre([]).
pre([_,B,C|T]):-turtle(B,R),disp(R,C),pre(T).

disp(R,C):-
        (R==C->Str=" yes ";Str=" no  "),write(Str),writeln(R).

str("0       2RcL3LL22       ABCNYjmpsvy147edcbcdef
1       L3R4L5RR5R3L5   A?
2       2ReLLe  ABCNYjmpsvy147eTITe741yvspmjYNC
3       1ReRRe  ABMXilorux036fUJUf630xuroliXMB
4       ReRRe   ALWhknqtwz25gVKVg52zwtqnkhWLA
5       f       ABCDEFGHIJK?
6       Rf      ALWhknqtwz25gVK?
7       1Rf     ABMXilorux036fUJ?
8       2Rf     ABCNYjmpsvy147eTI?
9       aR1RaL1LaR1R2L1L2       ABCDEFGHIJKVUTSRQPONMLWXYZabcdefg567432
10      2R1R2L1L2R1R2L1L2R1R2L1L2R1R2L1L2       ABCNMLWXYjihklmponqrsvutwxy
11      2R4R2L4L2R4R2L4L2R4R2L4L2       ABCNYjmlknqtwxy147efgVK?
12      R1L2R4R2L4L2R4R2L4L2R4R2L4L2    ALMNYjmponqtwz0147eTUVK?
13      R2L2R4R2L4L2R4R2L4L2R4R2L4L2    ALWXYjmpsrqtwz2347eTIJK?
14      R3L2R4R2L4L2R4R2L4L2R4R2L4L2    ALWhijmpsvutwz2567eTI?
15      R5L2L5L1LaR1L4L5        ALWhknopmjYNCBMXilorux0325gVKJIHGF
16      1R2L4L2R4R2L4L2R4       ABMXYZabQFGHIJUfg?
17      2R2L4L2R4R2L4L2R4       ABCNYZabcRGHIJKVg?
18      3R2L4L2R4R2L4L2R4       ABCDOZabcdSHIJK?
19      4R2L4L2R4R2L4L2R4       ABCDEPabcdeTIJK?
20      5R2L4L2R4R2L4L2R4       ABCDEFQbcdefUJK?
21      LLL1RRR1LLL1RRR2R1      ALMXYZ?
22      R3RRR3  ALWhij?
23      1LLL4RRR1LR1RL1         ABMXilm?
24      R2L1R2L1R3R4    ALWXilmpsvut?
25      7R4f47LLLc6R9L  ABCDEFGHSd?
26      5RR868L8448LL4R6        ABCDEFEDCBA?
27      42Rd1RLLa7L5    ABCDEFGRc?
28      RRLL6RLR1L5d12LaLRRL529L        ABCDEFGRSTUV?
29      RLR7L6LL1LRRRcRL52R     ALWhknqtuv?
30      1RLR8RLR1R437L99636R    ABMXiloruxwtqnkhWLA?
31      LLL2L3La9Le5LRR         ALWXYZOD?
32      R1LcRR491       ALMNOPQRSTUV?
33      R8L1R1R512L8RLLReRf     ALWhknqtwx0z?
34      1RcL8f1L29a5    ABMXilorux036fedcbaZYXW?
35      R822LeL46LL39LL         ALWhknqtwz25gfedcbaZYXW?
36      9R3L5LRRLb5R3L7cLLLR4L  ABCDEFGHIJUf65?
37      7LLRRR2R3R69Lf76eR2L    ABCDEFGHSdcbaPE?
38      8RRRLL3Le       ABCDEFGHITe765?
39      8R5RLL6LbL4LL5bL        ABCDEFGHITe7410z?
40      6LR2R1LR5LRLRL484L63    ABCDEFGHITe741yxw?").
```
CodeIQ：メビウスの亀
問題はこちら
->http://nabetani.hatenablog.com/
->https://sw-logic.com/Portfolio/Programing/CodeIQ/3230.php

　ねじれているので複雑なようですが、表と裏の間に空気を注入して管にすれば、
　例えばその表面を這っている生物にとっては、、
　方向と座標の関係の変換がないので道なりの亀より簡単かもしれません。
　升目の数字（アルファベットも数字に変換）を原点からの直線距離を32や5で割った剰余と
　対応付ければ、接続部をスムーズに移行しどこまでも同じ法則で歩けます。(xytos/3)
　これを平面に移すため、輪にする前の帯の表と裏を数字の大小が同じ向きになるように
　縦に2枚つなぎ、更に裏と表の順を逆にしたものを横に接続します。
　　　　　　　裏(1,2,3..):表(1,2,3..)
　　　　　　　表(1,2,3..):裏(1,2,3..)
　メビウスの輪の座標をそれぞれ原点からの直線距離を64と10で割った剰余(0-63と0-9)
　とすれば、この矩形内を移動することが、メビウスの輪の中を動き回るのと同じです。
　飛び出した場合は対辺より入ります。(walk/6)
　裏への移動は特別な対応が必要です。（反対側の6-i列目(座標は9-i)+向きは調整）(warp/6)

　テストケースが少ないのですが、前問と似た問題ですし、例外もなさそうですので、
　大丈夫だと思います。

```Prolog
xytos(X,Y,S):-
     (X<5->(Y<32->X1 is X+97;X1 is X+65);(Y<32->X1 is X+60;X1 is X+92)),
     Y1 is (Y+1) mod 32,atom_number(S2,Y1),
     atom_codes(S1,[X1]),string_concat(S2,S1,S).
     
walk([DX,DY],N,X,Y,NX,NY):-NY is (Y+DY*N) mod 64,NX is (X+DX*N) mod 10.

dir('R',[X,Y],[NX,NY]):-NX is -Y,NY is X.
dir('L',[X,Y],[NX,NY]):-NX is Y,NY is -X.

warp(X,Y,D,NX,NY,ND):-
     NX is 9-X,NY=Y,((D==[0,1];D==[0,-1])->
     ND=D;(dir('R',D,D1),dir('R',D1,ND))).

move([],0,0,[0,1],[]).
move(['B'|T],X,Y,D,R):-
     !,move(T,X1,Y1,D1,R1),warp(X1,Y1,D1,X,Y,D),xytos(X,Y,S),R=[S|R1].
move([H|T],X,Y,D,R):-
     (H=='R';H=='L'),!,move(T,X,Y,D1,R),dir(H,D1,D).
move([H|T],X,Y,D,R):-
     move(T,X1,Y1,D,R1),atom_number(H,N),walk(D,N,X1,Y1,X,Y),xytos(X,Y,S),R=[S|R1].

solve(S,R):-atom_chars(S,L),reverse(L,L1),move(L1,_,_,_,R).

start:-case(S,A),solve(S,[R|_]),disp(R,A),fail.
start.

disp(R,C):-(R==C->Str=" yes ";Str=" no  "),write(Str),writeln(R).

case('L9R9B9',"19a").
case('RRRB1',"1D").
```