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