-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday_04.ex
70 lines (59 loc) · 2.06 KB
/
day_04.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
defmodule AdventOfCode.Y2020.Day04 do
@moduledoc """
--- Day 4: Passport Processing ---
Problem Link: https://adventofcode.com/2020/day/4
"""
alias AdventOfCode.Helpers.{InputReader, Transformers}
def input, do: InputReader.read_from_file(2020, 4)
def run(input \\ input()) do
input = parse(input)
{Enum.count(input, &ok?(:k, &1)), Enum.count(input, &ok?(:v, &1))}
end
def parse(data) do
data
|> String.split(~r{\n\n|\r\r|\r\n\r\n})
|> Enum.map(fn pp_raw ->
pp_raw
|> Transformers.lines()
|> Enum.map_join(" ", &Function.identity/1)
|> as_pp()
end)
end
defp as_pp(fields) do
fields
|> String.split(" ")
|> Enum.map(&List.to_tuple(String.split(&1, ":")))
|> Enum.into(%{})
|> Map.put_new("cid", nil)
|> cast()
end
@fields ~w/byr cid ecl eyr hcl hgt iyr pid/
@birth_year 1920..2002
@expiration_year 2020..2030
@eye_colors ~w/amb blu brn gry grn hzl oth/
@height_cm 59..76
@height_inch 150..193
@issuing_year 2010..2020
defp ok?(:k, pp), do: map_size(Map.take(pp, @fields)) == 8
defp ok?(:v, pp), do: Enum.all?(Enum.map(@fields, &ok?(&1, pp)))
defp ok?("cid", %{}), do: true
defp ok?("byr", %{"byr" => byr}), do: byr in @birth_year
defp ok?("ecl", %{"ecl" => ecl}), do: ecl in @eye_colors
defp ok?("eyr", %{"eyr" => eyr}), do: eyr in @expiration_year
defp ok?("hcl", %{"hcl" => "#" <> hcl}), do: String.length(hcl) == 6
defp ok?("hgt", %{"hgt" => {hgt, "cm"}}) when hgt in @height_inch, do: true
defp ok?("hgt", %{"hgt" => {hgt, "in"}}) when hgt in @height_cm, do: true
defp ok?("hgt", %{"hgt" => _}), do: false
defp ok?("iyr", %{"iyr" => iyr}), do: iyr in @issuing_year
defp ok?("pid", %{"pid" => pid}), do: String.length(pid) == 9 && String.to_integer(pid)
defp ok?(_, _), do: false
defp cast(%{"byr" => b, "eyr" => e, "hgt" => h, "iyr" => i} = pp) do
Map.merge(pp, %{
"byr" => String.to_integer(b),
"eyr" => String.to_integer(e),
"hgt" => Integer.parse(h),
"iyr" => String.to_integer(i)
})
end
defp cast(pp), do: pp
end