57 lines
1.4 KiB
Elixir
57 lines
1.4 KiB
Elixir
defmodule Day2 do
|
|
@example """
|
|
1-3 a: abcde
|
|
1-3 b: cdefg
|
|
2-9 c: ccccccccc
|
|
"""
|
|
|
|
def part1(example \\ false) do
|
|
if(example, do: @example, else: File.read!("lib/day2/input.txt"))
|
|
|> String.trim()
|
|
|> String.split("\n")
|
|
|> Enum.map(&parse_policy_and_password/1)
|
|
|> Enum.count(&password_valid1/1)
|
|
end
|
|
|
|
def part2(example \\ false) do
|
|
if(example, do: @example, else: File.read!("lib/day2/input.txt"))
|
|
|> String.trim()
|
|
|> String.split("\n")
|
|
|> Enum.map(&parse_policy_and_password/1)
|
|
|> Enum.count(&password_valid2/1)
|
|
end
|
|
|
|
def parse_policy_and_password(line) do
|
|
[policy, rest] = String.split(line, ":")
|
|
rest = String.trim(rest)
|
|
|
|
[count, letter] = String.split(policy, " ")
|
|
[min, max] = String.split(count, "-")
|
|
min = String.to_integer(min)
|
|
max = String.to_integer(max)
|
|
|
|
{{letter, min, max}, rest}
|
|
end
|
|
|
|
def password_valid1({{letter, min, max}, password}) do
|
|
letter_count =
|
|
password
|
|
|> String.codepoints()
|
|
|> Enum.count(fn
|
|
^letter -> true
|
|
_ -> false
|
|
end)
|
|
|
|
letter_count >= min && letter_count <= max
|
|
end
|
|
|
|
def password_valid2({{letter, first, second}, password}) do
|
|
at_first = String.at(password, first - 1)
|
|
at_second = String.at(password, second - 1)
|
|
first_matches = letter == at_first
|
|
second_matches = letter == at_second
|
|
|
|
(first_matches || second_matches) && !(first_matches && second_matches)
|
|
end
|
|
end
|