aoc/20/lib/days/day4.ex

83 lines
1.9 KiB
Elixir
Raw Permalink Normal View History

2023-04-17 18:18:20 +00:00
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