commit
This commit is contained in:
130
day18/day18.erl
Normal file
130
day18/day18.erl
Normal file
@@ -0,0 +1,130 @@
|
||||
-module(day18).
|
||||
|
||||
-export ([solve/0, solve/1]).
|
||||
-compile ([export_all]).
|
||||
|
||||
solve() ->
|
||||
solve(['1']),
|
||||
solve(['2']),
|
||||
init:stop().
|
||||
|
||||
solve(['1']) ->
|
||||
io:format("The solution to ~p puzzle1 is: ~p~n", [?MODULE, solve(1)]);
|
||||
solve(1) ->
|
||||
solution1();
|
||||
solve(['2']) ->
|
||||
io:format("The solution to ~p puzzle2 is: ~p~n", [?MODULE, solve(2)]);
|
||||
solve(2) ->
|
||||
solution2().
|
||||
|
||||
solution1() ->
|
||||
{ok, IO} = file:open("input.txt", 'read'),
|
||||
Ans = maybe_reduce(read_line(IO), IO),
|
||||
file:close(IO),
|
||||
magnitude(Ans).
|
||||
|
||||
solution2() ->
|
||||
{ok, IO} = file:open("input.txt", 'read'),
|
||||
Numbers = read_all_lines(read_line(IO), IO, []),
|
||||
file:close(IO),
|
||||
io:format("total:~p lines: ~p~n", [length(Numbers), Numbers]),
|
||||
max_magnitude(Numbers).
|
||||
|
||||
read_all_lines('eof', _IO, Acc) ->
|
||||
Acc;
|
||||
read_all_lines(Line, IO, Acc) ->
|
||||
read_all_lines(read_line(IO), IO, [Line|Acc]).
|
||||
|
||||
read_line(IO) ->
|
||||
case file:read_line(IO) of
|
||||
{ok, Line} ->
|
||||
{ok, Tokens, _} = erl_scan:string(Line ++ "."),
|
||||
{ok, Term} = erl_parse:parse_term(Tokens),
|
||||
Term;
|
||||
'eof' -> 'eof'
|
||||
end.
|
||||
|
||||
max_magnitude(Numbers) when is_list(Numbers) ->
|
||||
lists:max([ max_magnitude(lists:split(I, Numbers)) || I <- lists:seq(1, length(Numbers))]);
|
||||
max_magnitude({List1, List2}) ->
|
||||
[H|T] = lists:reverse(List1),
|
||||
max_magnitude(H, T ++ List2).
|
||||
|
||||
max_magnitude(Number, Rest) ->
|
||||
lists:foldl(fun(N, MaxMag) ->
|
||||
case magnitude(reduce([Number, N])) of
|
||||
Mag when Mag > MaxMag -> Mag;
|
||||
_ -> MaxMag
|
||||
end
|
||||
end, 0, Rest).
|
||||
|
||||
|
||||
magnitude(A) when is_integer(A) -> A;
|
||||
magnitude([A,B]) ->
|
||||
(3 * magnitude(A)) + (2 * magnitude(B)).
|
||||
|
||||
maybe_reduce(A, IO) ->
|
||||
case read_line(IO) of
|
||||
'eof' -> A;
|
||||
B ->
|
||||
maybe_reduce(reduce([A,B]), IO)
|
||||
end.
|
||||
|
||||
reduce(N) ->
|
||||
case maybe_explode(N, 0) of
|
||||
{true, New, _, _} ->
|
||||
reduce(New);
|
||||
false ->
|
||||
case maybe_split(N) of
|
||||
{true, New} ->
|
||||
reduce(New);
|
||||
false ->
|
||||
N
|
||||
end
|
||||
end.
|
||||
|
||||
maybe_explode([A,B], Depth) when Depth >= 4, is_integer(A), is_integer(B) ->
|
||||
{true, 0, A, B};
|
||||
maybe_explode([A,B], Depth) ->
|
||||
case maybe_explode(A, Depth+1) of
|
||||
{true, New, AddA, AddB} ->
|
||||
{true, [New, add_explode({b, AddB}, B)], AddA, 0};
|
||||
false ->
|
||||
case maybe_explode(B, Depth+1) of
|
||||
{true, New, AddA, AddB} ->
|
||||
{true, [add_explode({a, AddA}, A), New], 0, AddB};
|
||||
false ->
|
||||
false
|
||||
end
|
||||
end;
|
||||
maybe_explode(N, _) when is_integer(N) ->
|
||||
false.
|
||||
|
||||
add_explode({_, Add}, Num) when is_integer(Num) ->
|
||||
Add + Num;
|
||||
add_explode({b, Add}, [A,B]) ->
|
||||
[add_explode({b, Add}, A), B];
|
||||
add_explode({a, Add}, [A,B]) ->
|
||||
[A, add_explode({a,Add}, B)].
|
||||
|
||||
maybe_split(N) when is_integer(N) ->
|
||||
case N > 9 of
|
||||
true ->
|
||||
Left = N div 2,
|
||||
Right = case Left*2 == N of true -> Left; false -> Left+1 end,
|
||||
{true, [Left, Right]};
|
||||
false ->
|
||||
false
|
||||
end;
|
||||
maybe_split([A, B]) ->
|
||||
case maybe_split(A) of
|
||||
{true, NewA} ->
|
||||
{true, [NewA, B]};
|
||||
false ->
|
||||
case maybe_split(B) of
|
||||
{true, NewB} ->
|
||||
{true, [A, NewB]};
|
||||
false ->
|
||||
false
|
||||
end
|
||||
end.
|
||||
Reference in New Issue
Block a user