Zero-prefix numbers
This commit is contained in:
parent
c51a51ab63
commit
f295bd93af
18 changed files with 0 additions and 7750 deletions
107
2020/day04/day4.ex
Normal file
107
2020/day04/day4.ex
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
defmodule Day4 do
|
||||
defp read_input do
|
||||
Path.expand('input', Path.dirname(__ENV__.file))
|
||||
|> File.read!()
|
||||
end
|
||||
|
||||
defp parse_passports(text) do
|
||||
String.split(text, "\n\n")
|
||||
|> Enum.map(fn block ->
|
||||
fields = String.split(block)
|
||||
|
||||
Enum.reduce(fields, %{}, fn field, passport ->
|
||||
[key, val] = String.split(field, ":")
|
||||
Map.put(passport, key, val)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
@required_fields [
|
||||
"byr",
|
||||
"iyr",
|
||||
"eyr",
|
||||
"hgt",
|
||||
"hcl",
|
||||
"ecl",
|
||||
"pid"
|
||||
# "cid"
|
||||
]
|
||||
|
||||
defp all_fields?(passport) do
|
||||
Enum.all?(@required_fields, fn field ->
|
||||
case Map.fetch(passport, field) do
|
||||
{:ok, _val} -> true
|
||||
:error -> false
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
defp parse_int(val, default) do
|
||||
try do
|
||||
String.to_integer(val)
|
||||
rescue
|
||||
ArgumentError -> default
|
||||
end
|
||||
end
|
||||
|
||||
defp valid?(passport) do
|
||||
validators = %{
|
||||
"byr" => fn val ->
|
||||
int = parse_int(val, 0)
|
||||
1920 <= int && int <= 2002
|
||||
end,
|
||||
"iyr" => fn val ->
|
||||
int = parse_int(val, 0)
|
||||
2010 <= int && int <= 2020
|
||||
end,
|
||||
"eyr" => fn val ->
|
||||
int = parse_int(val, 0)
|
||||
2020 <= int && int <= 2030
|
||||
end,
|
||||
"hgt" => fn val ->
|
||||
case Regex.named_captures(~r/^(?<num>\d+)(?<units>cm|in)$/, val) do
|
||||
%{"num" => num, "units" => units} ->
|
||||
int = parse_int(num, 0)
|
||||
|
||||
case units do
|
||||
"cm" ->
|
||||
150 <= int && int <= 193
|
||||
|
||||
"in" ->
|
||||
59 <= int && int <= 76
|
||||
end
|
||||
|
||||
_ ->
|
||||
false
|
||||
end
|
||||
end,
|
||||
"hcl" => fn val -> Regex.match?(~r/^#[0-9a-f]{6}$/, val) end,
|
||||
"ecl" => fn val -> Enum.member?(["amb", "blu", "brn", "gry", "grn", "hzl", "oth"], val) end,
|
||||
"pid" => fn val -> Regex.match?(~r/^[0-9]{9}$/, val) end
|
||||
# cid
|
||||
}
|
||||
|
||||
Map.to_list(validators)
|
||||
|> Enum.all?(fn {field, validator} ->
|
||||
case Map.get(passport, field) do
|
||||
nil -> false
|
||||
val -> validator.(val)
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
def part1 do
|
||||
read_input()
|
||||
|> parse_passports()
|
||||
|> Enum.count(&all_fields?/1)
|
||||
end
|
||||
|
||||
def part2 do
|
||||
read_input()
|
||||
|> parse_passports()
|
||||
|> Enum.count(&valid?/1)
|
||||
end
|
||||
end
|
||||
|
||||
Day4.part1() |> IO.inspect()
|
||||
Day4.part2() |> IO.inspect()
|
||||
Loading…
Reference in a new issue