defmodule Pass do
defstruct passline: ""
def parse_input(input_string) do
%Pass{passline: input_string}
end
def valid(pass) do
["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
|> Enum.map(&(pass.passline =~ &1))
|> Enum.all?(&(&1 == true))
end
end
defmodule Passport do
defstruct [
:birth_year,
:country_id,
:expiration_year,
:eye_color,
:hair_color,
:height,
:issue_year,
:passport_id
]
def parse_input(input_string) do
input_string
|> String.split(" ", trim: true)
|> Enum.reduce(%Passport{}, &parse_prop/2)
end
def valid(passport) do
[
passport.birth_year,
passport.expiration_year,
passport.eye_color,
passport.hair_color,
passport.height,
passport.issue_year,
passport.passport_id
]
|> Enum.any?(&is_nil/1)
|> Kernel.not()
end
defp parse_prop("byr:" <> byr, passport) do
%{passport | birth_year: byr}
end
defp parse_prop("eyr:" <> eyr, passport) do
%{passport | expiration_year: eyr}
end
defp parse_prop("hgt:" <> hgt, passport) do
%{passport | height: hgt}
end
defp parse_prop("pid:" <> pid, passport) do
%{passport | passport_id: pid}
end
defp parse_prop("ecl:" <> ecl, passport) do
%{passport | eye_color: ecl}
end
defp parse_prop("hcl:" <> hcl, passport) do
%{passport | hair_color: hcl}
end
defp parse_prop("iyr:" <> iyr, passport) do
%{passport | issue_year: iyr}
end
defp parse_prop("cid:" <> cid, passport) do
%{passport | country_id: cid}
end
end
input =
File.read!("input")
|> String.split("\n\n", trim: true)
|> Enum.map(&Pass.parse_input/1)
|> Enum.filter(&Pass.valid/1)
IO.inspect(input)
Enum.count(input) |> IO.inspect()