1 changed files with 59 additions and 0 deletions
-
59day9.erl
@ -0,0 +1,59 @@ |
|||
-module(day9). |
|||
|
|||
-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}. |
|||
|
|||
simulate(Move, #{head := Head, tail := Tail, visited := Visited}) -> |
|||
NewHead = vec_add(Head, Move), |
|||
NewTail = chase_tail(NewHead, Tail), |
|||
NewVisited = Visited#{NewTail => []}, |
|||
#{head => NewHead, tail => NewTail, visited => NewVisited}. |
|||
|
|||
chase_tail(Head, Tail) -> |
|||
Diff = vec_sub(Head, Tail), |
|||
case vec_norm(Diff) of |
|||
Diff -> Tail; |
|||
Norm -> vec_add(Norm, Tail) |
|||
end. |
|||
|
|||
fold_instructions(<<Letter, $\s, RestIn/binary>>, Fun, Acc) -> |
|||
{Count, RestOut} = parse_int(RestIn, 0), |
|||
Direction = |
|||
case Letter of |
|||
$U -> up; |
|||
$D -> down; |
|||
$L -> left; |
|||
$R -> right |
|||
end, |
|||
fold_instructions(RestOut, Fun, Fun({Direction, Count}, Acc)); |
|||
fold_instructions(<<$\n, Rest/binary>>, Fun, Acc) -> fold_instructions(Rest, Fun, Acc); |
|||
fold_instructions(<<>>, _Fun, Acc) -> Acc. |
|||
|
|||
fold_moves(Stream, Fun, Acc) -> element(2, fold_instructions(Stream, fun per_move/2, {Fun, Acc})). |
|||
|
|||
per_move({Direction, Count}, {Fun, Acc}) -> {Fun, per_move0(direction_vec(Direction), Count, Fun, Acc)}. |
|||
|
|||
per_move0(_Move, 0, _Fun, Acc) -> Acc; |
|||
per_move0(Move, Count, Fun, Acc) -> per_move0(Move, Count-1, Fun, Fun(Move, Acc)). |
|||
|
|||
direction_vec(up) -> {0, 1}; |
|||
direction_vec(down) -> {0, -1}; |
|||
direction_vec(left) -> {-1, 0}; |
|||
direction_vec(right) -> {1, 0}. |
|||
|
|||
vec_add({X1, Y1}, {X2, Y2}) -> {X1+X2, Y1+Y2}. |
|||
|
|||
vec_sub({X1, Y1}, {X2, Y2}) -> {X1-X2, Y1-Y2}. |
|||
|
|||
vec_norm({X, Y}) -> {norm(X), norm(Y)}. |
|||
|
|||
norm(X) when X > 0 -> 1; |
|||
norm(X) when X < 0 -> -1; |
|||
norm(0) -> 0. |
|||
|
|||
parse_int(<<Char, Rest/binary>>, Acc) when Char >= $0 andalso Char =< $9 -> parse_int(Rest, Acc*10+(Char - $0)); |
|||
parse_int(Rest, Acc) -> {Acc, Rest}. |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue