82 lines
1.9 KiB
Elixir
82 lines
1.9 KiB
Elixir
defmodule AOC.Day4 do
|
|
def parse_input(lines), do: parse_input(lines, [], %{})
|
|
def parse_input([], acc, el), do: [el | acc]
|
|
def parse_input(["" | tl], acc, el), do: parse_input(tl, [el | acc], %{})
|
|
|
|
def parse_input([hd | tl], acc, el) do
|
|
el =
|
|
String.split(hd)
|
|
|> Enum.map(&String.split(&1, ":"))
|
|
|> Enum.map(fn [k, v] -> {k, v} end)
|
|
|> Enum.into(el)
|
|
|
|
parse_input(tl, acc, el)
|
|
end
|
|
|
|
def validate_field_presence(%{
|
|
"byr" => _,
|
|
"iyr" => _,
|
|
"eyr" => _,
|
|
"hgt" => _,
|
|
"hcl" => _,
|
|
"ecl" => _,
|
|
"pid" => _
|
|
}),
|
|
do: true
|
|
|
|
def validate_field_presence(_), do: false
|
|
|
|
def part1 do
|
|
AOC.Util.input_lines(4, 1)
|
|
|> parse_input()
|
|
|> Enum.filter(&validate_field_presence/1)
|
|
|> Enum.count()
|
|
end
|
|
|
|
def validate_height(height) do
|
|
if String.ends_with?(height, ["cm", "in"]) do
|
|
{height, measure} = String.split_at(height, -2)
|
|
height = String.to_integer(height)
|
|
|
|
case measure do
|
|
"cm" -> height >= 150 and height <= 193
|
|
"in" -> height >= 59 and height <= 76
|
|
end
|
|
else
|
|
false
|
|
end
|
|
end
|
|
|
|
def validate_fields(%{
|
|
"byr" => byr,
|
|
"iyr" => iyr,
|
|
"eyr" => eyr,
|
|
"hgt" => hgt,
|
|
"hcl" => hcl,
|
|
"ecl" => ecl,
|
|
"pid" => pid
|
|
}) do
|
|
byr = String.to_integer(byr)
|
|
iyr = String.to_integer(iyr)
|
|
eyr = String.to_integer(eyr)
|
|
|
|
[
|
|
byr >= 1920 and byr <= 2002,
|
|
iyr >= 2010 and iyr <= 2020,
|
|
eyr >= 2020 and eyr <= 2030,
|
|
validate_height(hgt),
|
|
hcl =~ ~r/^#([a-f]|[0-9]){6}$/,
|
|
ecl in ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"],
|
|
pid =~ ~r/^[0-9]{9}$/
|
|
]
|
|
|> Enum.reduce(&and/2)
|
|
end
|
|
|
|
def part2 do
|
|
AOC.Util.input_lines(4, 1)
|
|
|> parse_input()
|
|
|> Enum.filter(&validate_field_presence/1)
|
|
|> Enum.filter(&validate_fields/1)
|
|
|> Enum.count()
|
|
end
|
|
end
|