-51
2015/01/solution.erl
-51
2015/01/solution.erl
···
1
-
#!/usr/bin/env escript
2
-
3
-
% --- Part 1 Code
4
-
part1(Input) ->
5
-
io:format("Part 1: ~b~n", [destination(0, Input)]).
6
-
7
-
destination(Floor, Input) ->
8
-
case {_, Rest} = next_char(Input) of
9
-
{"(", _} -> destination(Floor + 1, Rest);
10
-
{")", _} -> destination(Floor - 1, Rest);
11
-
{"\n", _} -> Floor
12
-
end.
13
-
14
-
% --- Part 2 Code
15
-
part2(Input) ->
16
-
io:format("Part 2: ~b~n", [basement_enter(0, 0, Input)]).
17
-
18
-
basement_enter(Position, Floor, Input) ->
19
-
if
20
-
Floor == -1 ->
21
-
Position;
22
-
true ->
23
-
case {_, Rest} = next_char(Input) of
24
-
{"(", _} -> basement_enter(Position + 1, Floor + 1, Rest);
25
-
{")", _} -> basement_enter(Position + 1, Floor - 1, Rest);
26
-
% If we get here, our puzzle input is impossible
27
-
{"\n", _} -> halt(1)
28
-
end
29
-
end.
30
-
31
-
% --- Generic Helper Functions
32
-
next_char([Char | String]) -> {[Char], String}.
33
-
34
-
read_input() -> read_input("").
35
-
read_input(PrevLine) ->
36
-
case io:get_chars("", 8192) of
37
-
eof -> PrevLine;
38
-
Data -> read_input(PrevLine ++ Data)
39
-
end.
40
-
41
-
main(Args) ->
42
-
Input = read_input(),
43
-
case Args of
44
-
["1"] ->
45
-
part1(Input);
46
-
["2"] ->
47
-
part2(Input);
48
-
_ ->
49
-
part1(Input),
50
-
part2(Input)
51
-
end.
+52
2015/01/solution.escript
+52
2015/01/solution.escript
···
1
+
#!/usr/bin/env escript
2
+
-mode(compile).
3
+
4
+
% --- Part 1 Code
5
+
part1(Input) ->
6
+
io:format("Part 1: ~b~n", [destination(0, Input)]).
7
+
8
+
destination(Floor, Input) ->
9
+
case {_, Rest} = next_char(Input) of
10
+
{"(", _} -> destination(Floor + 1, Rest);
11
+
{")", _} -> destination(Floor - 1, Rest);
12
+
{"\n", _} -> Floor
13
+
end.
14
+
15
+
% --- Part 2 Code
16
+
part2(Input) ->
17
+
io:format("Part 2: ~b~n", [basement_enter(0, 0, Input)]).
18
+
19
+
basement_enter(Position, Floor, Input) ->
20
+
if
21
+
Floor == -1 ->
22
+
Position;
23
+
true ->
24
+
case {_, Rest} = next_char(Input) of
25
+
{"(", _} -> basement_enter(Position + 1, Floor + 1, Rest);
26
+
{")", _} -> basement_enter(Position + 1, Floor - 1, Rest);
27
+
% If we get here, our puzzle input is impossible
28
+
{"\n", _} -> halt(1)
29
+
end
30
+
end.
31
+
32
+
% --- Generic Helper Functions
33
+
next_char([Char | String]) -> {[Char], String}.
34
+
35
+
read_input() -> read_input("").
36
+
read_input(PrevLine) ->
37
+
case io:get_chars("", 8192) of
38
+
eof -> PrevLine;
39
+
Data -> read_input(PrevLine ++ Data)
40
+
end.
41
+
42
+
main(Args) ->
43
+
Input = read_input(),
44
+
case Args of
45
+
["1"] ->
46
+
part1(Input);
47
+
["2"] ->
48
+
part2(Input);
49
+
_ ->
50
+
part1(Input),
51
+
part2(Input)
52
+
end.
-59
2015/02/solution.erl
-59
2015/02/solution.erl
···
1
-
#!/usr/bin/env escript
2
-
3
-
% --- Part 1 Code
4
-
part1(Input) ->
5
-
io:format("Part 1: ~b~n", [calculate_wpaper(0, Input)]).
6
-
7
-
calculate_wpaper(Total, [Dimension | Dimensions]) ->
8
-
[Length, Width, Height] = lists:map(
9
-
fun(Num) ->
10
-
{Int, _} = string:to_integer(Num),
11
-
Int
12
-
end,
13
-
string:tokens(Dimension, "x")
14
-
),
15
-
SurfaceArea = (2 * Length * Width) + (2 * Width * Height) + (2 * Height * Length),
16
-
[MinOne, MinTwo, _] = lists:sort([Length, Width, Height]),
17
-
calculate_wpaper(Total + (SurfaceArea + (MinOne * MinTwo)), Dimensions);
18
-
calculate_wpaper(Total, []) ->
19
-
Total.
20
-
21
-
% --- Part 2 Code
22
-
part2(Input) ->
23
-
io:format("Part 2: ~b~n", [calculate_ribbon(0, Input)]).
24
-
25
-
calculate_ribbon(Total, [Dimension | Dimensions]) ->
26
-
[Length, Width, Height] = lists:map(
27
-
fun(Num) ->
28
-
{Int, _} = string:to_integer(Num),
29
-
Int
30
-
end,
31
-
string:tokens(Dimension, "x")
32
-
),
33
-
[MinOne, MinTwo, _] = lists:sort([Length, Width, Height]),
34
-
Perimeter = (2 * MinOne) + (2 * MinTwo),
35
-
CubicVolume = Length * Width * Height,
36
-
calculate_ribbon(Total + (Perimeter + CubicVolume), Dimensions);
37
-
calculate_ribbon(Total, []) ->
38
-
Total.
39
-
40
-
% --- Generic Helper Functions
41
-
read_input() -> read_input("").
42
-
read_input(PrevLine) ->
43
-
case io:fread("", "~s") of
44
-
eof -> PrevLine;
45
-
{error, _} -> halt(1);
46
-
{ok, Terms} -> read_input(PrevLine ++ Terms)
47
-
end.
48
-
49
-
main(Args) ->
50
-
Input = read_input(),
51
-
case Args of
52
-
["1"] ->
53
-
part1(Input);
54
-
["2"] ->
55
-
part2(Input);
56
-
_ ->
57
-
part1(Input),
58
-
part2(Input)
59
-
end.
+60
2015/02/solution.escript
+60
2015/02/solution.escript
···
1
+
#!/usr/bin/env escript
2
+
-mode(compile).
3
+
4
+
% --- Part 1 Code
5
+
part1(Input) ->
6
+
io:format("Part 1: ~b~n", [calculate_wpaper(0, Input)]).
7
+
8
+
calculate_wpaper(Total, [Dimension | Dimensions]) ->
9
+
[Length, Width, Height] = lists:map(
10
+
fun(Num) ->
11
+
{Int, _} = string:to_integer(Num),
12
+
Int
13
+
end,
14
+
string:tokens(Dimension, "x")
15
+
),
16
+
SurfaceArea = (2 * Length * Width) + (2 * Width * Height) + (2 * Height * Length),
17
+
[MinOne, MinTwo, _] = lists:sort([Length, Width, Height]),
18
+
calculate_wpaper(Total + (SurfaceArea + (MinOne * MinTwo)), Dimensions);
19
+
calculate_wpaper(Total, []) ->
20
+
Total.
21
+
22
+
% --- Part 2 Code
23
+
part2(Input) ->
24
+
io:format("Part 2: ~b~n", [calculate_ribbon(0, Input)]).
25
+
26
+
calculate_ribbon(Total, [Dimension | Dimensions]) ->
27
+
[Length, Width, Height] = lists:map(
28
+
fun(Num) ->
29
+
{Int, _} = string:to_integer(Num),
30
+
Int
31
+
end,
32
+
string:tokens(Dimension, "x")
33
+
),
34
+
[MinOne, MinTwo, _] = lists:sort([Length, Width, Height]),
35
+
Perimeter = (2 * MinOne) + (2 * MinTwo),
36
+
CubicVolume = Length * Width * Height,
37
+
calculate_ribbon(Total + (Perimeter + CubicVolume), Dimensions);
38
+
calculate_ribbon(Total, []) ->
39
+
Total.
40
+
41
+
% --- Generic Helper Functions
42
+
read_input() -> read_input("").
43
+
read_input(PrevLine) ->
44
+
case io:fread("", "~s") of
45
+
eof -> PrevLine;
46
+
{error, _} -> halt(1);
47
+
{ok, Terms} -> read_input(PrevLine ++ Terms)
48
+
end.
49
+
50
+
main(Args) ->
51
+
Input = read_input(),
52
+
case Args of
53
+
["1"] ->
54
+
part1(Input);
55
+
["2"] ->
56
+
part2(Input);
57
+
_ ->
58
+
part1(Input),
59
+
part2(Input)
60
+
end.
-85
2015/03/solution.erl
-85
2015/03/solution.erl
···
1
-
#!/usr/bin/env escript
2
-
3
-
% --- Part 1 Code
4
-
part1(Input) ->
5
-
InitialPosition = {0, 0},
6
-
InitialMap = #{InitialPosition => 1},
7
-
io:format("Part 1: ~b~n", [
8
-
length(maps:keys(process_instructions(InitialMap, InitialPosition, Input)))
9
-
]).
10
-
11
-
visit_house(HouseMap, Position) ->
12
-
CurrentValue = maps:get(Position, HouseMap, 0),
13
-
maps:put(Position, CurrentValue + 1, HouseMap).
14
-
15
-
process_instructions(HouseMap, _, "\n") ->
16
-
HouseMap;
17
-
process_instructions(HouseMap, Position, Input) ->
18
-
{CurrentX, CurrentY} = Position,
19
-
NewPos =
20
-
case {_, Rest} = next_char(Input) of
21
-
{"^", _} -> {CurrentX, CurrentY + 1};
22
-
{"<", _} -> {CurrentX - 1, CurrentY};
23
-
{"v", _} -> {CurrentX, CurrentY - 1};
24
-
{">", _} -> {CurrentX + 1, CurrentY}
25
-
end,
26
-
process_instructions(visit_house(HouseMap, NewPos), NewPos, Rest).
27
-
28
-
% --- Part 2 Code
29
-
part2(Input) ->
30
-
InitialPositionMap = #{santa => {0, 0}, robo_santa => {0, 0}},
31
-
InitialMap = #{{0, 0} => 2},
32
-
Mover = santa,
33
-
io:format("Part 2: ~b~n", [
34
-
length(maps:keys(process_instructions(InitialMap, InitialPositionMap, Mover, Input)))
35
-
]).
36
-
37
-
update_position(PositionMap, Mover, Movement) ->
38
-
{CurrentX, CurrentY} = maps:get(Mover, PositionMap),
39
-
case Movement of
40
-
up -> maps:put(Mover, {CurrentX, CurrentY + 1}, PositionMap);
41
-
left -> maps:put(Mover, {CurrentX - 1, CurrentY}, PositionMap);
42
-
down -> maps:put(Mover, {CurrentX, CurrentY - 1}, PositionMap);
43
-
right -> maps:put(Mover, {CurrentX + 1, CurrentY}, PositionMap)
44
-
end.
45
-
46
-
process_instructions(HouseMap, _, _, "\n") ->
47
-
HouseMap;
48
-
process_instructions(HouseMap, PositionMap, Mover, Input) ->
49
-
NextMover =
50
-
case Mover of
51
-
santa -> robo_santa;
52
-
robo_santa -> santa
53
-
end,
54
-
NewPosMap =
55
-
case {_, Rest} = next_char(Input) of
56
-
{"^", _} -> update_position(PositionMap, Mover, up);
57
-
{"<", _} -> update_position(PositionMap, Mover, left);
58
-
{"v", _} -> update_position(PositionMap, Mover, down);
59
-
{">", _} -> update_position(PositionMap, Mover, right)
60
-
end,
61
-
process_instructions(
62
-
visit_house(HouseMap, maps:get(Mover, NewPosMap)), NewPosMap, NextMover, Rest
63
-
).
64
-
65
-
% --- Generic Helper Functions
66
-
next_char([Char | String]) -> {[Char], String}.
67
-
68
-
read_input() -> read_input("").
69
-
read_input(PrevLine) ->
70
-
case io:get_chars("", 8192) of
71
-
eof -> PrevLine;
72
-
Data -> read_input(PrevLine ++ Data)
73
-
end.
74
-
75
-
main(Args) ->
76
-
Input = read_input(),
77
-
case Args of
78
-
["1"] ->
79
-
part1(Input);
80
-
["2"] ->
81
-
part2(Input);
82
-
_ ->
83
-
part1(Input),
84
-
part2(Input)
85
-
end.
+86
2015/03/solution.escript
+86
2015/03/solution.escript
···
1
+
#!/usr/bin/env escript
2
+
-mode(compile).
3
+
4
+
% --- Part 1 Code
5
+
part1(Input) ->
6
+
InitialPosition = {0, 0},
7
+
InitialMap = #{InitialPosition => 1},
8
+
io:format("Part 1: ~b~n", [
9
+
length(maps:keys(process_instructions(InitialMap, InitialPosition, Input)))
10
+
]).
11
+
12
+
visit_house(HouseMap, Position) ->
13
+
CurrentValue = maps:get(Position, HouseMap, 0),
14
+
maps:put(Position, CurrentValue + 1, HouseMap).
15
+
16
+
process_instructions(HouseMap, _, "\n") ->
17
+
HouseMap;
18
+
process_instructions(HouseMap, Position, Input) ->
19
+
{CurrentX, CurrentY} = Position,
20
+
NewPos =
21
+
case {_, Rest} = next_char(Input) of
22
+
{"^", _} -> {CurrentX, CurrentY + 1};
23
+
{"<", _} -> {CurrentX - 1, CurrentY};
24
+
{"v", _} -> {CurrentX, CurrentY - 1};
25
+
{">", _} -> {CurrentX + 1, CurrentY}
26
+
end,
27
+
process_instructions(visit_house(HouseMap, NewPos), NewPos, Rest).
28
+
29
+
% --- Part 2 Code
30
+
part2(Input) ->
31
+
InitialPositionMap = #{santa => {0, 0}, robo_santa => {0, 0}},
32
+
InitialMap = #{{0, 0} => 2},
33
+
Mover = santa,
34
+
io:format("Part 2: ~b~n", [
35
+
length(maps:keys(process_instructions(InitialMap, InitialPositionMap, Mover, Input)))
36
+
]).
37
+
38
+
update_position(PositionMap, Mover, Movement) ->
39
+
{CurrentX, CurrentY} = maps:get(Mover, PositionMap),
40
+
case Movement of
41
+
up -> maps:put(Mover, {CurrentX, CurrentY + 1}, PositionMap);
42
+
left -> maps:put(Mover, {CurrentX - 1, CurrentY}, PositionMap);
43
+
down -> maps:put(Mover, {CurrentX, CurrentY - 1}, PositionMap);
44
+
right -> maps:put(Mover, {CurrentX + 1, CurrentY}, PositionMap)
45
+
end.
46
+
47
+
process_instructions(HouseMap, _, _, "\n") ->
48
+
HouseMap;
49
+
process_instructions(HouseMap, PositionMap, Mover, Input) ->
50
+
NextMover =
51
+
case Mover of
52
+
santa -> robo_santa;
53
+
robo_santa -> santa
54
+
end,
55
+
NewPosMap =
56
+
case {_, Rest} = next_char(Input) of
57
+
{"^", _} -> update_position(PositionMap, Mover, up);
58
+
{"<", _} -> update_position(PositionMap, Mover, left);
59
+
{"v", _} -> update_position(PositionMap, Mover, down);
60
+
{">", _} -> update_position(PositionMap, Mover, right)
61
+
end,
62
+
process_instructions(
63
+
visit_house(HouseMap, maps:get(Mover, NewPosMap)), NewPosMap, NextMover, Rest
64
+
).
65
+
66
+
% --- Generic Helper Functions
67
+
next_char([Char | String]) -> {[Char], String}.
68
+
69
+
read_input() -> read_input("").
70
+
read_input(PrevLine) ->
71
+
case io:get_chars("", 8192) of
72
+
eof -> PrevLine;
73
+
Data -> read_input(PrevLine ++ Data)
74
+
end.
75
+
76
+
main(Args) ->
77
+
Input = read_input(),
78
+
case Args of
79
+
["1"] ->
80
+
part1(Input);
81
+
["2"] ->
82
+
part2(Input);
83
+
_ ->
84
+
part1(Input),
85
+
part2(Input)
86
+
end.
-41
2015/04/solution.erl
-41
2015/04/solution.erl
···
1
-
#!/usr/bin/env escript
2
-
3
-
% --- Part 1 Code
4
-
part1(Input) ->
5
-
io:format("Part 1: ~b~n", [find_hash_with_prefix("00000", Input)]).
6
-
7
-
find_hash_with_prefix(PrefixMatch, Input) ->
8
-
find_hash_with_prefix(PrefixMatch, Input, 0).
9
-
find_hash_with_prefix(PrefixMatch, Input, CurrentNumber) ->
10
-
Hash = binary:encode_hex(crypto:hash(md5, [Input, integer_to_list(CurrentNumber)])),
11
-
Prefix = string:slice(binary_to_list(Hash), 0, length(PrefixMatch)),
12
-
13
-
if
14
-
Prefix == PrefixMatch -> CurrentNumber;
15
-
true -> find_hash_with_prefix(PrefixMatch, Input, CurrentNumber + 1)
16
-
end.
17
-
18
-
% --- Part 2 Code
19
-
part2(Input) ->
20
-
io:format("Part 2: ~b~n", [find_hash_with_prefix("000000", Input)]).
21
-
22
-
% --- Generic Helper Functions
23
-
read_input() -> read_input("").
24
-
read_input(PrevLine) ->
25
-
case io:fread("", "~s") of
26
-
eof -> PrevLine;
27
-
{error, _} -> halt(1);
28
-
{ok, Terms} -> read_input(PrevLine ++ Terms)
29
-
end.
30
-
31
-
main(Args) ->
32
-
Input = read_input(),
33
-
case Args of
34
-
["1"] ->
35
-
part1(Input);
36
-
["2"] ->
37
-
part2(Input);
38
-
_ ->
39
-
part1(Input),
40
-
part2(Input)
41
-
end.
+42
2015/04/solution.escript
+42
2015/04/solution.escript
···
1
+
#!/usr/bin/env escript
2
+
-mode(compile).
3
+
4
+
% --- Part 1 Code
5
+
part1(Input) ->
6
+
io:format("Part 1: ~b~n", [find_hash_with_prefix("00000", Input)]).
7
+
8
+
find_hash_with_prefix(PrefixMatch, Input) ->
9
+
find_hash_with_prefix(PrefixMatch, Input, 0).
10
+
find_hash_with_prefix(PrefixMatch, Input, CurrentNumber) ->
11
+
Hash = binary:encode_hex(crypto:hash(md5, [Input, integer_to_list(CurrentNumber)])),
12
+
Prefix = string:slice(binary_to_list(Hash), 0, length(PrefixMatch)),
13
+
14
+
if
15
+
Prefix == PrefixMatch -> CurrentNumber;
16
+
true -> find_hash_with_prefix(PrefixMatch, Input, CurrentNumber + 1)
17
+
end.
18
+
19
+
% --- Part 2 Code
20
+
part2(Input) ->
21
+
io:format("Part 2: ~b~n", [find_hash_with_prefix("000000", Input)]).
22
+
23
+
% --- Generic Helper Functions
24
+
read_input() -> read_input("").
25
+
read_input(PrevLine) ->
26
+
case io:fread("", "~s") of
27
+
eof -> PrevLine;
28
+
{error, _} -> halt(1);
29
+
{ok, Terms} -> read_input(PrevLine ++ Terms)
30
+
end.
31
+
32
+
main(Args) ->
33
+
Input = read_input(),
34
+
case Args of
35
+
["1"] ->
36
+
part1(Input);
37
+
["2"] ->
38
+
part2(Input);
39
+
_ ->
40
+
part1(Input),
41
+
part2(Input)
42
+
end.
-113
2015/05/solution.erl
-113
2015/05/solution.erl
···
1
-
#!/usr/bin/env escript
2
-
3
-
% --- Part 1 Code
4
-
part1(Input) ->
5
-
io:format("Part 1: ~b~n", [count_nice_strings(Input, 0)]).
6
-
7
-
count_vowels(String) ->
8
-
lists:foldl(
9
-
fun(Char, Total) ->
10
-
case lists:member(Char, "aeiou") of
11
-
true -> Total + 1;
12
-
false -> Total
13
-
end
14
-
end,
15
-
0,
16
-
String
17
-
).
18
-
19
-
has_consecutive_characters([_ | []]) ->
20
-
false;
21
-
has_consecutive_characters(String) ->
22
-
[First, Second | Rest] = String,
23
-
case First == Second of
24
-
true -> true;
25
-
false -> has_consecutive_characters([Second] ++ Rest)
26
-
end.
27
-
28
-
has_forbidden_pattern(String, Pattern) ->
29
-
case string:find(String, Pattern) of
30
-
nomatch -> false;
31
-
_ -> true
32
-
end.
33
-
34
-
is_nice_string(String) ->
35
-
maybe
36
-
true ?= count_vowels(String) >= 3,
37
-
true ?= has_consecutive_characters(String),
38
-
true ?= has_forbidden_pattern(String, "ab") == false,
39
-
true ?= has_forbidden_pattern(String, "cd") == false,
40
-
true ?= has_forbidden_pattern(String, "pq") == false,
41
-
true ?= has_forbidden_pattern(String, "xy") == false
42
-
end.
43
-
44
-
count_nice_strings([], Total) ->
45
-
Total;
46
-
count_nice_strings([Head | Rest], Total) ->
47
-
case is_nice_string(Head) of
48
-
true -> count_nice_strings(Rest, Total + 1);
49
-
false -> count_nice_strings(Rest, Total)
50
-
end.
51
-
52
-
% --- Part 2 Code
53
-
part2(Input) ->
54
-
io:format("Part 2: ~b~n", [count_nice_strings2(Input, 0)]).
55
-
56
-
has_pattern(String, Pattern) ->
57
-
case string:find(String, Pattern) of
58
-
nomatch -> false;
59
-
_ -> true
60
-
end.
61
-
62
-
has_duplicate_pattern([_ | []]) ->
63
-
false;
64
-
has_duplicate_pattern(String) ->
65
-
[First, Second | Rest] = String,
66
-
case has_pattern(Rest, [First, Second]) of
67
-
true -> true;
68
-
false -> has_duplicate_pattern([Second] ++ Rest)
69
-
end.
70
-
71
-
has_repeating_with_interrupt([_, _ | []]) ->
72
-
false;
73
-
has_repeating_with_interrupt(String) ->
74
-
[Start, Middle, End | Rest] = String,
75
-
case Start == End of
76
-
true -> true;
77
-
false -> has_repeating_with_interrupt([Middle, End] ++ Rest)
78
-
end.
79
-
80
-
is_nice_string2(String) ->
81
-
maybe
82
-
true ?= has_duplicate_pattern(String),
83
-
true ?= has_repeating_with_interrupt(String)
84
-
end.
85
-
86
-
count_nice_strings2([], Total) ->
87
-
Total;
88
-
count_nice_strings2([Head | Rest], Total) ->
89
-
case is_nice_string2(Head) of
90
-
true -> count_nice_strings2(Rest, Total + 1);
91
-
false -> count_nice_strings2(Rest, Total)
92
-
end.
93
-
94
-
% --- Generic Helper Functions
95
-
read_input() -> read_input("").
96
-
read_input(PrevLine) ->
97
-
case io:fread("", "~s") of
98
-
eof -> PrevLine;
99
-
{error, _} -> halt(1);
100
-
{ok, Terms} -> read_input(PrevLine ++ Terms)
101
-
end.
102
-
103
-
main(Args) ->
104
-
Input = read_input(),
105
-
case Args of
106
-
["1"] ->
107
-
part1(Input);
108
-
["2"] ->
109
-
part2(Input);
110
-
_ ->
111
-
part1(Input),
112
-
part2(Input)
113
-
end.
+114
2015/05/solution.escript
+114
2015/05/solution.escript
···
1
+
#!/usr/bin/env escript
2
+
-mode(compile).
3
+
4
+
% --- Part 1 Code
5
+
part1(Input) ->
6
+
io:format("Part 1: ~b~n", [count_nice_strings(Input, 0)]).
7
+
8
+
count_vowels(String) ->
9
+
lists:foldl(
10
+
fun(Char, Total) ->
11
+
case lists:member(Char, "aeiou") of
12
+
true -> Total + 1;
13
+
false -> Total
14
+
end
15
+
end,
16
+
0,
17
+
String
18
+
).
19
+
20
+
has_consecutive_characters([_ | []]) ->
21
+
false;
22
+
has_consecutive_characters(String) ->
23
+
[First, Second | Rest] = String,
24
+
case First == Second of
25
+
true -> true;
26
+
false -> has_consecutive_characters([Second] ++ Rest)
27
+
end.
28
+
29
+
has_forbidden_pattern(String, Pattern) ->
30
+
case string:find(String, Pattern) of
31
+
nomatch -> false;
32
+
_ -> true
33
+
end.
34
+
35
+
is_nice_string(String) ->
36
+
maybe
37
+
true ?= count_vowels(String) >= 3,
38
+
true ?= has_consecutive_characters(String),
39
+
true ?= has_forbidden_pattern(String, "ab") == false,
40
+
true ?= has_forbidden_pattern(String, "cd") == false,
41
+
true ?= has_forbidden_pattern(String, "pq") == false,
42
+
true ?= has_forbidden_pattern(String, "xy") == false
43
+
end.
44
+
45
+
count_nice_strings([], Total) ->
46
+
Total;
47
+
count_nice_strings([Head | Rest], Total) ->
48
+
case is_nice_string(Head) of
49
+
true -> count_nice_strings(Rest, Total + 1);
50
+
false -> count_nice_strings(Rest, Total)
51
+
end.
52
+
53
+
% --- Part 2 Code
54
+
part2(Input) ->
55
+
io:format("Part 2: ~b~n", [count_nice_strings2(Input, 0)]).
56
+
57
+
has_pattern(String, Pattern) ->
58
+
case string:find(String, Pattern) of
59
+
nomatch -> false;
60
+
_ -> true
61
+
end.
62
+
63
+
has_duplicate_pattern([_ | []]) ->
64
+
false;
65
+
has_duplicate_pattern(String) ->
66
+
[First, Second | Rest] = String,
67
+
case has_pattern(Rest, [First, Second]) of
68
+
true -> true;
69
+
false -> has_duplicate_pattern([Second] ++ Rest)
70
+
end.
71
+
72
+
has_repeating_with_interrupt([_, _ | []]) ->
73
+
false;
74
+
has_repeating_with_interrupt(String) ->
75
+
[Start, Middle, End | Rest] = String,
76
+
case Start == End of
77
+
true -> true;
78
+
false -> has_repeating_with_interrupt([Middle, End] ++ Rest)
79
+
end.
80
+
81
+
is_nice_string2(String) ->
82
+
maybe
83
+
true ?= has_duplicate_pattern(String),
84
+
true ?= has_repeating_with_interrupt(String)
85
+
end.
86
+
87
+
count_nice_strings2([], Total) ->
88
+
Total;
89
+
count_nice_strings2([Head | Rest], Total) ->
90
+
case is_nice_string2(Head) of
91
+
true -> count_nice_strings2(Rest, Total + 1);
92
+
false -> count_nice_strings2(Rest, Total)
93
+
end.
94
+
95
+
% --- Generic Helper Functions
96
+
read_input() -> read_input("").
97
+
read_input(PrevLine) ->
98
+
case io:fread("", "~s") of
99
+
eof -> PrevLine;
100
+
{error, _} -> halt(1);
101
+
{ok, Terms} -> read_input(PrevLine ++ Terms)
102
+
end.
103
+
104
+
main(Args) ->
105
+
Input = read_input(),
106
+
case Args of
107
+
["1"] ->
108
+
part1(Input);
109
+
["2"] ->
110
+
part2(Input);
111
+
_ ->
112
+
part1(Input),
113
+
part2(Input)
114
+
end.
-103
2015/06/solution.erl
-103
2015/06/solution.erl
···
1
-
#!/usr/bin/env escript
2
-
% --- Part 1 Code
3
-
part1(Input) -> io:format("Part 1: ~b~n", [count_lit_lights(Input, #{})]).
4
-
5
-
generate_coordinates({XStart, YStart}, {XEnd, YEnd}) ->
6
-
[{X, Y} || X <- lists:seq(XStart, XEnd), Y <- lists:seq(YStart, YEnd)].
7
-
8
-
generate_map(Coords, Value) -> maps:from_list([{Coord, Value} || Coord <- Coords]).
9
-
10
-
perform_instruction(toggle, Coords, Map) ->
11
-
maps:merge_with(
12
-
fun(_, Current, _) ->
13
-
case Current of
14
-
0 -> 1;
15
-
1 -> 0
16
-
end
17
-
end,
18
-
Map,
19
-
generate_map(Coords, 1)
20
-
);
21
-
perform_instruction(Action, Coords, Map) ->
22
-
maps:merge(
23
-
Map,
24
-
case Action of
25
-
on -> generate_map(Coords, 1);
26
-
off -> generate_map(Coords, 0)
27
-
end
28
-
).
29
-
30
-
count_lit_lights([], Map) ->
31
-
maps:fold(fun(_, Value, Accumulator) -> Accumulator + Value end, 0, Map);
32
-
count_lit_lights([{Action, Start, End} | Instructions], Map) ->
33
-
count_lit_lights(
34
-
Instructions,
35
-
perform_instruction(Action, generate_coordinates(Start, End), Map)
36
-
).
37
-
38
-
% --- Part 2 Code
39
-
part2(Input) -> io:format("Part 2: ~b~n", [calculate_brightness(Input, #{})]).
40
-
41
-
perform_instruction2(off, Coords, Map) ->
42
-
maps:merge_with(
43
-
fun(_, Current, _) ->
44
-
case Current of
45
-
Current when Current > 0 -> Current - 1;
46
-
Current -> 0
47
-
end
48
-
end,
49
-
Map,
50
-
generate_map(Coords, 0)
51
-
);
52
-
perform_instruction2(Action, Coords, Map) ->
53
-
maps:merge_with(
54
-
fun(_, Current, New) -> Current + New end,
55
-
Map,
56
-
case Action of
57
-
toggle -> generate_map(Coords, 2);
58
-
on -> generate_map(Coords, 1)
59
-
end
60
-
).
61
-
62
-
calculate_brightness([], Map) ->
63
-
maps:fold(fun(_, Value, Accumulator) -> Accumulator + Value end, 0, Map);
64
-
calculate_brightness([{Action, Start, End} | Instructions], Map) ->
65
-
calculate_brightness(
66
-
Instructions,
67
-
perform_instruction2(Action, generate_coordinates(Start, End), Map)
68
-
).
69
-
70
-
% --- Read Input
71
-
split_coordinate(Coordinate) ->
72
-
[X, Y] = string:split(Coordinate, ","),
73
-
{Xint, _} = string:to_integer(X),
74
-
{Yint, _} = string:to_integer(Y),
75
-
{Xint, Yint}.
76
-
77
-
parse_line(Data) ->
78
-
case string:split(string:trim(Data), " ", all) of
79
-
["toggle", Start, _, End] -> {toggle, split_coordinate(Start), split_coordinate(End)};
80
-
["turn", "on", Start, _, End] -> {on, split_coordinate(Start), split_coordinate(End)};
81
-
["turn", "off", Start, _, End] -> {off, split_coordinate(Start), split_coordinate(End)}
82
-
end.
83
-
84
-
read_input() -> read_input("").
85
-
read_input(Prev) ->
86
-
case io:get_line("") of
87
-
eof -> Prev;
88
-
{error, _} -> halt(1);
89
-
Data when Prev == "" -> read_input([parse_line(Data)]);
90
-
Data -> read_input(Prev ++ [parse_line(Data)])
91
-
end.
92
-
93
-
main(Args) ->
94
-
Input = read_input(),
95
-
case Args of
96
-
["1"] ->
97
-
part1(Input);
98
-
["2"] ->
99
-
part2(Input);
100
-
_ ->
101
-
part1(Input),
102
-
part2(Input)
103
-
end.
+105
2015/06/solution.escript
+105
2015/06/solution.escript
···
1
+
#!/usr/bin/env escript
2
+
-mode(compile).
3
+
4
+
% --- Part 1 Code
5
+
part1(Input) -> io:format("Part 1: ~b~n", [count_lit_lights(Input, #{})]).
6
+
7
+
generate_coordinates({XStart, YStart}, {XEnd, YEnd}) ->
8
+
[{X, Y} || X <- lists:seq(XStart, XEnd), Y <- lists:seq(YStart, YEnd)].
9
+
10
+
generate_map(Coords, Value) -> maps:from_list([{Coord, Value} || Coord <- Coords]).
11
+
12
+
perform_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
+
);
23
+
perform_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
+
32
+
count_lit_lights([], Map) ->
33
+
maps:fold(fun(_, Value, Accumulator) -> Accumulator + Value end, 0, Map);
34
+
count_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
41
+
part2(Input) -> io:format("Part 2: ~b~n", [calculate_brightness(Input, #{})]).
42
+
43
+
perform_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
+
);
54
+
perform_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
+
64
+
calculate_brightness([], Map) ->
65
+
maps:fold(fun(_, Value, Accumulator) -> Accumulator + Value end, 0, Map);
66
+
calculate_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
73
+
split_coordinate(Coordinate) ->
74
+
[X, Y] = string:split(Coordinate, ","),
75
+
{Xint, _} = string:to_integer(X),
76
+
{Yint, _} = string:to_integer(Y),
77
+
{Xint, Yint}.
78
+
79
+
parse_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
+
86
+
read_input() -> read_input("").
87
+
read_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
+
95
+
main(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.
+3
-3
flake.lock
+3
-3
flake.lock
···
2
2
"nodes": {
3
3
"nixpkgs": {
4
4
"locked": {
5
-
"lastModified": 1753939845,
6
-
"narHash": "sha256-K2ViRJfdVGE8tpJejs8Qpvvejks1+A4GQej/lBk5y7I=",
5
+
"lastModified": 1766902085,
6
+
"narHash": "sha256-coBu0ONtFzlwwVBzmjacUQwj3G+lybcZ1oeNSQkgC0M=",
7
7
"owner": "nixos",
8
8
"repo": "nixpkgs",
9
-
"rev": "94def634a20494ee057c76998843c015909d6311",
9
+
"rev": "c0b0e0fddf73fd517c3471e546c0df87a42d53f4",
10
10
"type": "github"
11
11
},
12
12
"original": {