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);
|
let mut res = String::with_capacity(128);
|
||||||
|
|
||||||
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
writeln!(res, "part 1: {}", part1(INPUT)?)?;
|
||||||
|
writeln!(res, "part 2: {}", part2(INPUT)?)?;
|
||||||
|
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
@ -39,6 +40,12 @@ fn part1(input: &str) -> aoc::Result<usize> {
|
||||||
Ok(passports.iter().filter(|p| p.has_valid_fields()).count())
|
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)]
|
#[derive(Debug)]
|
||||||
struct Passport {
|
struct Passport {
|
||||||
byr: Option<String>,
|
byr: Option<String>,
|
||||||
|
@ -62,6 +69,115 @@ impl Passport {
|
||||||
&& self.ecl.is_some()
|
&& self.ecl.is_some()
|
||||||
&& self.pid.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 {
|
impl FromStr for Passport {
|
||||||
|
@ -97,15 +213,28 @@ impl FromStr for Passport {
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
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]
|
#[test]
|
||||||
fn part1_provided() {
|
fn part1_provided() {
|
||||||
assert_eq!(part1(PROVIDED).unwrap(), 2);
|
assert_eq!(part1(PROVIDED1).unwrap(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn part1_real() {
|
fn part1_real() {
|
||||||
assert_eq!(part1(INPUT).unwrap(), 192);
|
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