Day 9: Marble Mania - Advent of Code 2018
I did the Advent of Code 2018 day 9 challenge in Erlang! Parts one and two are as follows:
#!/usr/bin/env escript
-mode(native).
%% https://adventofcode.com/2018/day/9
main(Args) ->
{ok, [N, M]} = io:fread("", "~d ~d"),
Sol =
case Args of
["2"] -> high_score(N, M * 100);
_ -> high_score(N, M)
end,
io:format("~p~n", [Sol]).
high_score(N, M) ->
high_score({[0], []}, 1, #{}, N, M).
high_score(_Marbles, Turn, Scores, _N, Last) when Turn > Last ->
FindWinner =
fun(K, V, {_, MaxV} = Max) ->
case V > MaxV of
true -> {K, V};
false -> Max
end
end,
{_Winner, HighScore} = maps:fold(FindWinner, {0, 0}, Scores),
HighScore;
high_score(Marbles, Turn, Scores, N, Last) ->
case Turn rem 23 =:= 0 of
false ->
NewMarbles = add_rotate_2(Turn, Marbles),
high_score(NewMarbles, Turn + 1, Scores, N, Last);
true ->
{H, NewMarbles} = rem_rotate_neg7(Marbles),
Points = Turn + H,
Update = fun(V) -> V + Points end,
Winner = Turn rem N,
NewScores = maps:update_with(Winner, Update, Points, Scores),
high_score(NewMarbles, Turn + 1, NewScores, N, Last)
end.
add_rotate_2(New, {[0], []}) -> {[New, 0], []};
add_rotate_2(New, {Front, Back}) ->
case Front of
[H1, H2|T] ->
{[New|T], [H2, H1|Back]};
[H1] ->
[H2|T] = lists:reverse(Back),
{[New|T], [H2, H1]};
[] ->
[H1, H2|T] = lists:reverse(Back),
{[New|T], [H2, H1]}
end.
rem_rotate_neg7({Front, Back}) ->
case Back of
[HN1, HN2, HN3, HN4, HN5, HN6, HN7|R] ->
{HN7, {[HN6, HN5, HN4, HN3, HN2, HN1|Front], R}};
_ ->
Rev = Back ++ lists:reverse(Front),
rem_rotate_neg7({[], Rev})
end.
ARTICLES: 7
Day 1: The Tyranny of the Rocket Equation
I did the Advent of Code 2019 day 1 challenge in Erlang!
#!/usr/bin/env escript
-mode(native).
%% https://adventofcode.com/2019/day/1
main(Args) ->
Nums = lists:append(read_list("~d")),
Sol =
case Args of
["2"] -> fuel_proper(Nums);
_ -> fuel_mod(Nums)
end,
io:format("~w~n", [Sol]).
read_list(Pat) ->
read_list(Pat, []).
read_list(Pat, Acc) ->
case io:fread("", Pat) of
{ok, Res} -> read_list(Pat, [Res|Acc]);
eof -> lists:reverse(Acc)
end.
fuel_mod(Nums) ->
lists:sum([(Mod div 3) - 2 || Mod <- Nums]).
fuel_proper(Nums) ->
lists:sum([mod_proper(Mod) || Mod <- Nums]).
mod_proper(Mod) ->
mod_proper(Mod, 0).
mod_proper(Lift, Fuel) ->
NF = (Lift div 3) - 2,
case NF < 0 of
true -> Fuel;
false -> mod_proper(NF, Fuel + NF)
end.
READ MORE
Day 14: Chocolate Charts - Advent of Code 2018
I did the Advent of Code 2018 day 14 challenge in Erlang! Parts one and two are as follows:
#!/usr/bin/env escript
-mode(native).
%% https://adventofcode.com/2018/day/14
-define(INPUT, 635041).
main(Args) ->
Sol =
case Args of
["2"] -> seek([6,3,5,0,4,1]);
_ ->
{_, P} = score(?INPUT),
P
end,
io:format("~p~n", [Sol]).
seek(Target) ->
seek(Target, 1000).
seek(Target, Range) ->
io:format("~p~n", [Range]),
{M, _} = score(Range),
io:format("Score done~n"),
case find(Target, M) of
{true, I} -> I;
false -> seek(Target, Range * 10)
end.
find(Target, M) ->
Rs = [D || {_, D} <- lists:sort(maps:to_list(M))],
io:format("Seq Done"),
find(0, Rs, Target).
find(_, [], _) ->
false;
find(I, [_|RRs] = Rs, Ds) ->
case lists:prefix(Ds, Rs) of
true ->
{true, I};
false ->
find(I + 1, RRs, Ds)
end.
score(N) ->
score(0, 1, #{0 => 3, 1 => 7}, 2, N).
score(_, _, Map, M, N) when M > N + 11 ->
Fold =
fun(X, A) ->
A * 10 + maps:get(X, Map)
end,
{Map, lists:foldl(Fold, 0, lists:seq(N, N + 9))};
score(E1, E2, Map, M, N) ->
%io:format("~p~n", [[D || {_, D} <- lists:sort(maps:to_list(Map))]]),
S1 = maps:get(E1, Map),
S2 = maps:get(E2, Map),
New = S1 + S2,
%io:format("~p~n", [{E1, E2, S1, S2, New}]),
{NewMap, NewM} =
case New > 9 of
true ->
{Map#{M => New div 10, M + 1 => New rem 10}, M + 2};
false ->
{Map#{M => New}, M + 1}
end,
{NewE1, NewE2} =
{(E1 + S1 + 1) rem NewM, (E2 + S2 + 1) rem NewM},
score(NewE1, NewE2, NewMap, NewM, N).
READ MORE
Day 12: Subterranean Sustainability - Advent of Code 2018
I did the Advent of Code 2018 day 12 challenge in Erlang! Parts one and two are as follows:
#!/usr/bin/env escript
-mode(native).
%% https://adventofcode.com/2018/day/12
main(Args) ->
{ok, [Initial]} = io:fread("", "initial state: ~s"),
{ok, []} = io:fread("", ""),
Evolve = make_evolve(read_list("~c~c~c~c~c => ~c")),
Sol =
case Args of
["2"] -> sum_state(state_after(50 * 1000, {0, Initial}, Evolve));
_ -> sum_state(state_after(20, {0, Initial}, Evolve))
end,
io:format("~p~n", [Sol]).
read_list(Pat) ->
read_list(Pat, []).
read_list(Pat, Acc) ->
case io:fread("", Pat) of
{ok, Res} -> read_list(Pat, [Res|Acc]);
eof -> lists:reverse(Acc)
end.
make_evolve(List) ->
Fold =
fun([[A],[B],[C],[D],[E],[F]], Map) ->
Map#{[A,B,C,D,E] => F}
end,
lists:foldl(Fold, #{}, List).
state_after(0, State, _Evolve) ->
State;
state_after(N, State, Evolve) ->
%io:format("~p~n", [State]),
NewState = evolve(State, Evolve),
state_after(N - 1, NewState, Evolve).
evolve({F, Line}, Evolve) ->
evolve("...." ++ Line ++ "....", Evolve, F-2, []).
evolve([A,B,C,D,E|Rest], Evolve, F, Acc) ->
NC = maps:get([A,B,C,D,E], Evolve, $.),
{NF, NAcc} =
case Acc =:= [] andalso NC =:= $. of
true -> {F + 1, []};
false -> {F, [NC|Acc]}
end,
evolve([B,C,D,E|Rest], Evolve, NF, NAcc);
evolve(_, _, F, Acc) ->
Pred = fun(C) -> C =:= $. end,
{F, lists:reverse(lists:dropwhile(Pred, Acc))}.
sum_state({F, List}) ->
sum_state(F, List, 0).
sum_state(_, [], Sum) -> Sum;
sum_state(I, [C|Rest], Sum) ->
NSum =
case C =:= $# of
true -> Sum + I;
false -> Sum
end,
sum_state(I+1, Rest, NSum).
READ MORE
Day 9: Marble Mania - Advent of Code 2018
I did the Advent of Code 2018 day 9 challenge in Erlang! Parts one and two are as follows:
#!/usr/bin/env escript
-mode(native).
%% https://adventofcode.com/2018/day/9
main(Args) ->
{ok, [N, M]} = io:fread("", "~d ~d"),
Sol =
case Args of
["2"] -> high_score(N, M * 100);
_ -> high_score(N, M)
end,
io:format("~p~n", [Sol]).
high_score(N, M) ->
high_score({[0], []}, 1, #{}, N, M).
high_score(_Marbles, Turn, Scores, _N, Last) when Turn > Last ->
FindWinner =
fun(K, V, {_, MaxV} = Max) ->
case V > MaxV of
true -> {K, V};
false -> Max
end
end,
{_Winner, HighScore} = maps:fold(FindWinner, {0, 0}, Scores),
HighScore;
high_score(Marbles, Turn, Scores, N, Last) ->
case Turn rem 23 =:= 0 of
false ->
NewMarbles = add_rotate_2(Turn, Marbles),
high_score(NewMarbles, Turn + 1, Scores, N, Last);
true ->
{H, NewMarbles} = rem_rotate_neg7(Marbles),
Points = Turn + H,
Update = fun(V) -> V + Points end,
Winner = Turn rem N,
NewScores = maps:update_with(Winner, Update, Points, Scores),
high_score(NewMarbles, Turn + 1, NewScores, N, Last)
end.
add_rotate_2(New, {[0], []}) -> {[New, 0], []};
add_rotate_2(New, {Front, Back}) ->
case Front of
[H1, H2|T] ->
{[New|T], [H2, H1|Back]};
[H1] ->
[H2|T] = lists:reverse(Back),
{[New|T], [H2, H1]};
[] ->
[H1, H2|T] = lists:reverse(Back),
{[New|T], [H2, H1]}
end.
rem_rotate_neg7({Front, Back}) ->
case Back of
[HN1, HN2, HN3, HN4, HN5, HN6, HN7|R] ->
{HN7, {[HN6, HN5, HN4, HN3, HN2, HN1|Front], R}};
_ ->
Rev = Back ++ lists:reverse(Front),
rem_rotate_neg7({[], Rev})
end.
READ MORE
Day 8: Memory maneuver - Advent of Code
I did the Advent of Code 2018 day 8 challenge in Erlang! Parts one and two are as follows:
#!/usr/bin/env escript
-mode(native).
%% https://adventofcode.com/2018/day/8
main(Args) ->
[Input] = read_input(),
Sol =
case Args of
["2"] -> value([Input], [1]);
_ -> sum_metadata([Input])
end,
io:format("~p~n", [Sol]).
read_input() ->
read_input(1).
read_input(0) -> [];
read_input(Nodes) ->
{ok, [ChildrenCount, MetaCount]} = io:fread("", "~d ~d"),
Children = read_input(ChildrenCount),
ReadMeta =
fun() ->
{ok, [M]} = io:fread("", "~d"),
M
end,
Meta = [ReadMeta() || _ <- lists:seq(1, MetaCount)],
Rest = read_input(Nodes - 1),
[{Children, Meta} | Rest].
sum_metadata([]) -> 0;
sum_metadata([{Children, Meta}|Rest]) ->
A = sum_metadata(Rest),
B = sum_metadata(Children),
C = lists:sum(Meta),
A + B + C.
value([], Meta) ->
lists:sum(Meta);
value(Children, Which) ->
Marked = select(Which, Children),
lists:sum([value(C, M) || {C, M} <- Marked]).
select(Which, Children) ->
select(Which, Children, []).
select([], _, Acc) ->
Acc;
select([N|R], Children, Acc) ->
try
C = lists:nth(N, Children),
select(R, Children, [C|Acc])
catch
_:_ ->
select(R, Children, Acc)
end.
READ MORE