Toggle navigation
?
users online
Logout
Open hangout
Open chat for current file
/* Stored solution sets */ order_pile([a,b,c,d,e,f,g,h],[],[]) :- write('Job Well Done!'). order_pile([],[a,b,c,d,e,f,g,h],[]) :- write('Job Well Done!'). order_pile([],[],[a,b,c,d,e,f,g,h]) :- write('Job Well Done!'). /* Entry point for logic processing */ order_pile(Pile1,Pile2,Pile3):- reverselists(Pile1,Pile2,Pile3,NewPile1,NewPile2,NewPile3),move_all_blocks_off_pile1(NewPile1,NewPile2,NewPile3). /* Optional entry point with random input, use "start(X)." */ /* start/1 is the logical entry point. */ start(_):-writeln('OOps what a mess!'),randomstart(_,_,_,[a,b,c,d,e,f,g,h]). /* choose/2 and delete/3 are used to support the randomstart/4 predicate */ choose([], []). choose(List, Elt) :- length(List, Length), random(0, Length, Index), nth0(Index, List, Elt). delete(A, [A|B], B). delete(A, [B, C|D], [B|E]) :- delete(A, [C|D], E). randomstart(_,_,_,[]):-!. randomstart(Pile1,Pile2,Pile3,X):- choose(X,E),choose([1,2,3],PickList),moveChosen(Pile1,Pile2,Pile3,X,E,PickList). randomstart(Pile1,Pile2,Pile3,X):- choose(X,E),choose([1,2,3],PickList), ((PickList==1)-> (NewPile1=[E|Pile1],NewPile2=Pile2,NewPile3=Pile3); ((PickList==2)-> (NewPile2=[E|Pile2],NewPile1=Pile1,NewPile3=Pile3); (NewPile3=[E|Pile3],NewPile1=Pile1,NewPile2=Pile2) ) ), delete(E,X,NewX),length(NewX,L1), ((L1==0)->(order_pile(NewPile1,NewPile2,NewPile3)); randomstart(NewPile1,NewPile2,NewPile3,NewX)). moveChosen(Pile1,Pile2,Pile3,X,E,PickList):-moveChosen(Pile1,Pile2,Pile3,X,E,PickList,[],[],[]). moveChosen(Pile1,Pile2,Pile3,X,E,PickList,NewPile1,NewPile2,NewPile3):- (PickList==1-> (NewPile1=[E|Pile1],NewPile2=Pile2,NewPile3=Pile3); (PickList==2-> (NewPile2=[E|Pile2],NewPile1=Pile1,NewPile3=Pile3); (NewPile3=[E|Pile3],NewPile1=Pile1,NewPile2=Pile2) ) ), delete(E,X,NewX),length(NewX,L1), (L1==0->(!,print_blocks(NewPile1,NewPile2,NewPile3)); randomstart(NewPile1,NewPile2,NewPile3,NewX)). print_blocks(A,B,C) :- print_b(A), print_b(B), print_b(C),nl. print_b([]) :- writeln('|'). print_b([H|T]) :- write('|'),write(H),print_b(T). /* pop/3 and push/3 - Block piles will be treated as stack structures, pop/3 and push/3 will be used to remove or add a single block from a block pile. */ pop(E, [E|Es],Es). push(E, Es, [E|Es]). /* reverselists/6 - The ground is specified as being the left hand side pile list, reverselists/6 is used so that pop/3 and push/3 act on the correct side of the pile lists. */ reverselists(Pile1,Pile2,Pile3,NewPile1,NewPile2,NewPile3):-reverse(Pile1,NewPile1),reverse(Pile2,NewPile2),reverse(Pile3,NewPile3). /* reverse_print_blocks/3 - This predicate prints block lists which have been reversed correctly*/ reverse_print_blocks(RPile1,RPile2,RPile3):- reverse(RPile1,Pile1),reverse(RPile2,Pile2),reverse(RPile3,Pile3), print_blocks(Pile1,Pile2,Pile3). /* First step is (block ordering), clear a space to start building our ordered pile. We are arbitrarily choosing Pile 1. move_all_blocks_off_pile1/3 ensures no blocks are placed on top of 'a' unnecessarily creating extra work */ move_all_blocks_off_pile1([],_,_). move_all_blocks_off_pile1(RPile1,RPile2,RPile3):- reverse_print_blocks(RPile1,RPile2,RPile3), length(RPile1,L), ( L==1-> (movelastblockfromPile1(RPile1,RPile2,RPile3)); ( member(a,RPile3)-> (moveblock_fromThisPile_toThatPile(RPile1,RPile2,RPile3,1,2,RNewPile1,RNewPile2,RNewPile3)); (moveblock_fromThisPile_toThatPile(RPile1,RPile2,RPile3,1,3,RNewPile1,RNewPile2,RNewPile3)) ) ),move_all_blocks_off_pile1(RNewPile1,RNewPile2,RNewPile3). /* moveblock_fromThisPile_toThatPile/8, this predicate is designed to move a block from any one pile to any another, this shortens the code and eliminates overhead for debugging. Separate predicates to move blocks from piles 1 to 2, 1 to 3, 2 to 1, 2 to 3, 3 to 1 and 3 to 2 are required otherwise. */ moveblock_fromThisPile_toThatPile(Pile1,Pile2,Pile3,PileFrom,PileTo,NewPile1,NewPile2,NewPile3) :- (PileFrom==1->(pop(P1,Pile1,NewPile1));(PileFrom==2->(pop(P1,Pile2,NewPile2));pop(P1,Pile3,NewPile3))), (PileTo==1-> (push(P1,Pile1,NewPile1),(PileFrom==2->NewPile3=Pile3;NewPile2=Pile2)); (PileTo==2-> (push(P1,Pile2,NewPile2),(PileFrom==1->NewPile3=Pile3;NewPile1=Pile1)); (push(P1,Pile3,NewPile3),(PileFrom==1->NewPile2=Pile2;NewPile1=Pile1)))). /* movelastblockfromPile1/3 moves the last block off the floor unless it is the starting block 'a' */ movelastblockfromPile1(RPile1,RPile2,RPile3):- (RPile1==a) -> find_Next_Block_Needed(RPile1,RPile2,RPile3); (pop(P1,RPile1,RNewPile1),push(P1,RPile3,RNewPile3)), find_Next_Block_Needed(RNewPile1,RPile2,RNewPile3). /* find_Next_Block_Needed/3 determines which is the next block to be moved, and checks when the ordered pile is complete. */ find_Next_Block_Needed(RPile1, RPile2, RPile3) :- length(RPile1,LenofOrderedPile), (LenofOrderedPile==0->NextBlock=a;( RPile1=[H|_], (H==a->NextBlock=b; (H==b->NextBlock=c; (H==c->NextBlock=d; (H==d->NextBlock=e; (H==e->NextBlock=f; (H==f->NextBlock=g; (H==g->NextBlock=h;(reverselists(RPile1,RPile2,RPile3,Pile1,Pile2,Pile3),reverse_print_blocks(RPile1,RPile2,RPile3),order_pile(Pile1, Pile2, Pile3))))))))))),(LenofOrderedPile==8->!;find_pile_containing_next_block_needed(RPile1,RPile2,RPile3,NextBlock)). % find_pile_containing_next_block_needed/4 identifies which pile the next block needed is in. find_pile_containing_next_block_needed(RPile1,RPile2,RPile3,NextBlock):- (member(NextBlock,RPile2)-> (move_blocks_above_thisblock_on_Pile2_to_Pile3(RPile1,RPile2,RPile3,NextBlock)); (move_blocks_above_thisblock_on_Pile3_to_Pile2(RPile1,RPile2,RPile3,NextBlock))). % uncover the block needed from pile2, move it to pile1, and then find the next block needed. move_blocks_above_thisblock_on_Pile2_to_Pile3(RPile1,RPile2,RPile3,NextBlock):- reverse_print_blocks(RPile1,RPile2,RPile3), RPile2=[H|_],H==NextBlock->( moveblock_fromThisPile_toThatPile(RPile1,RPile2,RPile3,2,1,RNewPile1,RNewPile2,RNewPile3),find_Next_Block_Needed(RNewPile1,RNewPile2,RNewPile3));( moveblock_fromThisPile_toThatPile(RPile1,RPile2,RPile3,2,3,RNewPile1,RNewPile2,RNewPile3), move_blocks_above_thisblock_on_Pile2_to_Pile3(RNewPile1,RNewPile2,RNewPile3,NextBlock)). % uncover the block needed from pile3, move it to pile1, and then find the next block needed. move_blocks_above_thisblock_on_Pile3_to_Pile2(RPile1,RPile2,RPile3,NextBlock):- reverse_print_blocks(RPile1,RPile2,RPile3), RPile3=[H|_],H==NextBlock->( moveblock_fromThisPile_toThatPile(RPile1,RPile2,RPile3,3,1,RNewPile1,RNewPile2,RNewPile3),find_Next_Block_Needed(RNewPile1,RNewPile2,RNewPile3));( moveblock_fromThisPile_toThatPile(RPile1,RPile2,RPile3,3,2,RNewPile1,RNewPile2,RNewPile3), move_blocks_above_thisblock_on_Pile3_to_Pile2(RNewPile1,RNewPile2,RNewPile3,NextBlock)).