]> fbox.kageds.com Git - adventofcode.git/blob - 2021/day11/day11.erl
move unit64 back to int
[adventofcode.git] / 2021 / day11 / day11.erl
1 %% to compile: erlc day3A.erl
2 %% to run: erl -noshell -s day3 solve
3 %%
4 -module(day11).
5
6 -export ([solve/0, solve/1, solve/2]).
7 -export ([read_input/0]).
8
9 -compile([export_all]).
10
11 solve() ->
12 solve(['1']),
13 solve(['2']),
14 init:stop().
15
16 solve(A) ->
17 solve(A, read_input()).
18
19 solve(['1'], D) ->
20 io:format("The solution to ~p puzzle1 is: ~p~n", [?MODULE, solve(1, D)]);
21 solve(1, D) ->
22 solution1(D);
23 solve(['2'], D) ->
24 io:format("The solution to ~p puzzle2 is: ~p~n", [?MODULE, solve(2, D)]);
25 solve(2, D) ->
26 solution2(D).
27
28 read_input() ->
29 {ok, IO} = file:open("input.txt", 'read'),
30 Data = read_input(IO),
31 file:close(IO),
32 Data.
33
34 read_input(IO) ->
35 read_input(IO, []).
36
37 read_input(IO, Input) ->
38 case read_line(IO) of
39 'eof' -> Input;
40 Line -> read_input(IO, Input ++ [Line])
41 end.
42
43 read_line(IO) ->
44 case file:read_line(IO) of
45 'eof' -> 'eof';
46 {ok, Line} -> [ X - $0 || X <- Line, [X] /= "\n"]
47 end.
48
49 solution1(Input) ->
50 Coords = coords(Input),
51 Data = [ {X, init_data(X, Input)} || X <- Coords],
52 put(flash, 0),
53 sn1_step(Data, 0),
54 get(flash).
55
56 sn1_step(Data, 100) -> Data;
57 sn1_step(Data, Count) ->
58 Step1 = step1(Data),
59 Step2 = step2(Step1),
60 sn1_step(Step2, Count + 1).
61
62 solution2(Input) ->
63 Coords = coords(Input),
64 Data = [ {X, init_data(X, Input)} || X <- Coords],
65 put(flash, 0),
66 sn2_step(Data, 0).
67
68 sn2_step(Data, Count) ->
69 Step1 = step1(Data),
70 Step2 = step2(Step1),
71 case all_flash(Step2) of
72 'true'-> Count + 1;
73 'false' -> sn2_step(Step2, Count + 1)
74 end.
75
76 all_flash(Data) ->
77 lists:all(fun({_,V}) -> V == 0 end, Data).
78
79 coords([H|_] = Table) ->
80 X = length(H),
81 Y = length(Table),
82 lists:flatten([[{A,B} || A <- lists:seq(1,X)] || B <- lists:seq(1,Y)]).
83
84
85 step1(Data) ->
86 lists:map(fun({C, X}) -> case X of 9 -> incr_flash(), {C, 'flash'}; _ -> {C, X + 1} end end, Data).
87
88 step2(Data) ->
89 case is_flash(Data) of
90 'true' -> flash(Data);
91 'false' -> clear_flashed(Data)
92 end.
93
94 is_flash(Data) ->
95 lists:any(fun({_, X}) -> X == 'flash' end, Data).
96
97 flash(Data) ->
98 NewData = flash(Data, Data),
99 step2(flashed(Data, NewData)).
100
101 flash([], Acc) -> Acc;
102 flash([{{X,Y},V}|T], Acc) when V == 'flash' ->
103 flash(T, increase_neighbors({X,Y}, Acc));
104 flash([_|T], Acc) -> flash(T, Acc).
105
106 clear_flashed(Data) ->
107 clear_flashed(Data, []).
108
109 clear_flashed([], Acc) -> lists:reverse(Acc);
110 clear_flashed([{C, V}|T], Acc) when V == 'flashed' ->
111 clear_flashed(T, [{C, 0}|Acc]);
112 clear_flashed([H|T], Acc) ->
113 clear_flashed(T, [H|Acc]).
114
115
116 flashed(OldData, NewData) ->
117 lists:zipwith(fun({C, V}, N) -> case V of 'flash' -> {C, 'flashed'}; _ -> N end end, OldData, NewData).
118
119 increase_neighbors({X,Y}, Data) ->
120 Neigbours = [{X+1,Y},{X-1,Y},{X,Y+1},{X,Y-1},{X+1,Y+1},{X+1,Y-1},{X-1,Y+1},{X-1,Y-1}],
121 increase_neighbor(Neigbours, Data).
122
123 increase_neighbor([], Data) -> Data;
124 increase_neighbor([{X,Y}|T], Data) when X < 1; Y < 1; X > 10; Y > 10 -> io:format("ignore: ~p~n",[{X,Y}]), increase_neighbor(T,Data);
125 increase_neighbor([H|T], Data) ->
126 case get_value(H, Data) of
127 'flash' -> increase_neighbor(T, Data);
128 'flashed' -> increase_neighbor(T, Data);
129 9 -> incr_flash(), increase_neighbor(T, set_value(H, Data, 'flash'));
130 V -> increase_neighbor(T, set_value(H, Data, V + 1))
131 end.
132
133 get_value(C, Table) ->
134 {C, V} = lists:keyfind(C, 1, Table),
135 V.
136
137 set_value(C, Table, V) ->
138 lists:keyreplace(C, 1, Table, {C, V}).
139
140 init_data({X,Y}, Table) ->
141 lists:nth(X, lists:nth(Y, Table)).
142
143 incr_flash() ->
144 put(flash, get(flash) + 1).