-
Notifications
You must be signed in to change notification settings - Fork 0
/
04.rs
97 lines (88 loc) · 2.5 KB
/
04.rs
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#![feature(test)]
use std::collections::HashMap;
use regex::Regex;
type Input = Vec<HashMap<String, String>>;
fn setup(input: &str) -> Input {
let mut out = Vec::new();
for block in input.split("\n\n") {
let mut cur = HashMap::new();
for line in block.trim().lines() {
for (key, value) in line.split(' ').map(|a| {
let mut x = a.trim().split(':');
(x.next().unwrap(), x.next().unwrap())
}) {
cur.insert(key.to_string(), value.to_string());
}
}
out.push(cur);
}
out
}
fn part1(input: &Input) -> String {
let mut out = 0;
for passport in input {
if ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"]
.iter()
.all(|x| passport.contains_key(&x.to_string()))
{
out += 1;
}
}
out.to_string()
}
type Rule = (&'static str, fn(&String) -> bool);
const RULES: [Rule; 7] = [
("byr", |x: &String| {
let num: i32 = x.parse().unwrap();
(1920..=2002).contains(&num)
}),
("iyr", |x: &String| {
let num: i32 = x.parse().unwrap();
(2010..=2020).contains(&num)
}),
("eyr", |x: &String| {
let num: i32 = x.parse().unwrap();
(2020..=2030).contains(&num)
}),
("hgt", |x: &String| {
let regex = Regex::new(r"^(\d+)(cm|in)$").unwrap();
match regex.captures(x) {
None => false,
Some(result) => {
let num: i32 = result[1].parse().unwrap();
match &result[2] {
"cm" => (150..=193).contains(&num),
"in" => (59..=76).contains(&num),
_ => false,
}
}
}
}),
("hcl", |x: &String| {
let regex = Regex::new(r"^#[0-9a-f]{6}$").unwrap();
regex.captures(x).is_some()
}),
("ecl", |x: &String| {
["amb", "blu", "brn", "gry", "grn", "hzl", "oth"].contains(&x.as_str())
}),
("pid", |x: &String| {
let regex = Regex::new(r"^\d{9}$").unwrap();
regex.captures(x).is_some()
}),
];
fn part2(input: &Input) -> String {
let mut out = 0;
for passport in input {
if RULES
.iter()
.all(|(key, validator)| match passport.get(&key.to_string()) {
None => false,
Some(value) => validator(value),
})
{
out += 1;
}
}
out.to_string()
}
aoc::main!(2020, 4, ex: 1[a]);