diff --git a/day9.erl b/day9.erl index 067febd..e5f5f70 100644 --- a/day9.erl +++ b/day9.erl @@ -3,9 +3,47 @@ -export([solve/1]). solve(Input) -> - State = #{head => {0, 0}, tail => {0, 0}, visited => #{{0, 0} => []}}, - #{visited := Visited} = EndState = fold_moves(Input, fun simulate/2, State), - {map_size(Visited), none}. + %#{visited := Visited} = EndState = fold_moves(Input, fun simulate/2, State), + {simulate_rope(Input, 1), simulate_rope(Input, 9)}. + +make_rope(Length) -> + Rope0 = make_head(), + Rope1 = add_knots(Rope0, Length), + add_trace(Rope1). + +simulate_rope(Input, Length) -> + {RopeFn, RopeState} = make_rope(Length), + {Visited, _RopeState} = fold_moves(Input, RopeFn, RopeState), + map_size(Visited). + +make_head() -> + { + fun(Move, [Pos]) -> + [vec_add(Move, Pos)] + end, + [{0, 0}] + }. + +add_knot({HeadFn, Head0}) -> + { + fun(Move, [TailPos|HeadState]) -> + [HeadPosNew|_] = HeadStateNew = HeadFn(Move, HeadState), + [chase_tail(HeadPosNew, TailPos) | HeadStateNew] + end, + [{0,0}|Head0] + }. + +add_knots(Stream, 0) -> Stream; +add_knots(Stream, N) -> add_knots(add_knot(Stream), N-1). + +add_trace({SimFn, Sim0}) -> + { + fun(Move, {Visited, SimAccIn}) -> + [Pos | _] = SimAccOut = SimFn(Move, SimAccIn), + {Visited#{Pos => []}, SimAccOut} + end, + {#{}, Sim0} + }. simulate(Move, #{head := Head, tail := Tail, visited := Visited}) -> NewHead = vec_add(Head, Move),