-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
285 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
Blueprint 1: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 13 clay. Each geode robot costs 3 ore and 7 obsidian. | ||
Blueprint 2: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 20 clay. Each geode robot costs 2 ore and 12 obsidian. | ||
Blueprint 3: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 9 clay. Each geode robot costs 3 ore and 7 obsidian. | ||
Blueprint 4: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 2 ore and 11 obsidian. | ||
Blueprint 5: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 16 clay. Each geode robot costs 2 ore and 15 obsidian. | ||
Blueprint 6: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 11 clay. Each geode robot costs 3 ore and 14 obsidian. | ||
Blueprint 7: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 3 ore and 11 obsidian. | ||
Blueprint 8: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 4 ore and 19 obsidian. | ||
Blueprint 9: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 2 ore and 19 obsidian. | ||
Blueprint 10: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 19 clay. Each geode robot costs 3 ore and 17 obsidian. | ||
Blueprint 11: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 11 clay. Each geode robot costs 3 ore and 8 obsidian. | ||
Blueprint 12: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 17 clay. Each geode robot costs 2 ore and 13 obsidian. | ||
Blueprint 13: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 2 ore and 13 obsidian. | ||
Blueprint 14: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 18 clay. Each geode robot costs 4 ore and 16 obsidian. | ||
Blueprint 15: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 3 ore and 15 obsidian. | ||
Blueprint 16: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 13 clay. Each geode robot costs 2 ore and 20 obsidian. | ||
Blueprint 17: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 2 ore and 9 obsidian. | ||
Blueprint 18: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 3 ore and 12 obsidian. | ||
Blueprint 19: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 8 obsidian. | ||
Blueprint 20: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 7 clay. Each geode robot costs 4 ore and 13 obsidian. | ||
Blueprint 21: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 5 clay. Each geode robot costs 4 ore and 8 obsidian. | ||
Blueprint 22: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 2 ore and 14 clay. Each geode robot costs 3 ore and 8 obsidian. | ||
Blueprint 23: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 2 ore and 15 clay. Each geode robot costs 3 ore and 16 obsidian. | ||
Blueprint 24: Each ore robot costs 3 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 18 clay. Each geode robot costs 3 ore and 13 obsidian. | ||
Blueprint 25: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 15 clay. Each geode robot costs 2 ore and 20 obsidian. | ||
Blueprint 26: Each ore robot costs 2 ore. Each clay robot costs 4 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 4 ore and 20 obsidian. | ||
Blueprint 27: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 17 clay. Each geode robot costs 2 ore and 13 obsidian. | ||
Blueprint 28: Each ore robot costs 3 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 15 clay. Each geode robot costs 2 ore and 8 obsidian. | ||
Blueprint 29: Each ore robot costs 4 ore. Each clay robot costs 3 ore. Each obsidian robot costs 4 ore and 19 clay. Each geode robot costs 4 ore and 12 obsidian. | ||
Blueprint 30: Each ore robot costs 4 ore. Each clay robot costs 4 ore. Each obsidian robot costs 4 ore and 14 clay. Each geode robot costs 2 ore and 16 obsidian. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,252 @@ | ||
use std::ops::{Add, AddAssign, Sub}; | ||
|
||
pub const SAMPLE: &str = include_str!("sample"); | ||
pub const INPUT: &str = include_str!("input"); | ||
|
||
#[derive(Debug)] | ||
struct Blueprint { | ||
n: u32, | ||
ore_robot: Resources, | ||
clay_robot: Resources, | ||
obsidian_robot: Resources, | ||
geode_robot: Resources, | ||
} | ||
|
||
#[derive(Clone, Debug, Default)] | ||
struct Resources { | ||
ore: u32, | ||
clay: u32, | ||
obsidian: u32, | ||
geode: u32, | ||
} | ||
|
||
impl Resources { | ||
fn checked_sub(&self, other: &Self) -> Option<Self> { | ||
Some(Resources { | ||
ore: self.ore.checked_sub(other.ore)?, | ||
clay: self.clay.checked_sub(other.clay)?, | ||
obsidian: self.obsidian.checked_sub(other.obsidian)?, | ||
geode: self.geode.checked_sub(other.geode)?, | ||
}) | ||
} | ||
} | ||
|
||
impl Sub for Resources { | ||
type Output = Resources; | ||
|
||
fn sub(self, rhs: Self) -> Self::Output { | ||
Resources { | ||
ore: self.ore - rhs.ore, | ||
clay: self.clay - rhs.clay, | ||
obsidian: self.obsidian - rhs.obsidian, | ||
geode: self.geode - rhs.geode, | ||
} | ||
} | ||
} | ||
|
||
impl Add for Resources { | ||
type Output = Resources; | ||
|
||
fn add(self, rhs: Self) -> Self::Output { | ||
Resources { | ||
ore: self.ore + rhs.ore, | ||
clay: self.clay + rhs.clay, | ||
obsidian: self.obsidian + rhs.obsidian, | ||
geode: self.geode + rhs.geode, | ||
} | ||
} | ||
} | ||
|
||
impl AddAssign for Resources { | ||
fn add_assign(&mut self, rhs: Self) { | ||
self.ore += rhs.ore; | ||
self.clay += rhs.clay; | ||
self.obsidian += rhs.obsidian; | ||
self.geode += rhs.geode; | ||
} | ||
} | ||
|
||
fn parse<'a>(lines: impl Iterator<Item = &'a str>) -> Vec<Blueprint> { | ||
lines | ||
.map(|bp| { | ||
let (n, s) = bp | ||
.strip_prefix("Blueprint ") | ||
.unwrap() | ||
.split_once(": Each ore robot costs ") | ||
.unwrap(); | ||
let n = n.parse().unwrap(); | ||
let (ore_robot_ore, s) = s.split_once(" ore. Each clay robot costs ").unwrap(); | ||
let (clay_robot_ore, s) = s.split_once(" ore. Each obsidian robot costs ").unwrap(); | ||
let (obsidian_robot_ore, s) = s.split_once(" ore and ").unwrap(); | ||
let (obsidian_robot_clay, s) = s.split_once(" clay. Each geode robot costs ").unwrap(); | ||
let (geode_robot_ore, s) = s.split_once(" ore and ").unwrap(); | ||
let geode_robot_obsidian = s.strip_suffix(" obsidian.").unwrap(); | ||
Blueprint { | ||
n, | ||
ore_robot: Resources { | ||
ore: ore_robot_ore.parse().unwrap(), | ||
..Default::default() | ||
}, | ||
clay_robot: Resources { | ||
ore: clay_robot_ore.parse().unwrap(), | ||
..Default::default() | ||
}, | ||
obsidian_robot: Resources { | ||
ore: obsidian_robot_ore.parse().unwrap(), | ||
clay: obsidian_robot_clay.parse().unwrap(), | ||
..Default::default() | ||
}, | ||
geode_robot: Resources { | ||
ore: geode_robot_ore.parse().unwrap(), | ||
obsidian: geode_robot_obsidian.parse().unwrap(), | ||
..Default::default() | ||
}, | ||
} | ||
}) | ||
.collect() | ||
} | ||
|
||
fn max_geodes( | ||
bp: &Blueprint, | ||
mut inventory: Resources, | ||
n_robots: Resources, | ||
minutes_left: u32, | ||
mut skip_ore: bool, | ||
mut skip_clay: bool, | ||
) -> u32 { | ||
if minutes_left == 1 { | ||
return inventory.geode + n_robots.geode; | ||
} | ||
let mut geodes = 0; | ||
let new_robot = if let Some(inven) = inventory.checked_sub(&bp.geode_robot) { | ||
inventory = inven; | ||
skip_clay = false; | ||
skip_ore = false; | ||
Resources { | ||
geode: 1, | ||
..Default::default() | ||
} | ||
} else if let Some(inven) = inventory.checked_sub(&bp.obsidian_robot) { | ||
inventory = inven; | ||
skip_clay = false; | ||
skip_ore = false; | ||
Resources { | ||
obsidian: 1, | ||
..Default::default() | ||
} | ||
} else { | ||
if !skip_clay { | ||
if let Some(inven) = inventory.checked_sub(&bp.clay_robot) { | ||
skip_ore = false; | ||
geodes = geodes.max(max_geodes( | ||
bp, | ||
inven + n_robots.clone(), | ||
n_robots.clone() | ||
+ Resources { | ||
clay: 1, | ||
..Default::default() | ||
}, | ||
minutes_left - 1, | ||
skip_ore, | ||
skip_clay, | ||
)); | ||
skip_clay = true; | ||
} | ||
} | ||
if !skip_ore { | ||
if let Some(inven) = inventory.checked_sub(&bp.ore_robot) { | ||
skip_clay = false; | ||
geodes = geodes.max(max_geodes( | ||
bp, | ||
inven + n_robots.clone(), | ||
n_robots.clone() | ||
+ Resources { | ||
ore: 1, | ||
..Default::default() | ||
}, | ||
minutes_left - 1, | ||
skip_ore, | ||
skip_clay, | ||
)); | ||
skip_ore = true; | ||
} | ||
} | ||
Resources::default() | ||
}; | ||
geodes.max(max_geodes( | ||
bp, | ||
inventory + n_robots.clone(), | ||
n_robots + new_robot, | ||
minutes_left - 1, | ||
skip_ore, | ||
skip_clay, | ||
)) | ||
} | ||
|
||
pub mod part1 { | ||
use super::*; | ||
|
||
pub fn solution(s: &str) -> u32 { | ||
let bps = parse(s.lines()); | ||
bps.iter() | ||
.map(|bp| { | ||
bp.n * max_geodes( | ||
bp, | ||
Resources::default(), | ||
Resources { | ||
ore: 1, | ||
..Default::default() | ||
}, | ||
24, | ||
false, | ||
false, | ||
) | ||
}) | ||
.inspect(|q| { | ||
dbg!(q); | ||
}) | ||
.sum() | ||
} | ||
#[test] | ||
fn sample() { | ||
assert_eq!(solution(SAMPLE), 33); | ||
} | ||
#[test] | ||
fn actual() { | ||
assert_eq!(solution(INPUT), 1382); | ||
} | ||
} | ||
|
||
pub mod part2 { | ||
use super::*; | ||
|
||
pub fn solution(s: &str) -> u32 { | ||
let bps = parse(s.lines().take(3)); | ||
bps.iter() | ||
.map(|bp| { | ||
max_geodes( | ||
bp, | ||
Resources::default(), | ||
Resources { | ||
ore: 1, | ||
..Default::default() | ||
}, | ||
32, | ||
false, | ||
false, | ||
) | ||
}) | ||
.inspect(|q| { | ||
dbg!(q); | ||
}) | ||
.product() | ||
} | ||
#[test] | ||
fn sample() { | ||
assert_eq!(solution(SAMPLE), 33); | ||
} | ||
// #[test] | ||
// fn actual() { | ||
// assert_eq!(solution(INPUT), 1382); | ||
// } | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Blueprint 1: Each ore robot costs 4 ore. Each clay robot costs 2 ore. Each obsidian robot costs 3 ore and 14 clay. Each geode robot costs 2 ore and 7 obsidian. | ||
Blueprint 2: Each ore robot costs 2 ore. Each clay robot costs 3 ore. Each obsidian robot costs 3 ore and 8 clay. Each geode robot costs 3 ore and 12 obsidian. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,5 +24,6 @@ pub mod d15; | |
pub mod d16; | ||
pub mod d17; | ||
pub mod d18; | ||
pub mod d19; | ||
|
||
pub mod y2021; |