-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday07.ex
87 lines (69 loc) · 2.15 KB
/
day07.ex
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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
defmodule Y2016.Day07 do
use Advent.Day, no: 7
def tls_addresses(input) do
input
|> Stream.reject(&(!tls_address?(&1)))
|> Enum.count()
end
def ssl_addresses(input) do
input
|> Stream.reject(&(!ssl_address?(&1)))
|> Enum.count()
end
def parse_input do
input() |> String.split()
end
@doc """
iex> Day07.ssl_address?("aba[bab]xyz")
true
iex> Day07.ssl_address?("xyx[xyx]xyx")
false
iex> Day07.ssl_address?("aaa[kek]eke")
true
iex> Day07.ssl_address?("zazbz[bzb]cdb")
true
"""
def ssl_address?(address) do
address
# Strip out the hypernet sections so we can iterate over the string checking for aba's safely
# Otherwise we may run into aba's within the hypernets
|> String.replace(~r/\[\w+\]/, " ")
|> String.graphemes()
|> check_ssl_address(address)
end
def check_ssl_address([], _string), do: false
def check_ssl_address([a, b, a | tail], string)
when a >= "a" and a <= "z" and b >= "a" and b <= "z" and a != b do
case String.match?(string, ~r/\[\w*#{b}#{a}#{b}\w*\]/) do
true -> true
false -> check_ssl_address([b, a | tail], string)
end
end
def check_ssl_address([_head | tail], string), do: check_ssl_address(tail, string)
@doc """
iex> Day07.tls_address?("abba[mnop]qrst")
true
iex> Day07.tls_address?("abcd[bddb]xyyx")
false
iex> Day07.tls_address?("aaaa[qwer]tyui")
false
iex> Day07.tls_address?("ioxxoj[asdfgh]zxcvbn")
true
Some more examples to flesh out edge cases that the original tests didn't cover.
iex> Day07.tls_address?("ioxxoj[asdfgh]zxcvbn[asdfgh]zxcvbn")
true
iex> Day07.tls_address?("ioxxoj[abcoxxoabc]zxcvbn[asdfgh]zxcvbn")
false
"""
def tls_address?(address) do
abba = "(\\w)((?!\\1)\\w)\\2\\1"
case String.match?(address, ~r/\[\w*#{abba}\w*\]/) do
# If there is an ABBA in the hypernet [] parts, it's all over.
true -> false
# But if not, and there's an ABBA anywhere in the string, it's a win.
false -> String.match?(address, ~r/#{abba}/)
end
end
def part1_verify, do: parse_input() |> tls_addresses()
def part2_verify, do: parse_input() |> ssl_addresses()
end