Add solution for 2020 day 04
This commit is contained in:
parent
2a6086f434
commit
ca5f179bae
2
2020/day-04/.gitignore
vendored
Normal file
2
2020/day-04/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
part_one
|
||||
part_two
|
30
2020/day-04/common.rs
Normal file
30
2020/day-04/common.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use std::collections::HashMap;
|
||||
use std::fs::File;
|
||||
use std::io::{self, Read};
|
||||
use std::path::Path;
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
pub type Passport = HashMap<String, String>;
|
||||
|
||||
pub fn read_file<P: AsRef<Path>>(path: P) -> io::Result<Vec<Passport>> {
|
||||
let mut file = File::open(path)?;
|
||||
let mut content = String::new();
|
||||
file.read_to_string(&mut content)?;
|
||||
|
||||
let mut passports = vec![];
|
||||
|
||||
for passport in content.split("\n\n") {
|
||||
let passport = passport.trim_end();
|
||||
let pairs = passport.split(&['\n', ' ', ':'][..]).collect::<Vec<_>>();
|
||||
|
||||
let mut passport = Passport::new();
|
||||
|
||||
for pair in pairs.chunks_exact(2) {
|
||||
passport.insert(pair[0].to_owned(), pair[1].to_owned());
|
||||
}
|
||||
|
||||
passports.push(passport);
|
||||
}
|
||||
|
||||
Ok(passports)
|
||||
}
|
1159
2020/day-04/inputs/puzzle.txt
Normal file
1159
2020/day-04/inputs/puzzle.txt
Normal file
File diff suppressed because it is too large
Load Diff
13
2020/day-04/inputs/sample.txt
Normal file
13
2020/day-04/inputs/sample.txt
Normal file
@ -0,0 +1,13 @@
|
||||
ecl:gry pid:860033327 eyr:2020 hcl:#fffffd
|
||||
byr:1937 iyr:2017 cid:147 hgt:183cm
|
||||
|
||||
iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884
|
||||
hcl:#cfa07d byr:1929
|
||||
|
||||
hcl:#ae17e1 iyr:2013
|
||||
eyr:2024
|
||||
ecl:brn pid:760753108 byr:1931
|
||||
hgt:179cm
|
||||
|
||||
hcl:#cfa07d eyr:2025 pid:166559648
|
||||
iyr:2011 ecl:brn hgt:59in
|
29
2020/day-04/part_one.rs
Normal file
29
2020/day-04/part_one.rs
Normal file
@ -0,0 +1,29 @@
|
||||
mod common;
|
||||
|
||||
use std::env;
|
||||
|
||||
use common::{read_file, Passport, Result};
|
||||
|
||||
fn check_valid(passports: Vec<Passport>) -> u64 {
|
||||
let mut num_valid = 0;
|
||||
|
||||
for passport in passports {
|
||||
if passport.len() == 8 || (passport.len() == 7 && !passport.contains_key("cid")) {
|
||||
num_valid += 1;
|
||||
}
|
||||
}
|
||||
|
||||
num_valid
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let path = env::args().skip(1).next().unwrap();
|
||||
|
||||
let passports = read_file(path)?;
|
||||
|
||||
let num_valid = check_valid(passports);
|
||||
|
||||
println!("{}", num_valid);
|
||||
|
||||
Ok(())
|
||||
}
|
74
2020/day-04/part_two.rs
Normal file
74
2020/day-04/part_two.rs
Normal file
@ -0,0 +1,74 @@
|
||||
mod common;
|
||||
|
||||
use std::env;
|
||||
|
||||
use common::{read_file, Passport, Result};
|
||||
|
||||
fn check_valid(passports: Vec<Passport>) -> Result<u64> {
|
||||
let mut num_valid = 0;
|
||||
|
||||
for passport in passports {
|
||||
let mut valid =
|
||||
passport.len() == 8 || (passport.len() == 7 && !passport.contains_key("cid"));
|
||||
|
||||
if !valid {
|
||||
continue;
|
||||
};
|
||||
|
||||
let birth_year = passport.get("byr").unwrap();
|
||||
valid = valid
|
||||
&& birth_year.matches(|c: char| c.is_digit(10)).count() == 4
|
||||
&& (1920..=2002_u32).contains(&birth_year.parse()?);
|
||||
|
||||
let issue_year = passport.get("iyr").unwrap();
|
||||
valid = valid
|
||||
&& issue_year.matches(|c: char| c.is_digit(10)).count() == 4
|
||||
&& (2010..=2020_u32).contains(&issue_year.parse()?);
|
||||
|
||||
let expir_year = passport.get("eyr").unwrap();
|
||||
valid = valid
|
||||
&& expir_year.matches(|c: char| c.is_digit(10)).count() == 4
|
||||
&& (2020..=2030_u32).contains(&expir_year.parse()?);
|
||||
|
||||
let height = passport.get("hgt").unwrap();
|
||||
let height_cm = height.strip_suffix("cm").map(|h| h.parse().unwrap());
|
||||
let height_in = height.strip_suffix("in").map(|h| h.parse().unwrap());
|
||||
valid = valid
|
||||
&& (height_cm.map(|h| (150..=193_u32).contains(&h)) == Some(true)
|
||||
|| height_in.map(|h| (59..=76_u32).contains(&h)) == Some(true));
|
||||
|
||||
let hair_color = passport.get("hcl").unwrap().strip_prefix("#");
|
||||
valid = valid
|
||||
&& hair_color.is_some()
|
||||
&& hair_color
|
||||
.unwrap()
|
||||
.matches(|c: char| c.is_digit(16))
|
||||
.count()
|
||||
== 6;
|
||||
|
||||
let eye_color = passport.get("ecl").unwrap();
|
||||
valid = valid
|
||||
&& ["amb", "blu", "brn", "gry", "grn", "hzl", "oth"].contains(&eye_color.as_str());
|
||||
|
||||
let pass_id = passport.get("pid").unwrap();
|
||||
valid = valid && pass_id.matches(|c: char| c.is_digit(10)).count() == 9;
|
||||
|
||||
if valid {
|
||||
num_valid += 1;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(num_valid)
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let path = env::args().skip(1).next().unwrap();
|
||||
|
||||
let passports = read_file(path)?;
|
||||
|
||||
let num_valid = check_valid(passports)?;
|
||||
|
||||
println!("{}", num_valid);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue
Block a user