marginally more readable d8p2
This commit is contained in:
		
							
								
								
									
										51
									
								
								08/part2.pl
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								08/part2.pl
									
									
									
									
									
								
							| @@ -10,15 +10,16 @@ answer(Answer) :- | |||||||
|  |  | ||||||
| % unify2 combines 2 routes into one with its own stride-offsets-dests | % unify2 combines 2 routes into one with its own stride-offsets-dests | ||||||
| unify2(Route1, Route2, NewRoute) :- | unify2(Route1, Route2, NewRoute) :- | ||||||
|  |     writef('Combining %t + %t', [Route1, Route2]), | ||||||
|     once(findnsols(2, S, converge(Route1, Route2, S), SolutionPair)), |     once(findnsols(2, S, converge(Route1, Route2, S), SolutionPair)), | ||||||
|     SolutionPair = [NewA-LenA-NewZ, _-LenB-_], |     SolutionPair = [NewA-LenA-NewZ, _-LenB-_], | ||||||
|     NewStride is LenB - LenA, |     NewStride is LenB - LenA, | ||||||
|     NewRoute = NewA-(NewStride-LenA-[0-NewZ]). |     NewRoute = NewA-(NewStride-LenA-[0-NewZ]), | ||||||
|  |     writef(' --> %t\n', [NewRoute]). | ||||||
|  |  | ||||||
| % Len = Stride1*X1 + Offset1 + Dest1 = Stride2*X2 + Offset2 + Dest2 | % Len = Stride1*X1 + Offset1 + Dest1 = Stride2*X2 + Offset2 + Dest2 | ||||||
| % For performance, Route1's Stride should =< Route2's Stride | % For performance, Route1's Stride should =< Route2's Stride | ||||||
| converge(Route1, Route2, NewA-Len-NewZ) :- | converge(Route1, Route2, NewA-Len-NewZ) :- | ||||||
|     writef('Combining %t - %t\n', [Route1, Route2]), |  | ||||||
|     Route1 = A1-(Stride1-Offset1-Dests1), |     Route1 = A1-(Stride1-Offset1-Dests1), | ||||||
|     Route2 = A2-(Stride2-Offset2-Dests2), |     Route2 = A2-(Stride2-Offset2-Dests2), | ||||||
|     natnum(X2), |     natnum(X2), | ||||||
| @@ -28,42 +29,38 @@ converge(Route1, Route2, NewA-Len-NewZ) :- | |||||||
|     atom_concat(A1, A2, NewA), atom_concat(Z1, Z2, NewZ). |     atom_concat(A1, A2, NewA), atom_concat(Z1, Z2, NewZ). | ||||||
|  |  | ||||||
| routes(Starts, Routes) :- | routes(Starts, Routes) :- | ||||||
|     maplist([S, S-Route]>>(zloop(S, Route)), Starts, Routes). |     maplist([S, S-Route]>>(route_at(S, Route)), Starts, Routes). | ||||||
|  |  | ||||||
| % zloop builds a route (Stride-Offset-Internals) for a particular starting node. | % route_at(N, Node, Dests, AllDests) means going N steps will arrive at Node | ||||||
| zloop(Node, Route) :- zloop([], Node, 0, [], Route). | % passing through Dests. | ||||||
| zloop(_Direction, _Node, _Index, Zs, Stride-Offset-Dests) :- | route_at(Start, Route) :- route_at(0, Start, [], Route). | ||||||
|     Zs = [FirstZIndex-Z | _], reverse(Zs, [LastZIndex-Z | ReversedZs]), | route_at(N, FirstZ, [FirstZN-FirstZ | Zs], Stride-Offset-AllZs) :- | ||||||
|     DeltaZ is LastZIndex - FirstZIndex, DeltaZ =\= 0, |     Stride is N - FirstZN, direction_looped(Stride), | ||||||
|     direction_len(Len), |     Offset is FirstZN, | ||||||
|     divmod(DeltaZ, Len, _, 0), |     maplist({Offset}/[N-X, M-X]>>(M is N-Offset), [FirstZN-FirstZ | Zs], AllZs), | ||||||
|     Offset = FirstZIndex, Stride = DeltaZ, |  | ||||||
|     foldl([Idx-Z, NewIdx-Z, Off, Off]>>(NewIdx is Idx - Off), |  | ||||||
|           ReversedZs, ReversedDests, Offset, _), |  | ||||||
|     reverse(ReversedDests, Dests), |  | ||||||
|     !. |     !. | ||||||
| zloop(Directions, Node, Index, Zs, Route) :- | route_at(N, At, Dests, AllDests) :- | ||||||
|     (   is_end(Node) |     (   is_end(At) | ||||||
|     ->  append(Zs, [Index-Node], NewZs) |     ->  append(Dests, [N-At], NextDests) | ||||||
|     ;   NewZs = Zs |     ;   NextDests = Dests), | ||||||
|     ), |     Nplus1 is N + 1, step_at(N, Step), call(Step, At, NextNode), | ||||||
|     next_step(Directions, Move, Remain), |     route_at(Nplus1, NextNode, NextDests, AllDests). | ||||||
|     G =.. [Move, Node, To], G, |  | ||||||
|     NewIndex is Index + 1, |  | ||||||
|     zloop(Remain, To, NewIndex, NewZs, Route). |  | ||||||
|  |  | ||||||
| starts(Starts) :- findall(X, X to _, Nodes), include(is_start, Nodes, Starts). | starts(Starts) :- findall(X, X to _, Nodes), include(is_start, Nodes, Starts). | ||||||
|  |  | ||||||
| is_start(Node) :- atom_chars(Node, [_, _, a]). | is_start(Node) :- atom_chars(Node, [_, _, a]). | ||||||
| is_end(Node) :- atom_chars(Node, [_, _, z]). | is_end(Node) :- atom_chars(Node, [_, _, z]). | ||||||
|  |  | ||||||
| next_step([Move | Remain], Move, Remain). | % Step is the N-th step (counting starts from 0). | ||||||
| next_step([], Move, Remain) :- direction_list([Move | Remain]). | step_at(N, Step) :- | ||||||
|  |     direction_list(Dir), length(Dir, DirLen), Remainder is N mod DirLen, | ||||||
|  |     nth0(Remainder, Dir, Step). | ||||||
|  |  | ||||||
| direction_list(Dir) :- direction(Str), atom_chars(Str, Dir). | direction_list(Dir) :- direction(Str), atom_chars(Str, Dir). | ||||||
| direction_len(Len) :- direction_list(D), length(D, Len). | direction_looped(Len) :- direction_list(D), length(D, DLen), 0 is Len mod DLen. | ||||||
|  |  | ||||||
| % pick([[1,2,3], [4], [5,6]], X). X = [1,4,5]; X = [1,4,6]; X = [2,4,5]; ... | % pick one item from each sublist of ListOfLists & put them into Items in order. | ||||||
|  | % [[1,2,3], [4], [5,6]] -> [1,4,5]; [1,4,6]; [2,4,5]; [2,4,6]; [3,4,5]; [3,4,6]. | ||||||
| pick(ListOfLists, Items) :- | pick(ListOfLists, Items) :- | ||||||
|     maplist([SubList, X]>>(member(X, SubList)), ListOfLists, Items). |     maplist([SubList, X]>>(member(X, SubList)), ListOfLists, Items). | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user