day7
This commit is contained in:
parent
59a21265c6
commit
2c499e9efe
52
Cargo.lock
generated
52
Cargo.lock
generated
@ -9,10 +9,21 @@ dependencies = [
|
|||||||
"aoc-runner",
|
"aoc-runner",
|
||||||
"aoc-runner-derive",
|
"aoc-runner-derive",
|
||||||
"itertools",
|
"itertools",
|
||||||
|
"lazy_static",
|
||||||
|
"regex",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aho-corasick"
|
||||||
|
version = "1.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aoc-runner"
|
name = "aoc-runner"
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
@ -69,6 +80,18 @@ version = "1.0.10"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lazy_static"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memchr"
|
||||||
|
version = "2.6.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.71"
|
version = "1.0.71"
|
||||||
@ -87,6 +110,35 @@ dependencies = [
|
|||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex"
|
||||||
|
version = "1.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-automata",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-automata"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
|
||||||
|
dependencies = [
|
||||||
|
"aho-corasick",
|
||||||
|
"memchr",
|
||||||
|
"regex-syntax",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "regex-syntax"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustversion"
|
name = "rustversion"
|
||||||
version = "1.0.14"
|
version = "1.0.14"
|
||||||
|
@ -14,3 +14,5 @@ aoc-runner-derive = "0.3.0"
|
|||||||
itertools = "0.12.0"
|
itertools = "0.12.0"
|
||||||
strum = "0.25.0"
|
strum = "0.25.0"
|
||||||
strum_macros = "0.25"
|
strum_macros = "0.25"
|
||||||
|
lazy_static = "1.4.0"
|
||||||
|
regex = "1.10.2"
|
119
src/day7.rs
Normal file
119
src/day7.rs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
use std::collections::{HashMap, VecDeque};
|
||||||
|
|
||||||
|
use aoc_runner_derive::{aoc, aoc_generator};
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
const GOAL: &str = "shiny gold";
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref LINE_RE: Regex = Regex::new(r"(\w+ \w+) bags contain (.*)").unwrap();
|
||||||
|
static ref ITEM_RE: Regex = Regex::new(r"(\d+) (\w+ \w+) bags?").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc_generator(day7)]
|
||||||
|
fn parse(input: &str) -> HashMap<String, Vec<(usize, String)>> {
|
||||||
|
let mut bags = HashMap::<String, Vec<(usize, String)>>::new();
|
||||||
|
for line in input.lines() {
|
||||||
|
if let Some((item, items)) = LINE_RE
|
||||||
|
.captures(line.as_ref())
|
||||||
|
.and_then(|captures| {
|
||||||
|
Some((captures.get(1)?.as_str(), captures.get(2)?.as_str()))
|
||||||
|
}) {
|
||||||
|
bags.insert(
|
||||||
|
item.to_string(),
|
||||||
|
ITEM_RE
|
||||||
|
.captures_iter(items)
|
||||||
|
.filter_map(|captures| {
|
||||||
|
Some((
|
||||||
|
captures.get(1)?.as_str().parse().ok()?,
|
||||||
|
captures.get(2)?.as_str().to_string(),
|
||||||
|
))
|
||||||
|
}).collect()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
bags
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Expand<'a> {
|
||||||
|
bags: &'a HashMap<String, Vec<(usize, String)>>,
|
||||||
|
queue: VecDeque<(usize, &'a str)>
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expand<'a>(bags: &'a HashMap<String, Vec<(usize, String)>>, bag: &str) -> Expand<'a> {
|
||||||
|
Expand {
|
||||||
|
bags,
|
||||||
|
queue: bags.get(bag).map_or_else(VecDeque::new, |items| {
|
||||||
|
items.iter()
|
||||||
|
.map(|(count, item)| (*count, item.as_str()))
|
||||||
|
.collect()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Iterator for Expand<'a> {
|
||||||
|
type Item = (usize, &'a str);
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.queue.pop_front().map(|(count, item)| {
|
||||||
|
if let Some(items) = self.bags.get(item) {
|
||||||
|
for (subcount, subitem) in items {
|
||||||
|
self.queue.push_back((count * subcount, subitem));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(count, item)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day7, part1)]
|
||||||
|
fn part1(bags: &HashMap<String, Vec<(usize, String)>>) -> usize {
|
||||||
|
bags.keys()
|
||||||
|
.filter(|key| expand(&bags, key).any(|(_, item)| item == GOAL))
|
||||||
|
.count()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[aoc(day7, part2)]
|
||||||
|
fn part2(bags: &HashMap<String, Vec<(usize, String)>>) -> usize {
|
||||||
|
expand(bags, GOAL).map(|(count, _)| count).sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
const EX: &str = r"light red bags contain 1 bright white bag, 2 muted yellow bags.
|
||||||
|
dark orange bags contain 3 bright white bags, 4 muted yellow bags.
|
||||||
|
bright white bags contain 1 shiny gold bag.
|
||||||
|
muted yellow bags contain 2 shiny gold bags, 9 faded blue bags.
|
||||||
|
shiny gold bags contain 1 dark olive bag, 2 vibrant plum bags.
|
||||||
|
dark olive bags contain 3 faded blue bags, 4 dotted black bags.
|
||||||
|
vibrant plum bags contain 5 faded blue bags, 6 dotted black bags.
|
||||||
|
faded blue bags contain no other bags.
|
||||||
|
dotted black bags contain no other bags.";
|
||||||
|
|
||||||
|
const EX_2: &str = r"shiny gold bags contain 2 dark red bags.
|
||||||
|
dark red bags contain 2 dark orange bags.
|
||||||
|
dark orange bags contain 2 dark yellow bags.
|
||||||
|
dark yellow bags contain 2 dark green bags.
|
||||||
|
dark green bags contain 2 dark blue bags.
|
||||||
|
dark blue bags contain 2 dark violet bags.
|
||||||
|
dark violet bags contain no other bags.";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_example() {
|
||||||
|
assert_eq!(part1(&parse(EX)), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example() {
|
||||||
|
assert_eq!(part2(&parse(EX)), 32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_example2() {
|
||||||
|
assert_eq!(part2(&parse(EX_2)), 126);
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
mod day7;
|
||||||
mod day6;
|
mod day6;
|
||||||
mod day5;
|
mod day5;
|
||||||
mod day1;
|
mod day1;
|
||||||
@ -8,5 +9,7 @@ extern crate aoc_runner;
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate aoc_runner_derive;
|
extern crate aoc_runner_derive;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
aoc_lib!{ year = 2020 }
|
aoc_lib!{ year = 2020 }
|
Loading…
Reference in New Issue
Block a user