/****************************************************************/ Solutions in B-Prolog for the 2012 Prolog Programming Contest Team members: Christian Theil Have, Nuno Lopes, and Neng-Fa Zhou ****************************************************************/ %% 1. lace.pl % Example query ?-lace(5). lace(N) :- grid_size(N,S), new_array(Grid,[S,S]), R0 is S//2+1, C0 is R0, foreach(I in 1..N, draw(I,Grid,R0,C0)), foreach(R in 1..S, (foreach(C in 1..S, [G], (G @= Grid[C,R], var(G) -> write(' ') ; write('*'))),nl)). draw(I,Grid,R0,C0):- I mod 2=:=0,!, grid_size(I,S), foreach(Offset in 0..S//2, (Grid[R0-Offset,C0-S//2+Offset] @= '*', Grid[R0-Offset,C0+S//2-Offset] @= '*', Grid[R0+Offset,C0-S//2+Offset] @= '*', Grid[R0+Offset,C0+S//2-Offset] @= '*')). draw(I,Grid,R0,C0):- grid_size(I,S), foreach(C in C0-S//2..C0+S//2, (Grid[R0-S//2,C] @= '*', Grid[R0+S//2,C] @= '*')), foreach(R in R0-S//2..R0+S//2, (Grid[R,C0-S//2] @= '*', Grid[R,C0+S//2] @= '*')). :- table grid_size(+,-). grid_size(1,3) :- !. grid_size(N,S) :- 0 is N mod 2,!, N1 is N-1, grid_size(N1,S1), S is S1 + S1 // 2 * 2. grid_size(N,S) :- N1 is N - 1, grid_size(N1,S). %% 2. Rubik's Cube (cube.pl) % Example queries: % ?-cube([front], 4). % ?-cube([left,left], 2). % ?-cube([left,front], 15). % ?-cube([up,left,down,front], 45). % cube representation % cube(FRONT, BACK, UP, DOWN, LEFT, RIGHT) move(front, cube([F1,F2,F3,F4], B, [U1,U2,U3,U4], [D1,D2,D3,D4], [L1,L2,L3,L4], [R1,R2,R3,R4]), cube([F4,F1,F2,F3], B, [U1,U2,L2,L3], [R4,R1,D3,D4], [L1,D1,D2,L4], [U4,R2,R3,U3]) ). move(back, cube(F, [B1,B2,B3,B4], [U1,U2,U3,U4], [D1,D2,D3,D4], [L1,L2,L3,L4], [R1,R2,R3,R4]), cube(F, [B4,B1,B2,B3], [R2,R3,U3,U4], [D1,D2,L4,L1], [U2,L2,L3,U1], [R1,D3,D4,R4]) ). move(up, cube([F1,F2,F3,F4], [B1,B2,B3,B4], [U1,U2,U3,U4], D, [L1,L2,L3,L4], [R1,R2,R3,R4]), cube([R1,R2,F3,F4], [B1,B2,L1,L2], [U4,U1,U2,U3], D, [F1,F2,L3,L4], [B3,B4,R3,R4]) ). move(down, cube([F1,F2,F3,F4], [B1,B2,B3,B4], U, [D1,D2,D3,D4], [L1,L2,L3,L4], [R1,R2,R3,R4]), cube([F1,F2,L3,L4], [R3,R4,B3,B4], U, [D4,D1,D2,D3], [L1,L2,B1,B2], [R1,R2,F3,F4]) ). move(left, cube([F1,F2,F3,F4], [B1,B2,B3,B4], [U1,U2,U3,U4], [D1,D2,D3,D4], [L1,L2,L3,L4], R), cube([U1,F2,F3,U4], [D1,B2,B3,D4], [B1,U2,U3,B4], [F1,D2,D3,F4], [L4,L1,L2,L3], R) ). move(right, cube([F1,F2,F3,F4], [B1,B2,B3,B4], [U1,U2,U3,U4], [D1,D2,D3,D4], L, [R1,R2,R3,R4]), cube([F1,D2,D3,F4], [B1,U2,U3,B4], [U1,F2,F3,U4], [D1,B2,B3,D4], L, [R4,R1,R2,R3]) ). cube(L, M):- S = cube([1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16], [17,18,19,20], [21,22,23,24]), apply(S, S, L, 0, M). apply(S, F, L, I, M):- apply_moves(L, S, S1), I1 is I + 1, (S1 == F -> M = I1 ; apply(S1, F, L, I1, M) ). apply_moves([], SF, SF). apply_moves([M|Ms], S1, SF):- move(M, S1, S2), apply_moves(Ms, S2, SF). %% 3. invert.pl % Example queries: % ?- invert([],(nonvar(X)->X=a;X=b)). % ?- invert([],(var(X)->X=a;X=b)). invert(Cs,(A,B)):- invert(Cs,A), invert(Cs,B), invert(Cs,A). invert(Cs,(A,B)):-!, invert(Cs,B), invert(Cs,A), invert(Cs,B). invert(Cs,(A->B;C)):- invert(Cs,A), invert(Cs,B), invert(Cs,A),!, invert(Cs,B). invert(Cs,(A->B;C)):- invert(Cs,B), invert(Cs,A), invert(Cs,B),!, invert(Cs,B). invert(Cs,(A->B;C)):-!, invert(Cs,C). invert(Cs,(A;B)):- invert(Cs,A). invert(Cs,(A;B)):-!, invert(Cs,B). invert(Cs,(A==B)):-!, A==B. invert(Cs,var(A)):- !, var(A). invert(Cs,nonvar(A)):-!, nonvar(A). invert(Cs,A=B):-!, A=B. invert(Cs,G):- member(Cl,Cs), copy_term(Cl,clause(G,B)), list_to_and(B,AB), invert(Cs,AB). %% 4. omelet.pl % Example queries: % ?- omelet(1,1,D) % D = 1 % ?- omelet(2,1,D) % D=1 % ?- omelet(2,7,D) % D=4 % ?- omelet(3,7,D) % D=3 :-table omelet(+,+,min). omelet(_,0,0). omelet(_,1,1). omelet(1,H,H). omelet(N,H,D):- N>1, H>1, between(1,H,L), N1 is N-1, L1 is L-1, omelet(N1,L1,D1), L2 is H-L, omelet(N,L2,D2), D is max(D1,D2)+1. %% 5. cop.pl % Example query: % ?- cop([q(start,d,gotcha,start)],[q(start,d,gotcha,q2),q(q2,d,gotcha,start)]). cop(Plan1,Plan2):- p(Plan1,start,gotcha,t,Path1,_), p(Plan2,start,gotcha,t,Path2,_), Path1=Path2. :-table p(+,+,+,+,-,min). p(_,X,X,_,[],0):-!. p(Plan,X,Y,Pid,Path,Len):- (member(q(X,Id,Z,_),Plan);member(q(X,Id,_,Z),Plan)), p(Plan,Z,Y,Id,Path1,Len1), (Id==Pid->Path=Path1,Len=Len1; Path=[Id|Path1],Len is Len1+1).