]> fbox.kageds.com Git - adventofcode.git/blob - 2021/day14/day14.erl
Day_1
[adventofcode.git] / 2021 / day14 / day14.erl
1 %% to compile: erlc day3A.erl
2 %% to run: erl -noshell -s day5 solve
3 %%
4 -module(day14).
5
6 -export ([solve/0, solve/1, solve/2]).
7 -export ([expand_pair/4, read_input/0]).
8 -compile ([export_all]).
9
10 solve() ->
11 solve(['1']),
12 solve(['2']),
13 init:stop().
14
15 solve(A) ->
16 solve(A, read_input()).
17
18 solve(['1'], D) ->
19 io:format("The solution to ~p puzzle1 is: ~p~n", [?MODULE, solve(1, D)]);
20 solve(1, D) ->
21 solution1(D);
22 solve(['2'], D) ->
23 io:format("The solution to ~p puzzle2 is: ~p~n", [?MODULE, solve(2, D)]);
24 solve(2, D) ->
25 solution2(D).
26
27 read_input() ->
28 {ok, IO} = file:open("input.txt", 'read'),
29 Data = read_input(IO),
30 file:close(IO),
31 Data.
32
33 read_input(IO) ->
34 read_input(IO, []).
35
36 read_input(IO, Input) ->
37 case read_line(IO) of
38 'eof' -> make_map(Input);
39 Line -> read_input(IO, Input ++ [Line])
40 end.
41
42 read_line(IO) ->
43 case file:read_line(IO) of
44 'eof' -> 'eof';
45 {ok, Line} -> parse_line(Line)
46 end.
47
48 parse_line(Line) ->
49 string:tokens(Line, " ->\n").
50
51 make_map(Input) -> make_map(Input, maps:new()).
52
53 make_map([], Map) -> Map;
54 make_map([[P, [Res]]|Rest], Map) ->
55 NewMap = maps:put(P, Res, Map),
56 make_map(Rest, NewMap).
57
58 solution1(PolyMap) ->
59 Ets = ets:new(polymer, [set, public, named_table]),
60 Polymer = "FNFPPNKPPHSOKFFHOFOC",
61 init_counters(Ets, PolyMap),
62 io:format("~p~n", [ets:tab2list(Ets)]),
63 Pairs = make_pairs(Polymer, []),
64 io:format("expand pairs: ~p~n",[Pairs]),
65 count_pairs(Pairs, Ets),
66 [count_elems(Pair, Ets, 1) || Pair <- Pairs],
67 loop(Ets, PolyMap, 10),
68 get_max_elm(Ets) - get_min_elm(Ets).
69
70 solution2(PolyMap) ->
71 Ets = ets:new(polymer, [set, public, named_table]),
72 Polymer = "FNFPPNKPPHSOKFFHOFOC",
73 init_counters(Ets, PolyMap),
74 io:format("~p~n", [ets:tab2list(Ets)]),
75 Pairs = make_pairs(Polymer, []),
76 io:format("expand pairs: ~p~n",[Pairs]),
77 count_pairs(Pairs, Ets),
78 [count_elems(Pair, Ets, 1) || Pair <- Pairs],
79 loop(Ets, PolyMap, 40),
80 get_max_elm(Ets) - get_min_elm(Ets).
81
82 get_max_elm(Ets) ->
83 Ents = ets:tab2list(Ets),
84 {V, _} = lists:max([{V,X} || {{elem, X},V} <- Ents]),
85 V.
86
87 get_min_elm(Ets) ->
88 Ents = ets:tab2list(Ets),
89 {V, _} = lists:min([{V,X} || {{elem, X},V} <- Ents]),
90 V.
91
92 loop(Ets, _PolyMap, 0) -> ets:tab2list(Ets);
93 loop(Ets, PolyMap, Count) ->
94 Counters = get_counters(Ets),
95 [update_ets(Ets, PolyMap, Counter) || Counter <- Counters],
96 loop(Ets, PolyMap, Count - 1).
97
98 init_counters(Ets, PolyMap) ->
99 maps:foreach(fun([X,Y] = Key, _Value) -> ets:insert(Ets, {{elem,X},0}), ets:insert(Ets, {{elem,Y},0}), ets:insert(Ets, {{pair, Key}, 0}) end, PolyMap).
100
101 update_ets(_Ets, _PolyMap, {_Key, 0}) -> ok;
102 update_ets(Ets, PolyMap, {[X,Y] = Key, Value}) ->
103 V = maps:get(Key, PolyMap),
104 count_pair([X,V],Ets, Value),
105 count_pair([V,Y],Ets, Value),
106 count_pair(Key,Ets, -1 * Value),
107 count_elem(V, Ets, Value).
108
109 get_counters(Ets) ->
110 Ents = ets:tab2list(Ets),
111 [{X,V} || {{pair, X},V} <- Ents].
112
113 make_pairs([_], Pairs) -> Pairs;
114 make_pairs([X,Y|Rest], Pairs) -> make_pairs([Y|Rest], [[X,Y]|Pairs]).
115
116 count_pairs([], _Ets) -> ok;
117 count_pairs([P|Rest], Ets) ->
118 count_pair(P, Ets, 1),
119 count_pairs(Rest, Ets).
120
121 count_pair(P, Ets, V) ->
122 ets:update_counter(Ets, {pair,P}, {2,V}).
123
124 count_elems([X,Y], Ets, V) ->
125 count_elem(X, Ets, V),
126 count_elem(Y, Ets, V).
127
128 count_elem(Elem, Ets, V) ->
129 ets:update_counter(Ets, {elem,Elem}, {2,V}).
130
131 expand_pair(_P, _PolyMap, _Ets, 0) -> ok;
132 expand_pair([P1,P2], PolyMap, Ets, Count) when is_list(P1), is_list(P2) ->
133 expand_pair(P1,PolyMap, Ets, Count - 1);
134 expand_pair([X,Y] = P, PolyMap, Ets, Count) ->
135 [V] = maps:get(P, PolyMap),
136 ets:update_counter(Ets, [V], {2,1}),
137 [expand_pair(Pa, PolyMap, Ets, Count) || Pa <- [[X,V]] ++ [[V,Y]]].
138
139
140 pairs([], _PolyMap, Pairs, _Ets, 0) ->
141 Pairs;
142 pairs([], PolyMap, Pairs, Ets, Count) ->
143 io:format("new pairs: ~p~n", [Pairs]),
144 pairs(Pairs, PolyMap, [], Ets, Count - 1);
145 pairs([[X,Y] = P|Rest], PolyMap, Pairs, Ets, Count) ->
146 [V] = maps:get(P, PolyMap),
147 ets:update_counter(Ets, [V], {2,1}),
148 pairs(Rest, PolyMap, Pairs ++ [[X,V]] ++ [[V,Y]], Ets, Count).
149
150 count(Polymer) ->
151 Ps = lists:usort(Polymer),
152 [ {count_p(P, Polymer), [P]} || P <- Ps].
153
154 count_p(P, Polymer) ->
155 lists:foldl(fun(X, Acc) -> case X == P of 'true' -> Acc + 1; _ -> Acc end end, 0, Polymer).
156
157 steps(Polymer, _PolyMap, 0) -> Polymer;
158 steps(Polymer, PolyMap, Count) ->
159 Insert = get_insert_list(Polymer, PolyMap),
160 steps(lists:flatten(lists:zipwith(fun(A, B) -> [A,B] end, Polymer, Insert)), PolyMap, Count - 1).
161
162 get_insert_list(Polymer, PolyMap) ->
163 get_insert_list(Polymer, PolyMap, []).
164
165 get_insert_list([_], _PolyMap, InsertList) -> lists:reverse([[]|InsertList]);
166 get_insert_list([P1,P2|Rest], PolyMap, InsertList) ->
167 V = maps:get([P1,P2], PolyMap),
168 get_insert_list([P2|Rest], PolyMap, [V|InsertList]).