|
|
@ -3,9 +3,47 @@ |
|
|
-export([solve/1]). |
|
|
-export([solve/1]). |
|
|
|
|
|
|
|
|
solve(Input) -> |
|
|
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}) -> |
|
|
simulate(Move, #{head := Head, tail := Tail, visited := Visited}) -> |
|
|
NewHead = vec_add(Head, Move), |
|
|
NewHead = vec_add(Head, Move), |
|
|
|