Advent of Code Solutions
advent-of-code
aoc
1#!/usr/bin/env escript
2-mode(compile).
3
4% --- Part 1 Code
5part1(Input) -> io:format("Part 1: ~b~n", [count_lit_lights(Input, #{})]).
6
7generate_coordinates({XStart, YStart}, {XEnd, YEnd}) ->
8 [{X, Y} || X <- lists:seq(XStart, XEnd), Y <- lists:seq(YStart, YEnd)].
9
10generate_map(Coords, Value) -> maps:from_list([{Coord, Value} || Coord <- Coords]).
11
12perform_instruction(toggle, Coords, Map) ->
13 maps:merge_with(
14 fun(_, Current, _) ->
15 case Current of
16 0 -> 1;
17 1 -> 0
18 end
19 end,
20 Map,
21 generate_map(Coords, 1)
22 );
23perform_instruction(Action, Coords, Map) ->
24 maps:merge(
25 Map,
26 case Action of
27 on -> generate_map(Coords, 1);
28 off -> generate_map(Coords, 0)
29 end
30 ).
31
32count_lit_lights([], Map) ->
33 maps:fold(fun(_, Value, Accumulator) -> Accumulator + Value end, 0, Map);
34count_lit_lights([{Action, Start, End} | Instructions], Map) ->
35 count_lit_lights(
36 Instructions,
37 perform_instruction(Action, generate_coordinates(Start, End), Map)
38 ).
39
40% --- Part 2 Code
41part2(Input) -> io:format("Part 2: ~b~n", [calculate_brightness(Input, #{})]).
42
43perform_instruction2(off, Coords, Map) ->
44 maps:merge_with(
45 fun(_, Current, _) ->
46 case Current of
47 Current when Current > 0 -> Current - 1;
48 Current -> 0
49 end
50 end,
51 Map,
52 generate_map(Coords, 0)
53 );
54perform_instruction2(Action, Coords, Map) ->
55 maps:merge_with(
56 fun(_, Current, New) -> Current + New end,
57 Map,
58 case Action of
59 toggle -> generate_map(Coords, 2);
60 on -> generate_map(Coords, 1)
61 end
62 ).
63
64calculate_brightness([], Map) ->
65 maps:fold(fun(_, Value, Accumulator) -> Accumulator + Value end, 0, Map);
66calculate_brightness([{Action, Start, End} | Instructions], Map) ->
67 calculate_brightness(
68 Instructions,
69 perform_instruction2(Action, generate_coordinates(Start, End), Map)
70 ).
71
72% --- Read Input
73split_coordinate(Coordinate) ->
74 [X, Y] = string:split(Coordinate, ","),
75 {Xint, _} = string:to_integer(X),
76 {Yint, _} = string:to_integer(Y),
77 {Xint, Yint}.
78
79parse_line(Data) ->
80 case string:split(string:trim(Data), " ", all) of
81 ["toggle", Start, _, End] -> {toggle, split_coordinate(Start), split_coordinate(End)};
82 ["turn", "on", Start, _, End] -> {on, split_coordinate(Start), split_coordinate(End)};
83 ["turn", "off", Start, _, End] -> {off, split_coordinate(Start), split_coordinate(End)}
84 end.
85
86read_input() -> read_input("").
87read_input(Prev) ->
88 case io:get_line("") of
89 eof -> Prev;
90 {error, _} -> halt(1);
91 Data when Prev == "" -> read_input([parse_line(Data)]);
92 Data -> read_input(Prev ++ [parse_line(Data)])
93 end.
94
95main(Args) ->
96 Input = read_input(),
97 case Args of
98 ["1"] ->
99 part1(Input);
100 ["2"] ->
101 part2(Input);
102 _ ->
103 part1(Input),
104 part2(Input)
105 end.