Advent of Code Solutions
advent-of-code
aoc
1#!/usr/bin/env escript
2-mode(compile).
3
4% --- Part 1 Code
5part1(Input) ->
6 io:format("Part 1: ~b~n", [count_nice_strings(Input, 0)]).
7
8count_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
20has_consecutive_characters([_ | []]) ->
21 false;
22has_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
29has_forbidden_pattern(String, Pattern) ->
30 case string:find(String, Pattern) of
31 nomatch -> false;
32 _ -> true
33 end.
34
35is_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
45count_nice_strings([], Total) ->
46 Total;
47count_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
54part2(Input) ->
55 io:format("Part 2: ~b~n", [count_nice_strings2(Input, 0)]).
56
57has_pattern(String, Pattern) ->
58 case string:find(String, Pattern) of
59 nomatch -> false;
60 _ -> true
61 end.
62
63has_duplicate_pattern([_ | []]) ->
64 false;
65has_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
72has_repeating_with_interrupt([_, _ | []]) ->
73 false;
74has_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
81is_nice_string2(String) ->
82 maybe
83 true ?= has_duplicate_pattern(String),
84 true ?= has_repeating_with_interrupt(String)
85 end.
86
87count_nice_strings2([], Total) ->
88 Total;
89count_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
96read_input() -> read_input("").
97read_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
104main(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.