]> fbox.kageds.com Git - adventofcode.git/blob - day9/day9.erl
alan day9 erlang
[adventofcode.git] / day9 / day9.erl
1 %% to compile: erlc day3A.erl
2 %% to run: erl -noshell -s day3 solve
3 %%
4 -module(day9).
5
6 -export ([solve/0, solve/1, solve/2]).
7 -export ([read_input/0]).
8
9 solve() ->
10 solve(['1']),
11 solve(['2']),
12 init:stop().
13
14 solve(A) ->
15 solve(A, read_input()).
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_input() ->
27 {ok, IO} = file:open("input.txt", 'read'),
28 Data = read_input(IO),
29 file:close(IO),
30 Data.
31
32 read_input(IO) ->
33 read_input(IO, []).
34
35 read_input(IO, Input) ->
36 case read_line(IO) of
37 'eof' -> Input;
38 Line -> read_input(IO, Input ++ [Line])
39 end.
40
41 read_line(IO) ->
42 case file:read_line(IO) of
43 'eof' -> 'eof';
44 {ok, Line} -> [ X - $0 || X <- Line, [X] /= "\n"]
45 end.
46
47 solution1(Table) ->
48 Low_points = low_points(Table),
49 lists:foldl(fun(C, Acc) -> Acc + 1 + get_value(C, Table) end, 0, Low_points).
50
51 solution2(Table) ->
52 Low_points = low_points(Table),
53 Basins = get_basins(Low_points, Table),
54 [B1,B2,B3|_] = lists:sort(fun(A, B) -> length(A) > length(B) end, Basins),
55 length(B1) * length(B2) * length(B3).
56
57
58 get_basins(Low_points, Table) ->
59 get_basins(Low_points, Table, 0, []).
60
61 get_basins([], _Table, _, Basins) -> Basins;
62 get_basins([Low_point|Rest], Table, Count, Basins) ->
63 Basin = [Low_point|lists:usort(get_up_slopes([Low_point], Table))],
64 get_basins(Rest, Table, Count + 1, [Basin|Basins]).
65
66 low_points([H|_] = Table) ->
67 X = length(H),
68 Y = length(Table),
69 Coords = lists:flatten([[{A,B} || A <- lists:seq(1,X)] || B <- lists:seq(1,Y)]),
70 lists:filter(fun(C) -> is_low_point(C, Table) end, Coords).
71
72 get_up_slopes(Coords, Table) ->
73 get_up_slopes(Coords, Table, []).
74
75 get_up_slopes([], _Table, Acc) -> Acc;
76 get_up_slopes([{X, Y}|Rest], Table, Acc) ->
77 V = get_value({X,Y}, Table),
78 Neighbours = [{X+1, Y},{X-1, Y},{X, Y+1},{X, Y-1}],
79 Up_slopes = lists:filter(fun({X1,Y1}) -> C = get_value({X1,Y1}, Table), C /= 9 andalso C /=10 andalso C > V end, Neighbours),
80 get_up_slopes(lists:usort(Rest ++ Up_slopes), Table, lists:usort(Acc ++ Up_slopes)).
81
82 is_low_point({X,Y}, Table) ->
83 V = get_value({X,Y}, Table),
84 V < get_value({X+1, Y}, Table) andalso
85 V < get_value({X-1, Y}, Table) andalso
86 V < get_value({X, Y+1}, Table) andalso
87 V < get_value({X, Y-1}, Table).
88
89 get_value({X,Y}, [H|_] = Table) when X == 0; Y == 0; Y > length(Table); X > length(H) -> 10;
90
91 get_value({X,Y}, Table) ->
92 lists:nth(X, lists:nth(Y, Table)).
93