今回も@Nabetaniさんのどう書くとCodeIQの似た問題の解答を投稿します。
まず「ブロックを回す」。
問題はこちら->http://nabetani.sakura.ne.jp/hena/ordf05rotblo/
bで回転すると一列左にずれ、aで回転すると一列左にずれたうえ一行下にずれます。
回転してから不可を除外しても良いのですが、a,bの特徴に従い先に除外します。
残りは回転後、すべてのリストの先頭を除き末尾に0を加え、
更に'a'のときは最後のリストを先頭に回します。(先頭に[0,0,0,0,0]を加え最後のリストを削除)
%swi-Prolog version 7.4.2
%start.
rotate(L,L1):-L=[H|T],maplist([A,B]>>(B=[A]),H,H1),foldl(apall,T,H1,L1). %90do kaiten
apall([],[],[]).
apall([H1|T1],[H2|T2],R):-apall(T1,T2,R1),H3=[H1|H2],R=[H3|R1].
atos(L,R):-maplist(atomics_to_string,L,L1),atomics_to_string(L1,"/",R).
shape([_|T],R):-append(T,[0],R),!. %list sentou no 0 wo nozokuki saigo ni 0 wo kuwaeru
solve("a",L,"-"):-reverse(L,[H|_]),member('1',H),!.
solve("a",L,"-"):-maplist(nth1(5),L,H),member('1',H),!.
solve("b",L,"-"):-reverse(L,[H|_]),member('1',H),!.
solve(P,L,R):-rotate(L,L1),solve1(P,L1,L2),(L2==[]->R="-";atos(L2,R)). %90 do kaiten
solve1("a",L,L6):-
maplist(shape,L,L4),reverse(L4,[L0|T2]),reverse(T2,L5),L6=[L0|L5],!. % saigo no list wo sentou ni mawasu
solve1("b",L,L4):-
maplist(shape,L,L4).
start:-str(S),split_string(S,"\s\n","\s",L),pre(L),!.
pre([]).
pre([_,B,C|D]):-split_string(B,"/,:","",[H|T]),maplist(atom_chars,T,L),
solve(H,L,R),disp(R,C),pre(D).
disp(R,C):-(R==C->Str=" pass";Str=" fail"),write(Str),write(" "),writeln(R).
str("0 a:00000/00110/00100/00100/00000 00000/00000/00000/11100/00100
1 b:00000/00000/00000/00011/00011 -
2 a:00000/00000/00000/00011/00011 -
3 b:00000/00000/00100/00000/00000 00000/00000/01000/00000/00000
4 a:00000/00000/00100/00000/00000 00000/00000/00000/01000/00000
5 b:00000/00110/00100/00100/00000 00000/00000/11100/00100/00000
6 b:00000/00000/00011/00011/00000 00000/00000/00000/11000/11000
7 a:00000/00000/00011/00011/00000 -
8 a:01110/00100/00000/00000/00000 00000/00000/00010/00110/00010
9 b:01110/00100/00000/00000/00000 00000/00010/00110/00010/00000
10 a:00000/11110/00000/00000/00000 00000/00100/00100/00100/00100
11 b:00000/11110/00000/00000/00000 00100/00100/00100/00100/00000
12 a:00000/00011/00110/00000/00000 -
13 b:00000/00011/00110/00000/00000 00000/00000/01000/01100/00100
14 a:00000/11100/11100/11100/00000 00000/11100/11100/11100/00000
15 b:00000/11100/11100/11100/00000 11100/11100/11100/00000/00000
16 a:01000/00000/00101/10010/10001 -
17 b:01000/00000/00101/10010/10001 -
18 b:10000/00000/10010/00000/00000 01010/00000/00000/01000/00000
19 a:10000/00000/10010/00000/00000 00000/01010/00000/00000/01000
20 a:00000/10101/11010/11010/01000 -
21 b:00000/10101/11010/11010/01000 -
22 b:01101/00011/01101/00000/00000 00000/01010/01010/00100/01110
23 a:01101/00011/01101/00000/00000 -
24 a:00001/00000/00000/00100/00010 -
25 b:00001/00000/00000/00100/00010 -
26 b:00100/00000/00100/01000/00000 00000/10000/01010/00000/00000
27 a:00100/00000/00100/01000/00000 00000/00000/10000/01010/00000
28 a:00010/00100/00000/10000/00000 00000/10000/00000/00100/00010
29 b:00010/00100/00000/10000/00000 10000/00000/00100/00010/00000
30 b:11010/00011/10101/00001/00001 -").
次にCodeIQの「正六角形ブロックの回転」です。
http://nabetani.hatenablog.com/
https://blog.goo.ne.jp/r-de-r/e/116074e5de592083784034b1f6eb6b24
テストケースは上記より拝借しました。
x軸を左から右へ横向きに、y軸を右上から左下にとり、左上の座標を(1,1)とします。
左側が平行四辺形になるようにy>3のときx座標をx+(y-3)とします。
aを中心に回転
ブロックのベクトルをa(x0,y0)を原点とするx軸に平行なベクトル(x-x0,0)と
y軸に平行なベクトル(0,y-y0)の合成とし、回転後のブロックのベクトルは、
回転後の二つのベクトル(0,x-x0),(-(y-y0),-(y-y0))の合成と考えます。(rota/4)
bを中心に回転
中央のx軸に平行な直線上の点を(x,3)とすると、ブロック(x,y)へのベクトルは(0,y-3)となり、
回転により(x,3)がy軸に平行な対角線上の(3,x-1)に移り、
ベクトル(0,y-3)が(-(y-3),-(y-3))に変わりますので、
新しいブロックの座標は(3-(y-3),(x-1)-(y-3))となります。(rotb/4)
out/2で六角形をはみ出したものを除外します。
%swi-Prolog version 7.4.2
%start.
%:-initialization(start). %ideone
rotab(C,X,Y,[XR,YR]):-C=="a"->rota(X,Y,XR,YR);rotb(X,Y,XR,YR).
rota(X,Y,RX,RY):-
X0=2,Y0=3,X1 is X0+Y0-Y,Y1 is Y0+(X-X0)+(Y0-Y),
(out(X1,Y1)->(RX=X1,RY=Y1);(RX=0,RY=0)),!.
rotb(X,Y,RX,RY):-X1 is 3-(Y-3),Y1 is X-1-(Y-3),
(out(X1,Y1)->(RX=X1,RY=Y1);(RX=0,RY=0)),!.
out(X,Y):-(0<Y,Y<4,0<X,X<3+Y);(3<Y,Y<6,Y-3<X,X<10-Y).
makes(0,_,"").
makes(N,L,R):-
N1 is N-1,makes(N1,L,R1),(N>3->M is 8-N;M is N+2),makes1(N,M,L,R2),
string_concat(R1,"/",R3),string_concat(R3,R2,R).
makes1(N,0,_,"").
makes1(N,M,L,R):-
M1 is M-1,makes1(N,M1,L,R1),(N>3->M2 is M+(N-3);M2=M),
(member([M2,N],L)->string_concat(R1,"1",R);string_concat(R1,"0",R)).
solve(C,L,R):-
findall(R1,(between(1,5,Y),nth1(Y,L,L1),length(L1,N),between(1,N,X),nth1(X,L1,'1'),
(Y>3->X1 is X+(Y-3);X1=X),rotab(C,X1,Y,R1)),R2),
(member([0,0],R2)->R="-";
(makes(5,R2,R3),string_length(R3,M),M1 is M-1,sub_string(R3,1,M1,_,R))),!.
start:-f68(S),split_string(S,"\s","\s",[C,D,A]),atomics_to_string(L,"/",D),
maplist(atom_chars,L,L1),solve(C,L1,R),disp(R,A),fail.
start.
disp(R,A):-(R==A->write("pass ");write(" fail ")),writeln(R),!.
f68("a 110/1010/11100/1100/000 000/1100/11100/1010/110").
f68("b 000/0011/01101/0001/010 101/0010/01010/0110/000").
f68("a 000/0100/01100/0000/000 000/0000/01000/1100/000").
f68("b 000/0011/00111/0011/010 100/0110/01110/0110/000").
f68("a 100/0100/10100/0100/000 000/0100/10000/1110/000").
f68("b 000/0100/00110/0000/011 100/1011/00100/0000/000").
f68("a 000/1100/01100/0000/000 000/0000/01100/1100/000").
f68("b 000/0011/00000/0010/010 100/0100/00010/0010/000").
f68("a 010/0111/11000/0000/101 -").
f68("b 110/0000/10000/0110/010 -").
f68("a 110/1101/01001/1010/000 -").
f68("b 011/1111/10000/0110/111 -").