This topic is about Day 6 of the Advent of Code 2021.
We have a private leaderboard (shared with users of the elixir forum):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
This topic is about Day 6 of the Advent of Code 2021.
We have a private leaderboard (shared with users of the elixir forum):
https://adventofcode.com/2021/leaderboard/private/view/370884
The entry code is:
370884-a6a71927
Pretty easy one today. I used the solution they were obviously trying to trick you into using by representing the fish state as a list for part 1 and appending new fish as they spawn, before changing it to a map of counters to be able to run part 2.
Edit: Here’s a solution - did it in Go at first, which is famously verbose, and I wanted to see how much cleaner it would look in Erlang. Quite a bit, and I didn’t spend much time trying to make it pretty.
-module(day06).
-export([main/0]).
main() ->
Init = parse("input/day06.txt"),
io:format("Part 1: ~p~nPart 2: ~p~n", [run(Init, 80), run(Init, 256)]).
run(Fish, 0) -> lists:sum(maps:values(Fish));
run(Fish, Days) -> run(tick(Fish), Days - 1).
tick(Fish) ->
Spawning = maps:get(0, Fish, 0),
Decremented = lists:foldl(fun shift_down/2, Fish, lists:seq(1, 8)),
Decremented#{8 => Spawning,
6 => maps:get(6, Decremented, 0) + Spawning}.
shift_down(Ix, Map) ->
Map#{Ix - 1 => maps:get(Ix, Map, 0)}.
parse(File) ->
{ok, BinData} = file:read_file(File),
Str = binary_to_list(BinData),
Trimmed = string:trim(Str),
freq([list_to_integer(Token) || Token <- string:tokens(Trimmed, ",")]).
freq(Fish) ->
lists:foldl(fun increment_at/2, #{}, Fish).
increment_at(Ix, Map) ->
maps:update_with(Ix, fun(N) -> N + 1 end, 1, Map).
@Gwaeron that’s how it went for me :
main(File) ->
{ok, RawData} = file:read_file(File),
Data = [ binary_to_integer(X) || X <- binary:split(RawData, <<",">>, [global, trim]) ],
io:format("part 1: ~p~n", [solve1(Data)]),
io:format("part 2: ~p~n", [solve2(Data)]),
ok.
solve1(Data) ->
length(simulate_n(Data, 80)).
simulate_n(Data, Days) ->
lists:foldl(fun (_, Acc) -> [ NewFishes || F <- Acc, NewFishes <- simulate(F) ] end,
Data,
lists:seq(1, Days)).
simulate(0) -> [6, 8];
simulate(X) -> [X - 1].
solve2(Data) ->
OneToFive = maps:values(freq(Data)),
Initial = list_to_tuple([0] ++ OneToFive ++ [0, 0, 0]),
lists:sum(tuple_to_list(simulate_count_n(Initial, 256))).
simulate_count_n(Acc, 0) -> Acc;
simulate_count_n(Acc, N) ->
simulate_count_n(simulate_count(Acc), N - 1).
simulate_count({V0, V1, V2, V3, V4, V5, V6, V7, V8}) ->
{V1, V2, V3, V4, V5, V6, V7 + V0, V8, V0}.
freq(List) ->
lists:foldl(fun (K, Acc) -> maps:update_with(K, fun (V) -> V + 1 end, 1, Acc) end,
#{},
List).
Ditto.
Buy the way, there’s an Unofficial AoC 2021 Survey - would be good if more than one person ticked Erlang
Done in Awk first as I respect my initial engagement, but felt it would have been so much easier in Erlang:
BEGIN { FS="," }
{ for (i=1; i<=NF; i++) { l[$i]++ } }
END {
for (i=1; i<=DAYS; i++) {
t=l[0]
for (j=0; j<8; j++) { l[j]=l[j+1] }
l[8]=t; l[6]+=t
}
for (i in l) { c+=l[i] }
print c
}
For comparison:
main([File]) ->
{ok, Bin} = file:read_file(File),
T = lists:foldl(
fun(N,T) -> setelement(N+1, T, element(N+1,T)+1) end,
{0,0,0,0,0,0,0,0,0},
[binary_to_integer(B) || L <- string:split(Bin, "\n", all), L =/= <<>>,
B <- string:split(L, ",", all)]
),
io:format("~p~n", [run(256, T)]).
run(0,{A,B,C,D,E,F,G,H,I}) -> A+B+C+D+E+F+G+H+I;
run(N,{A,B,C,D,E,F,G,H,I}) -> run(N-1, {B,C,D,E,F,G,H+A,I,A}).
Part 1:
part1() ->
Bin = <<"3,4,3,1,2\n">>,
Data = [binary_to_integer(X) || X <- re:split(Bin, "[,/\n]+"), X /= <<>>],
length(simulation(256, Data))
simulation(0, Fishs) -> Fishs;
simulation(Days, Fishs) -> simulation(Days - 1, lanternfish(Fishs)).
lanternfish([]) -> [];
lanternfish([0|T]) -> [6 | [8 | lanternfish(T)]];
lanternfish([H|T]) -> [H - 1 | lanternfish(T)].
And… After crashing of my shell :
Part 2:
part2() ->
{ok, Bin} = file:read_file("input"),
Data = [binary_to_integer(X) || X <- re:split(Bin, "[,/\n]+"), X /= <<>>],
Acc = #{0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, 6 => 0, 7 => 0, 8 => 0},
gen(256, init(Data, Acc)).
init([], Acc) ->
Acc;
init([H|T], Acc) ->
init(T, Acc#{H => maps:get(H, Acc) + 1}).
gen(0, #{0 := D0, 1 := D1, 2 := D2, 3 := D3, 4 := D4, 5 := D5, 6 := D6, 7 := D7, 8 := D8}) ->
D0 + D1 + D2 + D3 + D4 + D5 + D6 + D7 + D8;
gen(Days, #{0 := D0, 1 := D1, 2 := D2, 3 := D3, 4 := D4, 5 := D5, 6 := D6, 7 := D7, 8 := D8}) ->
gen(Days - 1, #{0 => D1, 1 => D2, 2 => D3, 3 => D4, 4 => D5, 5 => D6, 6 => D0 + D7, 7 => D8, 8 => D0}).
Thanks. @Gwaeron. Your first few words helped me solve today’s puzzle: pensandoemelixir/day06_v2.erl at main · adolfont/pensandoemelixir · GitHub
Ugly as usual, but I believe I am learning.