Compare commits
	
		
			2 Commits
		
	
	
		
			1a7326555a
			...
			10e184a0bf
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 10e184a0bf | |||
| a997d00c89 | 
							
								
								
									
										74
									
								
								08/part2.pl
									
									
									
									
									
								
							
							
						
						
									
										74
									
								
								08/part2.pl
									
									
									
									
									
								
							| @@ -1,5 +1,3 @@ | |||||||
| :- table direction_loop/1. |  | ||||||
|  |  | ||||||
| :- op(700, xfx, l). | :- op(700, xfx, l). | ||||||
| :- op(700, xfx, r). | :- op(700, xfx, r). | ||||||
| From l To :- From to To-_. | From l To :- From to To-_. | ||||||
| @@ -7,58 +5,43 @@ From r To :- From to _-To. | |||||||
|  |  | ||||||
| answer(Answer) :- | answer(Answer) :- | ||||||
|     starts(Starts), |     starts(Starts), | ||||||
|     routes(Starts, Routes), |     routes(Starts, [Route1 | RestOfRoutes]), | ||||||
|     collapse_routes(Routes, _-(_-Answer-_)). |     foldl(unify2, RestOfRoutes, Route1, Answer). | ||||||
|  |  | ||||||
| collapse_routes([X], X). | % unify2 combines 2 routes into one with its own stride-offsets-dests | ||||||
| collapse_routes(Routes, Collapsed) :- | unify2(Route1, Route2, NewRoute) :- | ||||||
|     writef('Collapsing: %t\n', [Routes]), |     once(findnsols(2, S, converge(Route1, Route2, S), SolutionPair)), | ||||||
|     sort(2, @=<, Routes, [Route1, Route2 | CdrRoutes]), |     SolutionPair = [NewA-LenA-NewZ, _-LenB-_], | ||||||
|     unify2(Route1, Route2, 0-0-0-0, [], NewRoute), |     NewStride is LenB - LenA, | ||||||
|     collapse_routes([NewRoute | CdrRoutes], Collapsed). |     NewRoute = NewA-(NewStride-LenA-[0-NewZ]). | ||||||
|  |  | ||||||
| unify2(Route1, Route2, N1-Term1-N2-Term2, Founds, NewRoute) :- | % Len = Stride1*X1 + Offset1 + Dest1 = Stride2*X2 + Offset2 + Dest2 | ||||||
|     Route1 = A1-(Stride1-Offset1-Loop1), | % For performance, Route1's Stride should =< Route2's Stride | ||||||
|     Route2 = A2-(Stride2-Offset2-Loop2), | converge(Route1, Route2, NewA-Len-NewZ) :- | ||||||
|     nth0(Term1, Loop1, C1-_), |     writef('Combining %t - %t\n', [Route1, Route2]), | ||||||
|     nth0(Term2, Loop2, C2-_), |     Route1 = A1-(Stride1-Offset1-Dests1), | ||||||
|     Z1 is Offset1 + Stride1*N1 + C1, |     Route2 = A2-(Stride2-Offset2-Dests2), | ||||||
|     Z2 is Offset2 + Stride2*N2 + C2, |     natnum(X2), | ||||||
|     next(Route1, N1-Term1, NextN1-NextTerm1), |     pick([Dests1, Dests2], [Dest1-Z1, Dest2-Z2]), | ||||||
|     (   Z1 =:= Z2 |     0 is (Stride2*X2 + Offset2 + Dest2 - Offset1 - Dest1) mod Stride1, | ||||||
|     ->  (   Founds = [OldZ] |     Len is Stride2*X2 + Offset2 + Dest2, | ||||||
|         ->  atom_concat(A1, A2, NewA), |     atom_concat(A1, A2, NewA), atom_concat(Z1, Z2, NewZ). | ||||||
|             NewStride is Z1 - OldZ, |  | ||||||
|             NewRoute = NewA-(NewStride-OldZ-[0-NewA]), |  | ||||||
|             ! |  | ||||||
|         ;   unify2(Route1, Route2, NextN1-NextTerm1-N2-Term2, [Z1], NewRoute) |  | ||||||
|         ) |  | ||||||
|     ;   Z1 < Z2 |  | ||||||
|     ->  unify2(Route1, Route2, NextN1-NextTerm1-N2-Term2, Founds, NewRoute) |  | ||||||
|     ;   next(Route2, N2-Term2, NextN2-NextTerm2), |  | ||||||
|         unify2(Route1, Route2, N1-Term1-NextN2-NextTerm2, Founds, NewRoute) |  | ||||||
|     ). |  | ||||||
|  |  | ||||||
| next(_-(_-_-Loop), NLoops-Term, NextNLoops-NextTerm) :- |  | ||||||
|     length(Loop, LoopLen), |  | ||||||
|     (   Term < LoopLen - 1 |  | ||||||
|     ->  NextNLoops is NLoops, NextTerm is Term + 1 |  | ||||||
|     ;   NextNLoops is NLoops + 1, NextTerm is 0). |  | ||||||
|  |  | ||||||
| routes(Starts, Routes) :- | routes(Starts, Routes) :- | ||||||
|     maplist([S, S-Route]>>(zloop([], S, 0, [], Route)), Starts, Routes). |     maplist([S, S-Route]>>(zloop(S, Route)), Starts, Routes). | ||||||
|  |  | ||||||
| zloop(_, _, _, Zs, Stride-Offset-Loop) :- | % zloop builds a route (Stride-Offset-Internals) for a particular starting node. | ||||||
|  | zloop(Node, Route) :- zloop([], Node, 0, [], Route). | ||||||
|  | zloop(_Direction, _Node, _Index, Zs, Stride-Offset-Dests) :- | ||||||
|     Zs = [FirstZIndex-Z | _], reverse(Zs, [LastZIndex-Z | ReversedZs]), |     Zs = [FirstZIndex-Z | _], reverse(Zs, [LastZIndex-Z | ReversedZs]), | ||||||
|     DeltaZ is LastZIndex - FirstZIndex, DeltaZ =\= 0, |     DeltaZ is LastZIndex - FirstZIndex, DeltaZ =\= 0, | ||||||
|     direction_len(Len), |     direction_len(Len), | ||||||
|     divmod(DeltaZ, Len, _, 0), |     divmod(DeltaZ, Len, _, 0), | ||||||
|     Offset = FirstZIndex, Stride = DeltaZ, |     Offset = FirstZIndex, Stride = DeltaZ, | ||||||
|     foldl([Idx-Z, NewIdx-Z, Off, Off]>>(NewIdx is Idx - Off), |     foldl([Idx-Z, NewIdx-Z, Off, Off]>>(NewIdx is Idx - Off), | ||||||
|           ReversedZs, ReversedLoop, Offset, _), |           ReversedZs, ReversedDests, Offset, _), | ||||||
|     reverse(ReversedLoop, Loop), |     reverse(ReversedDests, Dests), | ||||||
|     !. |     !. | ||||||
|  |  | ||||||
| zloop(Directions, Node, Index, Zs, Route) :- | zloop(Directions, Node, Index, Zs, Route) :- | ||||||
|     (   is_end(Node) |     (   is_end(Node) | ||||||
|     ->  append(Zs, [Index-Node], NewZs) |     ->  append(Zs, [Index-Node], NewZs) | ||||||
| @@ -79,3 +62,10 @@ next_step([], Move, Remain) :- direction_list([Move | Remain]). | |||||||
|  |  | ||||||
| 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_len(Len) :- direction_list(D), length(D, Len). | ||||||
|  |  | ||||||
|  | % pick([[1,2,3], [4], [5,6]], X). X = [1,4,5]; X = [1,4,6]; X = [2,4,5]; ... | ||||||
|  | pick(ListOfLists, Items) :- | ||||||
|  |     maplist([SubList, X]>>(member(X, SubList)), ListOfLists, Items). | ||||||
|  |  | ||||||
|  | natnum(0). | ||||||
|  | natnum(N) :- natnum(N0), N is N0 + 1. | ||||||
|   | |||||||
| @@ -8,4 +8,12 @@ nna to nnb-xxx. | |||||||
| nnb to nnc-nnc. | nnb to nnc-nnc. | ||||||
| nnc to nnz-nnz. | nnc to nnz-nnz. | ||||||
| nnz to nnb-nnb. | nnz to nnb-nnb. | ||||||
|  | ooa to ooz-oob. | ||||||
|  | oob to ood-ooc. | ||||||
|  | ooc to ooa-oox. | ||||||
|  | ood to ooz-ood. | ||||||
|  | ooz to oob-ooz. | ||||||
| xxx to xxx-xxx. | xxx to xxx-xxx. | ||||||
|  |  | ||||||
|  | % Routes = [mma-(2-2-[0-mmz]), nna-(6-3-[0-nnz, 3-nnz]), ooa-(8-1-[0-ooz, 1-ooz])]. | ||||||
|  | % X = mmannaooa-(24-18-[0-mmznnzooz]). | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user