2020: day04: part 2
This commit is contained in:
parent
20e3f6c1a9
commit
ab5efad22e
13
aoc2020/input/day04_provided2.txt
Normal file
13
aoc2020/input/day04_provided2.txt
Normal file
|
@ -0,0 +1,13 @@
|
|||
eyr:1972 cid:100
|
||||
hcl:#18171d ecl:amb hgt:170 pid:186cm iyr:2018 byr:1926
|
||||
|
||||
iyr:2019
|
||||
hcl:#602927 eyr:1967 hgt:170cm
|
||||
ecl:grn pid:012533040 byr:1946
|
||||
|
||||
hcl:dab227 iyr:2012
|
||||
ecl:brn hgt:182cm pid:021572410 eyr:2020 byr:1992 cid:277
|
||||
|
||||
hgt:59cm ecl:zzz
|
||||
eyr:2038 hcl:74454a iyr:2023
|
||||
pid:3556412378 byr:2007
|
12
aoc2020/input/day04_provided3.txt
Normal file
12
aoc2020/input/day04_provided3.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
pid:087499704 hgt:74in ecl:grn iyr:2012 eyr:2030 byr:1980
|
||||
hcl:#623a2f
|
||||
|
||||
eyr:2029 ecl:blu cid:129 byr:1989
|
||||
iyr:2014 pid:896056539 hcl:#a97842 hgt:165cm
|
||||
|
||||
hcl:#888785
|
||||
hgt:164cm byr:2001 iyr:2015 cid:88
|
||||
pid:545766238 ecl:hzl
|
||||
eyr:2022
|
||||
|
||||
iyr:2010 hgt:158cm hcl:#b6652a ecl:blu byr:1944 eyr:2021 pid:093154719
|
|
@ -8,6 +8,7 @@ pub fn run() -> aoc::Result<String> {
|
|||
let mut res = String::with_capacity(128);
|
||||
|
||||
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
||||
writeln!(res, "part 2: {}", part2(INPUT)?)?;
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
@ -39,6 +40,12 @@ fn part1(input: &str) -> aoc::Result<usize> {
|
|||
Ok(passports.iter().filter(|p| p.has_valid_fields()).count())
|
||||
}
|
||||
|
||||
fn part2(input: &str) -> aoc::Result<usize> {
|
||||
let passports = get_passports(input)?;
|
||||
|
||||
Ok(passports.iter().filter(|p| p.is_valid()).count())
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Passport {
|
||||
byr: Option<String>,
|
||||
|
@ -62,6 +69,115 @@ impl Passport {
|
|||
&& self.ecl.is_some()
|
||||
&& self.pid.is_some()
|
||||
}
|
||||
|
||||
fn is_valid(&self) -> bool {
|
||||
self.byr_valid()
|
||||
&& self.iyr_valid()
|
||||
&& self.eyr_valid()
|
||||
&& self.hgt_valid()
|
||||
&& self.hcl_valid()
|
||||
&& self.ecl_valid()
|
||||
&& self.pid_valid()
|
||||
}
|
||||
|
||||
fn byr_valid(&self) -> bool {
|
||||
let byr = match &self.byr {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
if let Ok(res) = byr.parse::<i64>() {
|
||||
res >= 1920 && res <= 2002
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn iyr_valid(&self) -> bool {
|
||||
let iyr = match &self.iyr {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
if let Ok(res) = iyr.parse::<i64>() {
|
||||
res >= 2010 && res <= 2020
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn eyr_valid(&self) -> bool {
|
||||
let eyr = match &self.eyr {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
if let Ok(res) = eyr.parse::<i64>() {
|
||||
res >= 2020 && res <= 2030
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn hgt_valid(&self) -> bool {
|
||||
let hgt = match &self.hgt {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
if let Some(num) = hgt.strip_suffix("in") {
|
||||
if let Ok(res) = num.parse::<i64>() {
|
||||
res >= 59 && res <= 76
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else if let Some(num) = hgt.strip_suffix("cm") {
|
||||
if let Ok(res) = num.parse::<i64>() {
|
||||
res >= 150 && res <= 193
|
||||
} else {
|
||||
false
|
||||
}
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn hcl_valid(&self) -> bool {
|
||||
let hcl = match &self.hcl {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
if let Some(rest) = hcl.strip_prefix("#") {
|
||||
rest.chars().filter(|c| !c.is_ascii_hexdigit()).count() == 0
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
fn ecl_valid(&self) -> bool {
|
||||
let ecl = match &self.ecl {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
ecl == "amb"
|
||||
|| ecl == "blu"
|
||||
|| ecl == "brn"
|
||||
|| ecl == "gry"
|
||||
|| ecl == "grn"
|
||||
|| ecl == "hzl"
|
||||
|| ecl == "oth"
|
||||
}
|
||||
|
||||
fn pid_valid(&self) -> bool {
|
||||
let pid = match &self.pid {
|
||||
Some(s) => s,
|
||||
None => return false,
|
||||
};
|
||||
|
||||
pid.chars().filter(|c| !c.is_ascii_digit()).count() == 0 && pid.len() == 9
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Passport {
|
||||
|
@ -97,15 +213,28 @@ impl FromStr for Passport {
|
|||
mod tests {
|
||||
use super::*;
|
||||
|
||||
static PROVIDED: &'static str = include_str!("../input/day04_provided.txt");
|
||||
static PROVIDED1: &'static str = include_str!("../input/day04_provided1.txt");
|
||||
static PROVIDED2: &'static str = include_str!("../input/day04_provided2.txt");
|
||||
static PROVIDED3: &'static str = include_str!("../input/day04_provided3.txt");
|
||||
|
||||
#[test]
|
||||
fn part1_provided() {
|
||||
assert_eq!(part1(PROVIDED).unwrap(), 2);
|
||||
assert_eq!(part1(PROVIDED1).unwrap(), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part1_real() {
|
||||
assert_eq!(part1(INPUT).unwrap(), 192);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_provided() {
|
||||
assert_eq!(part2(PROVIDED2).unwrap(), 0);
|
||||
assert_eq!(part2(PROVIDED3).unwrap(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn part2_real() {
|
||||
assert_eq!(part2(INPUT).unwrap(), 101);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue