init
This commit is contained in:
commit
0005f4caff
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/target
|
||||||
|
/input
|
178
Cargo.lock
generated
Normal file
178
Cargo.lock
generated
Normal file
@ -0,0 +1,178 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 3
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "advent_of_code_2020"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"aoc-runner",
|
||||||
|
"aoc-runner-derive",
|
||||||
|
"itertools",
|
||||||
|
"strum",
|
||||||
|
"strum_macros",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aoc-runner"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d21ef9204ad206a5a3e918e9920da04e1118ad91ce4f23570be964b9d6b9dfcb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aoc-runner-derive"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ba8b944269d3fee645d281b1335e1797044db497bb02d0098cc3fdb8900069cc"
|
||||||
|
dependencies = [
|
||||||
|
"aoc-runner-internal",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aoc-runner-internal"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "274b0ba7f3669a45ec0aaacf94eb032a749de880ab776091576cca94037c9982"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "either"
|
||||||
|
version = "1.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "heck"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2"
|
||||||
|
version = "1.0.71"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quote"
|
||||||
|
version = "1.0.33"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.16"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.193"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.193"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.42",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.108"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum"
|
||||||
|
version = "0.25.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "290d54ea6f91c969195bdbcd7442c8c2a2ba87da8bf60a7ee86a235d4bc1e125"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "strum_macros"
|
||||||
|
version = "0.25.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn 2.0.42",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "syn"
|
||||||
|
version = "2.0.42"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"unicode-ident",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unicode-ident"
|
||||||
|
version = "1.0.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
16
Cargo.toml
Normal file
16
Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "advent_of_code_2020"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
bench = false
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
aoc-runner = "0.3.0"
|
||||||
|
aoc-runner-derive = "0.3.0"
|
||||||
|
itertools = "0.12.0"
|
||||||
|
strum = "0.25.0"
|
||||||
|
strum_macros = "0.25"
|
46
src/day1.rs
Normal file
46
src/day1.rs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use itertools::Itertools;
|
||||||
|
#[aoc_generator(day1)]
|
||||||
|
fn parse(input: &str) -> Vec<u64> {
|
||||||
|
input.lines()
|
||||||
|
.map(str::parse::<u64>)
|
||||||
|
.map(Result::unwrap)
|
||||||
|
.collect_vec()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day1, part1)]
|
||||||
|
fn part1(input: &Vec<u64>) -> u64 {
|
||||||
|
input.iter().combinations(2)
|
||||||
|
.find(|x| x.iter().cloned().sum::<u64>() == 2020)
|
||||||
|
.map(|x| x.iter().cloned().product()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day1, part2)]
|
||||||
|
fn part2(input: &Vec<u64>) -> u64 {
|
||||||
|
input.iter().combinations(3)
|
||||||
|
.find(|x| x.iter().cloned().sum::<u64>() == 2020)
|
||||||
|
.map(|x| x.iter().cloned().product()).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const EX: &str = r"1721
|
||||||
|
979
|
||||||
|
366
|
||||||
|
299
|
||||||
|
675
|
||||||
|
1456";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse(EX)), 514579);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse(EX)), 241861950);
|
||||||
|
}
|
||||||
|
}
|
75
src/day2.rs
Normal file
75
src/day2.rs
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Policy {
|
||||||
|
min: u32,
|
||||||
|
max: u32,
|
||||||
|
match_char: char,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc_generator(day2)]
|
||||||
|
fn parse(input: &str) -> Vec<(Policy, String)> {
|
||||||
|
let input = input.lines().map(|line| {
|
||||||
|
let line = line.split(": ").collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let policy = line[0].split(' ').collect::<Vec<_>>();
|
||||||
|
let min = policy[0][0..policy[0].find('-').unwrap()].parse::<u32>().unwrap();
|
||||||
|
let max = policy[0][policy[0].find('-').unwrap() + 1..].parse::<u32>().unwrap();
|
||||||
|
let match_char = policy[1].chars().next().unwrap();
|
||||||
|
(Policy {min, max, match_char}, line[1].to_string())
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day2, part1)]
|
||||||
|
fn part1(passwords: &Vec<(Policy, String)>) -> u32 {
|
||||||
|
let mut valid_count = 0;
|
||||||
|
for (Policy {min, max, match_char}, password) in passwords {
|
||||||
|
let mut count = 0;
|
||||||
|
for char in password.chars() {
|
||||||
|
if char == *match_char {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if count >= *min && count <= *max {
|
||||||
|
valid_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_count
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day2, part2)]
|
||||||
|
fn part2(passwords: &Vec<(Policy, String)>) -> u32 {
|
||||||
|
let mut valid_count = 0;
|
||||||
|
for (Policy {min, max, match_char}, password) in passwords {
|
||||||
|
let first = password.chars().collect::<Vec<_>>()[(*min - 1) as usize] == *match_char;
|
||||||
|
let second = password.chars().collect::<Vec<_>>()[(*max - 1) as usize] == *match_char;
|
||||||
|
if first ^ second {
|
||||||
|
valid_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valid_count
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const EX: &str = r"1-3 a: abcde
|
||||||
|
1-3 b: cdefg
|
||||||
|
2-9 c: ccccccccc";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse(EX)), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse(EX)), 1);
|
||||||
|
}
|
||||||
|
}
|
64
src/day3.rs
Normal file
64
src/day3.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
|
||||||
|
#[aoc_generator(day3)]
|
||||||
|
fn parse(input: &str) -> Vec<Vec<char>> {
|
||||||
|
let input = input.lines().map(|line| {
|
||||||
|
line.chars().collect::<Vec<_>>()
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day3, part1)]
|
||||||
|
fn part1(input: &Vec<Vec<char>>) -> u64 {
|
||||||
|
count_trees(1, 3, input)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day3, part2)]
|
||||||
|
fn part2(input: &Vec<Vec<char>>) -> u64 {
|
||||||
|
vec![(1,1), (1,3), (1,5), (1,7), (2,1)].iter()
|
||||||
|
.map(|(rise, run)| {
|
||||||
|
count_trees(*rise, *run, input)
|
||||||
|
}).product()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn count_trees(rise: usize, run: usize, input: &Vec<Vec<char>>) -> u64 {
|
||||||
|
let mut x = 0;
|
||||||
|
let mut tree_count = 0;
|
||||||
|
|
||||||
|
for y in (rise..input.len()).step_by(rise) {
|
||||||
|
x += run;
|
||||||
|
if input[y][x % input[0].len()] == '#' {
|
||||||
|
tree_count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tree_count
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const EX: &str = r"..##.......
|
||||||
|
#...#...#..
|
||||||
|
.#....#..#.
|
||||||
|
..#.#...#.#
|
||||||
|
.#...##..#.
|
||||||
|
..#.##.....
|
||||||
|
.#.#.#....#
|
||||||
|
.#........#
|
||||||
|
#.##...#...
|
||||||
|
#...##....#
|
||||||
|
.#..#...#.#";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse(EX)), 7);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse(EX)), 336);
|
||||||
|
}
|
||||||
|
}
|
202
src/day4.rs
Normal file
202
src/day4.rs
Normal file
@ -0,0 +1,202 @@
|
|||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use strum::IntoEnumIterator;
|
||||||
|
use strum_macros::EnumIter;
|
||||||
|
|
||||||
|
#[derive(Debug, EnumIter, PartialEq, Clone, Copy)]
|
||||||
|
enum IDField {
|
||||||
|
BirthYear,
|
||||||
|
IssueYear,
|
||||||
|
ExpirationYear,
|
||||||
|
Height,
|
||||||
|
HairColor,
|
||||||
|
EyeColor,
|
||||||
|
PassportID,
|
||||||
|
CountryID
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&str> for IDField {
|
||||||
|
fn from(value: &str) -> Self {
|
||||||
|
match &*value {
|
||||||
|
"byr" => Self::BirthYear,
|
||||||
|
"iyr" => Self::IssueYear,
|
||||||
|
"eyr" => Self::ExpirationYear,
|
||||||
|
"hgt" => Self::Height,
|
||||||
|
"hcl" => Self::HairColor,
|
||||||
|
"ecl" => Self::EyeColor,
|
||||||
|
"pid" => Self::PassportID,
|
||||||
|
"cid" => Self::CountryID,
|
||||||
|
_ => unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IDField {
|
||||||
|
fn validate(&self, val: &str) -> bool {
|
||||||
|
match self {
|
||||||
|
IDField::BirthYear => {
|
||||||
|
if val.len() == 4 {
|
||||||
|
if let Ok(num) = val.parse::<u32>() {
|
||||||
|
if num >= 1920 && num <= 2002 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
IDField::IssueYear => {
|
||||||
|
if val.len() == 4 {
|
||||||
|
if let Ok(num) = val.parse::<u32>() {
|
||||||
|
if num >= 2010 && num <= 2020 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
IDField::ExpirationYear => {
|
||||||
|
if val.len() == 4 {
|
||||||
|
if let Ok(num) = val.parse::<u32>() {
|
||||||
|
if num >= 2020 && num <= 2030 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
IDField::Height => {
|
||||||
|
if let Some(idx) = val.find("cm") {
|
||||||
|
if let Ok(num) = val[0..idx].parse::<u32>() {
|
||||||
|
if num >= 150 && num <= 193 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let Some(idx) = val.find("in") {
|
||||||
|
if let Ok(num) = val[0..idx].parse::<u32>() {
|
||||||
|
if num >= 59 && num <= 76 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
},
|
||||||
|
IDField::HairColor => {
|
||||||
|
if val.chars().next().unwrap() == '#' {
|
||||||
|
return val[1..].chars().all(|char| char.is_ascii_hexdigit())
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
},
|
||||||
|
IDField::EyeColor => {
|
||||||
|
match val {
|
||||||
|
"amb" | "blu" | "brn" | "gry" | "grn" | "hzl" | "oth" => true,
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
IDField::PassportID => {
|
||||||
|
val.len() == 9 && val.chars().all(char::is_numeric)
|
||||||
|
},
|
||||||
|
IDField::CountryID => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[aoc_generator(day4)]
|
||||||
|
fn parse(input: &str) -> Vec<Vec<(IDField, String)>> {
|
||||||
|
let input = input.split("\n\n")
|
||||||
|
.map(str::split_ascii_whitespace)
|
||||||
|
.map(|line| {
|
||||||
|
line.map(|field_str| {
|
||||||
|
let colon = field_str.find(':').unwrap();
|
||||||
|
(field_str[0..colon].into(), field_str[colon + 1..].to_string())
|
||||||
|
}).collect::<Vec<_>>()
|
||||||
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
input
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day4, part1)]
|
||||||
|
fn part1(input: &Vec<Vec<(IDField, String)>>) -> u32 {
|
||||||
|
input.iter()
|
||||||
|
.map(|passport| {
|
||||||
|
let passport = passport.iter().map(|(field, _)| *field).collect::<Vec<_>>();
|
||||||
|
IDField::iter().all(|x| {
|
||||||
|
if x == IDField::CountryID {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
passport.contains(&x)
|
||||||
|
})
|
||||||
|
}).filter(|x| *x).count() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day4, part2)]
|
||||||
|
fn part2(input: &Vec<Vec<(IDField, String)>>) -> u32 {
|
||||||
|
input.iter().map(|passport| {
|
||||||
|
IDField::iter().all(|x| {
|
||||||
|
if x == IDField::CountryID {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if let Some((_, val)) = passport.iter().find(|(field, _)| field == &x ) {
|
||||||
|
return x.validate(&val)
|
||||||
|
}
|
||||||
|
false
|
||||||
|
})
|
||||||
|
}).filter(|x| *x).count() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const EX: &str = r"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";
|
||||||
|
|
||||||
|
const EX_2: &str = r"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
|
||||||
|
|
||||||
|
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";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse(EX)), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse(EX_2)), 4);
|
||||||
|
}
|
||||||
|
}
|
10
src/lib.rs
Normal file
10
src/lib.rs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
mod day1;
|
||||||
|
mod day4;
|
||||||
|
mod day3;
|
||||||
|
mod day2;
|
||||||
|
extern crate aoc_runner;
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate aoc_runner_derive;
|
||||||
|
|
||||||
|
aoc_lib!{ year = 2020 }
|
7
src/main.rs
Normal file
7
src/main.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
extern crate advent_of_code_2020;
|
||||||
|
extern crate aoc_runner_derive;
|
||||||
|
extern crate aoc_runner;
|
||||||
|
|
||||||
|
use aoc_runner_derive::aoc_main;
|
||||||
|
|
||||||
|
aoc_main! { lib = advent_of_code_2020 }
|
Loading…
Reference in New Issue
Block a user