]> fbox.kageds.com Git - adventofcode.git/blob - 2021/day4/day4.erl
Day 6
[adventofcode.git] / 2021 / day4 / day4.erl
1 %% to compile: erlc day3A.erl
2 %% to run: erl -noshell -s day3 solve
3 %%
4 -module(day4).
5
6 -export ([solve/0, solve/1, solve/2]).
7 -export ([read_boards/0]).
8
9 solve() ->
10 solve(['1']),
11 solve(['2']),
12 init:stop().
13
14 solve(A) ->
15 solve(A, read_boards()).
16
17 solve(['1'], D) ->
18 io:format("The solution to ~p puzzle1 is: ~p~n", [?MODULE, solve(1, D)]);
19 solve(1, D) ->
20 solution1(D);
21 solve(['2'], D) ->
22 io:format("The solution to ~p puzzle2 is: ~p~n", [?MODULE, solve(2, D)]);
23 solve(2, D) ->
24 solution2(D).
25
26 read_boards() ->
27 {ok, IO} = file:open("boards.txt", 'read'),
28 Data = read_boards(IO),
29 file:close(IO),
30 Data.
31
32 read_boards(IO) ->
33 read_boards(IO, []).
34
35 read_boards('eof', Boards) ->
36 Boards;
37 read_boards(IO, Boards) ->
38 case read_board(IO) of
39 'eof' -> Boards;
40 Board -> read_boards(IO, Boards ++ [Board])
41 end.
42
43 read_board(IO) ->
44 read_line(IO, []).
45
46 read_line(IO, Board) ->
47 case file:read_line(IO) of
48 {ok, "\n"} -> make_board(Board);
49 'eof' -> 'eof';
50 {ok, Line} -> read_line(IO, [[ list_to_integer(X) || X <- string:tokens(Line, " \n")]|Board])
51 end.
52
53 make_board(B) ->
54 B ++ [lists:map(fun(X) -> lists:nth(Y,X) end, B) || Y <- lists:seq(1,5)].
55
56 solution1(Boards) ->
57 Input = get_input(),
58 Bingo = process(Boards, 1, Input),
59 score(Bingo).
60
61 solution2(Boards) ->
62 Input = get_input(),
63 Bingo = process(Boards, length(Boards), Input),
64 score(Bingo).
65
66 score({'bingo', Num, Board}) ->
67 Fun = fun(L) -> lists:foldl(fun(X, Acc) -> X + Acc end, 0, L) end,
68 Num * (Fun([Fun(X) || X <- Board]) / 2).
69
70 process(Boards, _Count, []) -> Boards;
71 process(Boards, Count, [H|T]) ->
72 New_boards = process_boards(Boards, H, []),
73 case is_bingo(New_boards) of
74 {'bingo', Board} when Count == 1 -> {'bingo', H, Board};
75 {'bingo', _Board} ->
76 New_boards2 = delete_bingo_boards(New_boards),
77 process(New_boards2, Count - length(New_boards) + length(New_boards2), T);
78 _Else -> process(New_boards, Count, T)
79 end.
80
81
82 process_boards([], _Num, Acc) ->
83 Acc;
84 process_boards([B|T], Num, Acc) ->
85 process_boards(T, Num, [[lists:delete(Num, X) || X <- B]|Acc]).
86
87 is_bingo([]) -> 'false';
88 is_bingo([Board|Rest]) ->
89 case is_line(Board) of
90 'true' -> {'bingo', Board};
91 'false' -> is_bingo(Rest)
92 end.
93 is_line(Board) ->
94 lists:any(fun(X) -> X == [] end, Board).
95
96 delete_bingo_boards(Boards) ->
97 [Board || Board <- Boards, not is_line(Board)].
98
99 get_input() ->
100 [83,69,34,46,30,23,19,75,22,37,89,78,32,39,11,44,95,43,26,48,84,53,94,88,18,40,62,35,27,42,15,2,91,20,4,64,99,71,54,97,52,36,28,7,74,45,70,86,98,1,61,50,68,6,77,8,57,47,51,72,65,3,49,24,79,13,17,92,41,80,63,67,82,90,55,0,10,93,38,21,59,73,33,31,9,76,5,66,16,58,85,87,12,29,25,14,96,56,60,81].