-
Notifications
You must be signed in to change notification settings - Fork 0
/
sol07a.erl
executable file
·38 lines (31 loc) · 1.07 KB
/
sol07a.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#!/usr/bin/escript
main([]) ->
main(["sol07.data"]);
main([Filename]) ->
{ok, File} = file:read_file(Filename),
Lines = string:lexemes(File, "\r\n"),
Rules = lists:append([split_rules(L) || L <- Lines]),
SG = {<<"shiny">>, <<"gold">>},
Containers = find_containers_for(Rules, SG),
UniqCont = lists:usort(Containers),
io:format("~B~n", [length(UniqCont)]).
split_rules(Line0) ->
Line = lists:foldl(
fun (Match, Str) -> string:replace(Str, Match, <<>>, all) end,
string:chomp(Line0),
[<<"contain">>, <<"bags">>, <<"bag">>, <<",">>, <<".">>]),
Parts = string:lexemes(Line, " "),
[O1, O2 | AllInner] = Parts,
Outer = {O1, O2},
Inners = split_inners(AllInner),
[{Outer, N, Inner} || {N, Inner} <- Inners].
split_inners([]) ->
[];
split_inners([<<"no">>, <<"other">>]) ->
[];
split_inners([IN, I1, I2 | Rest]) ->
[{binary_to_integer(IN), {I1, I2}} | split_inners(Rest)].
find_containers_for(Rules, Colour) ->
Direct = [Cnt || {Cnt, _, C0} <- Rules, C0 =:= Colour],
Indirect = [find_containers_for(Rules, C) || C <- Direct],
Direct ++ lists:append(Indirect).