145 lines
2.9 KiB
Elixir
145 lines
2.9 KiB
Elixir
defmodule Day4 do
|
|
@example """
|
|
ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
|
|
byr:1937 iyr:2017 cid:147 hgt:183cm
|
|
|
|
iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
|
|
hcl:#cfa07d byr:1929
|
|
|
|
hcl:#ae17e1 iyr:2013
|
|
eyr:2024
|
|
ecl:brn pid:760753108 byr:1931
|
|
hgt:179cm
|
|
|
|
hcl:#cfa07d eyr:2025 pid:166559648
|
|
iyr:2011 ecl:brn hgt:59in
|
|
"""
|
|
|
|
def part1(example \\ false) do
|
|
count_all_valid(example, false)
|
|
end
|
|
|
|
def part2(example \\ false) do
|
|
count_all_valid(example, true)
|
|
end
|
|
|
|
def count_all_valid(example, check_values) do
|
|
if(example, do: @example, else: File.read!("lib/day4/input.txt"))
|
|
|> String.trim()
|
|
|> String.split("\n\n")
|
|
|> parse_input()
|
|
|> count_valid(check_values)
|
|
end
|
|
|
|
def parse_input(inputs) do
|
|
Enum.map(inputs, fn input ->
|
|
input
|
|
|> String.split()
|
|
|> Enum.reduce(%{}, fn pair, acc ->
|
|
[k, v] = String.split(pair, ":")
|
|
Map.put(acc, k, v)
|
|
end)
|
|
end)
|
|
end
|
|
|
|
@doc """
|
|
iex> Day4.validate_byr("2002")
|
|
true
|
|
iex> Day4.validate_byr("2003")
|
|
false
|
|
"""
|
|
def validate_byr(v) do
|
|
Regex.match?(~r/(^19[2-9][0-9]|200[0-2])$/, v)
|
|
end
|
|
|
|
@doc """
|
|
iex> Day4.validate_iyr("2010")
|
|
true
|
|
iex> Day4.validate_iyr("2009")
|
|
false
|
|
iex> Day4.validate_iyr("2021")
|
|
false
|
|
"""
|
|
def validate_iyr(v) do
|
|
Regex.match?(~r/^(201\d|2020)$/, v)
|
|
end
|
|
|
|
@doc """
|
|
iex> Day4.validate_eyr("2020")
|
|
true
|
|
iex> Day4.validate_eyr("2030")
|
|
true
|
|
iex> Day4.validate_eyr("2019")
|
|
false
|
|
iex> Day4.validate_eyr("2031")
|
|
false
|
|
"""
|
|
def validate_eyr(v) do
|
|
Regex.match?(~r/^(202\d|2030)$/, v)
|
|
end
|
|
|
|
@doc """
|
|
iex> Day4.validate_hgt("60in")
|
|
true
|
|
iex> Day4.validate_hgt("190cm")
|
|
true
|
|
iex> Day4.validate_hgt("190in")
|
|
false
|
|
iex> Day4.validate_hgt("190")
|
|
false
|
|
"""
|
|
def validate_hgt(v) do
|
|
Regex.match?(~r/^(1[5-8]\dcm|19[0-9]cm|59in|6\din|7[0-6]in)$/, v)
|
|
end
|
|
|
|
@doc """
|
|
iex> Day4.validate_hcl("#123abc")
|
|
true
|
|
iex> Day4.validate_hcl("#123ABC")
|
|
true
|
|
iex> Day4.validate_hcl("#123abz")
|
|
false
|
|
iex> Day4.validate_hcl("123abc")
|
|
false
|
|
"""
|
|
def validate_hcl(v) do
|
|
Regex.match?(~r/#[0-9a-f]{6}/i, v)
|
|
end
|
|
|
|
@doc """
|
|
iex> Day4.validate_ecl("brn")
|
|
true
|
|
iex> Day4.validate_ecl("wat")
|
|
false
|
|
"""
|
|
def validate_ecl(v) do
|
|
Regex.match?(~r/^(amb|b(lu|rn)|gr[yn]|hzl|oth)$/i, v)
|
|
end
|
|
|
|
@doc """
|
|
iex> Day4.validate_pid("000000001")
|
|
true
|
|
iex> Day4.validate_pid("0123456789")
|
|
true
|
|
"""
|
|
def validate_pid(v) do
|
|
Regex.match?(~r/^\d{9}$/, v)
|
|
end
|
|
|
|
@required_keys ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
|
|
|
|
def count_valid(data, check_values) do
|
|
Enum.count(data, fn passport ->
|
|
is_valid(passport, check_values)
|
|
end)
|
|
end
|
|
|
|
def is_valid(data, check_values) do
|
|
Enum.all?(@required_keys, fn k ->
|
|
Map.has_key?(data, k) &&
|
|
(!check_values ||
|
|
apply(Day4, String.to_atom("validate_#{k}"), [Map.fetch!(data, k)]))
|
|
end)
|
|
end
|
|
end
|