From a997d00c89f9d07af00a97713f162aeaac0039c2 Mon Sep 17 00:00:00 2001 From: Dory Date: Sat, 9 Dec 2023 11:41:52 -0800 Subject: [PATCH] improve d8p2 readability --- 08/part2.pl | 64 +++++++++++++++++++++++++++-------------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/08/part2.pl b/08/part2.pl index 9b05c28..cb94866 100644 --- a/08/part2.pl +++ b/08/part2.pl @@ -1,5 +1,3 @@ -:- table direction_loop/1. - :- op(700, xfx, l). :- op(700, xfx, r). From l To :- From to To-_. @@ -14,51 +12,55 @@ collapse_routes([X], X). collapse_routes(Routes, Collapsed) :- writef('Collapsing: %t\n', [Routes]), sort(2, @=<, Routes, [Route1, Route2 | CdrRoutes]), - unify2(Route1, Route2, 0-0-0-0, [], NewRoute), + unify2(Route1, Route2, NewRoute), collapse_routes([NewRoute | CdrRoutes], Collapsed). -unify2(Route1, Route2, N1-Term1-N2-Term2, Founds, NewRoute) :- - Route1 = A1-(Stride1-Offset1-Loop1), - Route2 = A2-(Stride2-Offset2-Loop2), - nth0(Term1, Loop1, C1-_), - nth0(Term2, Loop2, C2-_), - Z1 is Offset1 + Stride1*N1 + C1, - Z2 is Offset2 + Stride2*N2 + C2, - next(Route1, N1-Term1, NextN1-NextTerm1), - ( Z1 =:= Z2 - -> ( Founds = [OldZ] - -> atom_concat(A1, A2, NewA), - NewStride is Z1 - OldZ, - NewRoute = NewA-(NewStride-OldZ-[0-NewA]), +% unify2 combines 2 routes into one with its own stride-offsets-dests +unify2(Route1, Route2, Route12) :- unify2(Route1, Route2, 0-0-0-0, [], Route12). +unify2(Route1, Route2, N1-Dest1-N2-Dest2, Founds, NewRoute) :- + Route1 = A1-(Stride1-Offset1-Dests1), + Route2 = A2-(Stride2-Offset2-Dests2), + nth0(Dest1, Dests1, C1-Z1), + nth0(Dest2, Dests2, C2-Z2), + Len1 is Offset1 + Stride1*N1 + C1, + Len2 is Offset2 + Stride2*N2 + C2, + next(Dests1, N1-Dest1, NextN1-NextDest1), + ( Len1 =:= Len2 + -> ( Founds = [OldLen] + -> atom_concat(A1, A2, NewA), atom_concat(Z1, Z2, NewZ), + NewStride is Len1 - OldLen, + NewRoute = NewA-(NewStride-OldLen-[0-NewZ]), ! - ; unify2(Route1, Route2, NextN1-NextTerm1-N2-Term2, [Z1], NewRoute) + ; unify2(Route1, Route2, NextN1-NextDest1-N2-Dest2, [Len1], 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) + ; Len1 < Len2 + -> unify2(Route1, Route2, NextN1-NextDest1-N2-Dest2, Founds, NewRoute) + ; next(Dests2, N2-Dest2, NextN2-NextDest2), + unify2(Route1, Route2, N1-Dest1-NextN2-NextDest2, 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). +% next(Dests, NumberOfLoops-WhichInternalZ, NextNumberOfLoops-NextInternalZ) +next(Dests, NLoops-Dest, NextNLoops-NextDest) :- + length(Dests, DestsLen), + ( Dest < DestsLen - 1 + -> NextNLoops is NLoops, NextDest is Dest + 1 + ; NextNLoops is NLoops + 1, NextDest is 0). 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]), DeltaZ is LastZIndex - FirstZIndex, DeltaZ =\= 0, direction_len(Len), divmod(DeltaZ, Len, _, 0), Offset = FirstZIndex, Stride = DeltaZ, foldl([Idx-Z, NewIdx-Z, Off, Off]>>(NewIdx is Idx - Off), - ReversedZs, ReversedLoop, Offset, _), - reverse(ReversedLoop, Loop), + ReversedZs, ReversedDests, Offset, _), + reverse(ReversedDests, Dests), !. - zloop(Directions, Node, Index, Zs, Route) :- ( is_end(Node) -> append(Zs, [Index-Node], NewZs)