first attempts :(
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
use std::collections::HashMap;
|
||||
#[derive(Debug)]
|
||||
struct Node {
|
||||
id: String,
|
||||
rate: i64,
|
||||
edges: Vec<String>,
|
||||
}
|
||||
type Data = (String, HashMap<String, Node>);
|
||||
type Output = i64;
|
||||
fn parse(input: &str) -> Data {
|
||||
let start = input.lines().next().unwrap()[6..=7].to_string();
|
||||
let map = input
|
||||
.lines()
|
||||
.map(|l| {
|
||||
let id = l[6..=7].to_string();
|
||||
|
||||
let rate = l
|
||||
.chars()
|
||||
.skip_while(|c| *c != '=')
|
||||
.skip(1)
|
||||
.take_while(|c| *c != ';')
|
||||
.collect::<String>()
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
let edges_str = l
|
||||
.chars()
|
||||
.skip_while(|c| *c != ';')
|
||||
.skip_while(|c| *c != 'v')
|
||||
.skip_while(|c| *c != ' ')
|
||||
.skip(1)
|
||||
.collect::<String>();
|
||||
let edges = edges_str.split(", ").map(str::to_owned).collect();
|
||||
|
||||
(id.clone(), Node { id, edges, rate })
|
||||
})
|
||||
.collect();
|
||||
(start, map)
|
||||
}
|
||||
fn part_one((start, mut graph): Data) -> Output {
|
||||
fn solve(
|
||||
graph: &mut HashMap<String, Node>,
|
||||
curr: &str,
|
||||
parent: &str,
|
||||
amount_released: i64,
|
||||
time_left: i64,
|
||||
) -> Output {
|
||||
if time_left == 0 {
|
||||
return amount_released;
|
||||
}
|
||||
|
||||
let mut max = 0;
|
||||
let rate = graph.get(curr).unwrap().rate;
|
||||
if rate > 0 {
|
||||
graph.get_mut(curr).unwrap().rate = 0;
|
||||
max = solve(
|
||||
&mut *graph,
|
||||
curr,
|
||||
curr,
|
||||
amount_released + rate * (time_left - 1),
|
||||
time_left - 1,
|
||||
);
|
||||
graph.get_mut(curr).unwrap().rate = rate;
|
||||
}
|
||||
|
||||
for edge in &graph.get(curr).unwrap().edges.clone() {
|
||||
if edge != parent {
|
||||
max = std::cmp::max(
|
||||
max,
|
||||
solve(graph, edge, curr, amount_released, time_left - 1),
|
||||
);
|
||||
}
|
||||
}
|
||||
max
|
||||
}
|
||||
solve(&mut graph, &start, "", 0, 30)
|
||||
}
|
||||
fn part_two(_data: Data) -> Output {
|
||||
todo!()
|
||||
}
|
||||
|
||||
advent_of_code_macro::generate_tests!(
|
||||
day 16,
|
||||
parse,
|
||||
part_one,
|
||||
part_two,
|
||||
sample tests [1_651, 0],
|
||||
star tests [0, 0]
|
||||
);
|
||||
@@ -0,0 +1,258 @@
|
||||
type Board = Vec<[bool; 7]>;
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
enum BlockType {
|
||||
Square,
|
||||
L,
|
||||
Horizontal,
|
||||
Vertical,
|
||||
Cross,
|
||||
}
|
||||
impl BlockType {
|
||||
fn height(&self) -> usize {
|
||||
match *self {
|
||||
Square => 2,
|
||||
L => 3,
|
||||
Horizontal => 1,
|
||||
Vertical => 4,
|
||||
Cross => 3,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
use BlockType::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Position {
|
||||
row: usize,
|
||||
col: usize,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Block {
|
||||
pos: Position,
|
||||
block_type: BlockType,
|
||||
}
|
||||
impl Block {
|
||||
fn left(&mut self, board: &Board) {
|
||||
let cond = match self.block_type {
|
||||
Square => {
|
||||
self.pos.col > 0
|
||||
&& !board[self.pos.row][self.pos.col - 1]
|
||||
&& !board[self.pos.row - 1][self.pos.col - 1]
|
||||
}
|
||||
L => {
|
||||
self.pos.col > 0
|
||||
&& !board[self.pos.row][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 2][self.pos.col - 1]
|
||||
}
|
||||
Cross => {
|
||||
self.pos.col > 0
|
||||
&& !board[self.pos.row][self.pos.col]
|
||||
&& !board[self.pos.row - 1][self.pos.col - 1]
|
||||
&& !board[self.pos.row - 2][self.pos.col]
|
||||
}
|
||||
Horizontal => self.pos.col > 0 && !board[self.pos.row][self.pos.col - 1],
|
||||
Vertical => {
|
||||
self.pos.col > 0
|
||||
&& !board[self.pos.row][self.pos.col - 1]
|
||||
&& !board[self.pos.row - 1][self.pos.col - 1]
|
||||
&& !board[self.pos.row - 2][self.pos.col - 1]
|
||||
&& !board[self.pos.row - 3][self.pos.col - 1]
|
||||
}
|
||||
};
|
||||
if cond {
|
||||
self.pos.col -= 1;
|
||||
}
|
||||
println!("left to {:?}, {:?}", self.pos, self.block_type);
|
||||
}
|
||||
|
||||
fn right(&mut self, board: &Board) {
|
||||
let cond = match self.block_type {
|
||||
Square => {
|
||||
self.pos.col < 5
|
||||
&& !board[self.pos.row][self.pos.col + 2]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 2]
|
||||
}
|
||||
L => {
|
||||
self.pos.col < 4
|
||||
&& !board[self.pos.row][self.pos.col + 3]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 3]
|
||||
&& !board[self.pos.row - 2][self.pos.col + 3]
|
||||
}
|
||||
Cross => {
|
||||
self.pos.col < 4
|
||||
&& !board[self.pos.row][self.pos.col + 2]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 3]
|
||||
&& !board[self.pos.row - 2][self.pos.col + 2]
|
||||
}
|
||||
Horizontal => self.pos.col < 3 && !board[self.pos.row][self.pos.col + 4],
|
||||
Vertical => {
|
||||
self.pos.col < 6
|
||||
&& !board[self.pos.row][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 2][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 3][self.pos.col + 1]
|
||||
}
|
||||
};
|
||||
if cond {
|
||||
self.pos.col += 1;
|
||||
}
|
||||
println!("right to {:?}, {:?}", self.pos, self.block_type);
|
||||
}
|
||||
|
||||
/// Returns if the block comes to rest (and can't move down)
|
||||
/// board will only be mutated to insert the object if the block is at rest
|
||||
fn down(&mut self, board: &mut Board) -> bool {
|
||||
let is_falling = match self.block_type {
|
||||
Square => {
|
||||
self.pos.row > 1
|
||||
&& !board[self.pos.row - 2][self.pos.col]
|
||||
&& !board[self.pos.row - 2][self.pos.col + 1]
|
||||
}
|
||||
L => {
|
||||
self.pos.row > 2
|
||||
&& !board[self.pos.row - 3][self.pos.col]
|
||||
&& !board[self.pos.row - 3][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 3][self.pos.col + 2]
|
||||
}
|
||||
Cross => {
|
||||
self.pos.row > 2
|
||||
&& !board[self.pos.row - 2][self.pos.col]
|
||||
&& !board[self.pos.row - 3][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 2][self.pos.col + 2]
|
||||
}
|
||||
Horizontal => {
|
||||
self.pos.row > 0
|
||||
&& !board[self.pos.row - 1][self.pos.col]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 1]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 2]
|
||||
&& !board[self.pos.row - 1][self.pos.col + 3]
|
||||
}
|
||||
Vertical => self.pos.row > 3 && !board[self.pos.row - 4][self.pos.col],
|
||||
};
|
||||
if is_falling {
|
||||
self.pos.row -= 1;
|
||||
}
|
||||
|
||||
println!(
|
||||
"down to {:?}, is falling? {:?}, {:?}",
|
||||
self.pos, is_falling, self.block_type
|
||||
);
|
||||
!is_falling
|
||||
}
|
||||
fn draw(&self, board: &mut Board) {
|
||||
match self.block_type {
|
||||
Square => {
|
||||
board[self.pos.row][self.pos.col] = true;
|
||||
board[self.pos.row][self.pos.col + 1] = true;
|
||||
board[self.pos.row - 1][self.pos.col] = true;
|
||||
board[self.pos.row - 1][self.pos.col + 1] = true;
|
||||
}
|
||||
L => {
|
||||
board[self.pos.row][self.pos.col + 2] = true;
|
||||
board[self.pos.row - 1][self.pos.col + 2] = true;
|
||||
board[self.pos.row - 2][self.pos.col + 2] = true;
|
||||
board[self.pos.row - 2][self.pos.col + 1] = true;
|
||||
board[self.pos.row - 2][self.pos.col] = true;
|
||||
}
|
||||
Cross => {
|
||||
board[self.pos.row][self.pos.col + 1] = true;
|
||||
board[self.pos.row - 1][self.pos.col + 1] = true;
|
||||
board[self.pos.row - 2][self.pos.col + 1] = true;
|
||||
board[self.pos.row - 1][self.pos.col] = true;
|
||||
board[self.pos.row - 1][self.pos.col + 2] = true;
|
||||
}
|
||||
Horizontal => {
|
||||
board[self.pos.row][self.pos.col] = true;
|
||||
board[self.pos.row][self.pos.col + 1] = true;
|
||||
board[self.pos.row][self.pos.col + 2] = true;
|
||||
board[self.pos.row][self.pos.col + 3] = true;
|
||||
}
|
||||
Vertical => {
|
||||
board[self.pos.row][self.pos.col] = true;
|
||||
board[self.pos.row - 1][self.pos.col] = true;
|
||||
board[self.pos.row - 2][self.pos.col] = true;
|
||||
board[self.pos.row - 3][self.pos.col] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Data = &'static str;
|
||||
type Output = i32;
|
||||
fn parse(input: &'static str) -> Data {
|
||||
input
|
||||
}
|
||||
fn part_one(data: Data) -> Output {
|
||||
let mut blocks = vec![Horizontal, Cross, L, Vertical, Square]
|
||||
.into_iter()
|
||||
.cycle();
|
||||
let mut top = -1i32;
|
||||
let block_type = blocks.next().unwrap();
|
||||
let mut curr = Block {
|
||||
pos: Position { row: 3, col: 2 },
|
||||
block_type,
|
||||
};
|
||||
let mut board = vec![[false; 7]; 5];
|
||||
let mut num_rocks = 0;
|
||||
for c in data.chars().cycle() {
|
||||
match c {
|
||||
'>' => curr.right(&board),
|
||||
'<' => curr.left(&board),
|
||||
_ => {}
|
||||
}
|
||||
if curr.down(&mut board) {
|
||||
curr.draw(&mut board);
|
||||
top = board
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
.find(|(_, el)| **el != [false; 7])
|
||||
.map(|(idx, _)| idx as i32)
|
||||
.unwrap();
|
||||
num_rocks += 1;
|
||||
|
||||
println!();
|
||||
for line in board.iter().rev() {
|
||||
print!("|");
|
||||
line.iter()
|
||||
.map(|filled| if *filled { '#' } else { '.' })
|
||||
.for_each(|c| print!("{c}"));
|
||||
println!("|");
|
||||
}
|
||||
println!("+-------+");
|
||||
println!("{:?}", top);
|
||||
println!();
|
||||
|
||||
if num_rocks == 15 {
|
||||
return top;
|
||||
}
|
||||
let block_type = blocks.next().unwrap();
|
||||
let start_row = top + 3 + block_type.height() as i32;
|
||||
while board.len() <= start_row as usize {
|
||||
board.push([false; 7]);
|
||||
}
|
||||
curr = Block {
|
||||
pos: Position {
|
||||
row: start_row as usize,
|
||||
col: 2,
|
||||
},
|
||||
block_type,
|
||||
};
|
||||
}
|
||||
}
|
||||
unreachable!()
|
||||
}
|
||||
fn part_two(_data: Data) -> Output {
|
||||
todo!()
|
||||
}
|
||||
|
||||
advent_of_code_macro::generate_tests!(
|
||||
day 17,
|
||||
parse,
|
||||
part_one,
|
||||
part_two,
|
||||
sample tests [3068, 0],
|
||||
star tests [0, 0]
|
||||
);
|
||||
@@ -0,0 +1,201 @@
|
||||
use std::collections::HashSet;
|
||||
use Side::*;
|
||||
|
||||
type Point = (i32, i32, i32);
|
||||
|
||||
#[derive(Debug, Clone, Copy, Hash, Eq, PartialEq)]
|
||||
enum Side {
|
||||
/// positive z side
|
||||
Top,
|
||||
|
||||
/// negative z side
|
||||
Bottom,
|
||||
|
||||
/// negative x side
|
||||
Left,
|
||||
|
||||
/// positive x side
|
||||
Right,
|
||||
|
||||
/// positive y side
|
||||
Front,
|
||||
|
||||
/// negative y side
|
||||
Back,
|
||||
}
|
||||
impl Side {
|
||||
fn inverse(&self) -> Self {
|
||||
match *self {
|
||||
Top => Bottom,
|
||||
Bottom => Top,
|
||||
Left => Right,
|
||||
Right => Left,
|
||||
Front => Back,
|
||||
Back => Front,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type Data = HashSet<Point>;
|
||||
|
||||
type Output = i32;
|
||||
|
||||
fn parse(input: &str) -> Data {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| l.split(',').map(str::parse).map(Result::unwrap))
|
||||
.map(|mut iter| {
|
||||
(
|
||||
iter.next().unwrap(),
|
||||
iter.next().unwrap(),
|
||||
iter.next().unwrap(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn part_one(data: Data) -> Output {
|
||||
data.iter()
|
||||
.map(|(x, y, z)| {
|
||||
let offsets = [
|
||||
(0, 0, 1),
|
||||
(0, 1, 0),
|
||||
(1, 0, 0),
|
||||
(0, 0, -1),
|
||||
(0, -1, 0),
|
||||
(-1, 0, 0),
|
||||
];
|
||||
offsets
|
||||
.iter()
|
||||
.filter(|(x_off, y_off, z_off)| !data.contains(&(x + x_off, y + y_off, z + z_off)))
|
||||
.count() as Output
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
fn part_two(data: Data) -> Output {
|
||||
let mut queue = vec![(
|
||||
*data
|
||||
.iter()
|
||||
.max_by(|(x1, _, _), (x2, _, _)| x1.cmp(x2))
|
||||
.unwrap(),
|
||||
Top,
|
||||
)];
|
||||
let mut visited: HashSet<(Point, Side)> = queue.clone().into_iter().collect();
|
||||
for i in 0.. {
|
||||
if i >= queue.len() {
|
||||
return visited.len() as Output;
|
||||
}
|
||||
let ((curr_x, curr_y, curr_z), curr_side) = queue[i];
|
||||
let offsets = [(1, 0), (0, 1), (-1, 0), (0, -1)];
|
||||
let positions = offsets.iter().map(|(a, b)| match curr_side {
|
||||
Top | Bottom => (curr_x + a, curr_y + b, curr_z),
|
||||
Left | Right => (curr_x, curr_y + a, curr_z + b),
|
||||
Front | Back => (curr_x + a, curr_y, curr_z + b),
|
||||
});
|
||||
for (new_x, new_y, new_z) in positions {
|
||||
let res = match curr_side {
|
||||
Top | Bottom => {
|
||||
let side = if curr_x > new_x {
|
||||
Right
|
||||
} else if curr_x < new_x {
|
||||
Left
|
||||
} else if curr_y > new_y {
|
||||
Front
|
||||
} else {
|
||||
Back
|
||||
};
|
||||
if curr_side == Top {
|
||||
if data.contains(&(new_x, new_y, new_z + 1)) {
|
||||
((new_x, new_y, new_z + 1), side)
|
||||
} else if data.contains(&(new_x, new_y, new_z)) {
|
||||
((new_x, new_y, new_z), Top)
|
||||
} else {
|
||||
((curr_x, curr_y, curr_z), side.inverse())
|
||||
}
|
||||
} else {
|
||||
if data.contains(&(new_x, new_y, new_z - 1)) {
|
||||
((new_x, new_y, new_z - 1), side)
|
||||
} else if data.contains(&(new_x, new_y, new_z)) {
|
||||
((new_x, new_y, new_z), Bottom)
|
||||
} else {
|
||||
((curr_x, curr_y, curr_z), side.inverse())
|
||||
}
|
||||
}
|
||||
}
|
||||
Left | Right => {
|
||||
let side = if curr_z > new_z {
|
||||
Top
|
||||
} else if curr_z < new_z {
|
||||
Bottom
|
||||
} else if curr_y > new_y {
|
||||
Front
|
||||
} else {
|
||||
Back
|
||||
};
|
||||
if curr_side == Left {
|
||||
if data.contains(&(new_x - 1, new_y, new_z)) {
|
||||
((new_x - 1, new_y, new_z), side)
|
||||
} else if data.contains(&(new_x, new_y, new_z)) {
|
||||
((new_x, new_y, new_z), Left)
|
||||
} else {
|
||||
((curr_x, curr_y, curr_z), side.inverse())
|
||||
}
|
||||
} else {
|
||||
if data.contains(&(new_x + 1, new_y, new_z)) {
|
||||
((new_x + 1, new_y, new_z), side)
|
||||
} else if data.contains(&(new_x, new_y, new_z)) {
|
||||
((new_x, new_y, new_z), Right)
|
||||
} else {
|
||||
((curr_x, curr_y, curr_z), side.inverse())
|
||||
}
|
||||
}
|
||||
}
|
||||
Front | Back => {
|
||||
let side = if curr_z > new_z {
|
||||
Top
|
||||
} else if curr_z < new_z {
|
||||
Bottom
|
||||
} else if curr_x > new_x {
|
||||
Right
|
||||
} else {
|
||||
Left
|
||||
};
|
||||
if curr_side == Front {
|
||||
if data.contains(&(new_x, new_y + 1, new_z)) {
|
||||
((new_x, new_y + 1, new_z), side)
|
||||
} else if data.contains(&(new_x, new_y, new_z)) {
|
||||
((new_x, new_y, new_z), Front)
|
||||
} else {
|
||||
((curr_x, curr_y, curr_z), side.inverse())
|
||||
}
|
||||
} else {
|
||||
if data.contains(&(new_x + 1, new_y, new_z)) {
|
||||
((new_x + 1, new_y, new_z), side)
|
||||
} else if data.contains(&(new_x, new_y, new_z)) {
|
||||
((new_x, new_y, new_z), Back)
|
||||
} else {
|
||||
((curr_x, curr_y, curr_z), side.inverse())
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if !visited.contains(&res) {
|
||||
visited.insert(res);
|
||||
println!("{:?}", res);
|
||||
queue.push(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
advent_of_code_macro::generate_tests!(
|
||||
day 18,
|
||||
parse,
|
||||
part_one,
|
||||
part_two,
|
||||
sample tests [64, 58],
|
||||
star tests [4300, 0]
|
||||
);
|
||||
@@ -0,0 +1,202 @@
|
||||
use std::collections::{BinaryHeap, HashSet};
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Blueprint {
|
||||
id: i64,
|
||||
ore_robot_cost: i64,
|
||||
clay_robot_cost: i64,
|
||||
obsidian_robot_cost: (i64, i64),
|
||||
geode_robot_cost: (i64, i64),
|
||||
}
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)]
|
||||
struct Search {
|
||||
time_left: i64,
|
||||
ore: i64,
|
||||
ore_robots: i64,
|
||||
clay: i64,
|
||||
clay_robots: i64,
|
||||
obsidian: i64,
|
||||
obsidian_robots: i64,
|
||||
geode: i64,
|
||||
geode_robots: i64,
|
||||
}
|
||||
impl std::cmp::Ord for Search {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
(self.geode_robots * self.time_left + self.geode)
|
||||
.cmp(&(other.geode_robots * other.time_left + other.geode))
|
||||
.then_with(|| self.obsidian_robots.cmp(&other.obsidian_robots))
|
||||
.then_with(|| self.clay_robots.cmp(&other.clay_robots))
|
||||
.then_with(|| self.ore_robots.cmp(&other.ore_robots))
|
||||
}
|
||||
}
|
||||
impl std::cmp::PartialOrd for Search {
|
||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||
Some(self.cmp(other))
|
||||
}
|
||||
}
|
||||
type Data = Vec<Blueprint>;
|
||||
type Output = i64;
|
||||
fn parse(input: &str) -> Data {
|
||||
input
|
||||
.lines()
|
||||
.map(|l| Blueprint {
|
||||
id: get_id(l),
|
||||
ore_robot_cost: get_cost_one(l, "ore"),
|
||||
clay_robot_cost: get_cost_one(l, "clay"),
|
||||
obsidian_robot_cost: get_cost_two(l, "obsidian"),
|
||||
geode_robot_cost: get_cost_two(l, "geode"),
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
fn max_geodes(bp: &Blueprint, initial_search: Search) -> Output {
|
||||
let mut queue: BinaryHeap<Search> = BinaryHeap::new();
|
||||
let mut visited: HashSet<Search> = HashSet::new();
|
||||
queue.push(initial_search);
|
||||
let mut max = 0;
|
||||
while let Some(search) = queue.pop() {
|
||||
if search.time_left == 0 {
|
||||
println!("{:?}, {:?}", max, search);
|
||||
max = std::cmp::max(search.geode, max);
|
||||
}
|
||||
{
|
||||
let mut temp_search = search;
|
||||
while temp_search.ore >= bp.ore_robot_cost {
|
||||
temp_search.ore -= bp.ore_robot_cost;
|
||||
temp_search.ore_robots += 1;
|
||||
}
|
||||
if !visited.contains(&temp_search) {
|
||||
visited.insert(temp_search);
|
||||
queue.push(temp_search);
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp_search = search;
|
||||
while temp_search.ore >= bp.clay_robot_cost {
|
||||
temp_search.ore -= bp.clay_robot_cost;
|
||||
temp_search.clay_robots += 1;
|
||||
}
|
||||
if !visited.contains(&temp_search) {
|
||||
visited.insert(temp_search);
|
||||
queue.push(temp_search);
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp_search = search;
|
||||
while temp_search.ore >= bp.obsidian_robot_cost.0
|
||||
&& temp_search.clay >= bp.obsidian_robot_cost.1
|
||||
{
|
||||
temp_search.ore -= bp.obsidian_robot_cost.0;
|
||||
temp_search.clay -= bp.obsidian_robot_cost.1;
|
||||
temp_search.obsidian_robots += 1;
|
||||
}
|
||||
if !visited.contains(&temp_search) {
|
||||
visited.insert(temp_search);
|
||||
queue.push(temp_search);
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp_search = search;
|
||||
while temp_search.ore >= bp.geode_robot_cost.0
|
||||
&& temp_search.obsidian >= bp.geode_robot_cost.1
|
||||
{
|
||||
temp_search.ore -= bp.geode_robot_cost.0;
|
||||
temp_search.obsidian -= bp.geode_robot_cost.1;
|
||||
temp_search.geode_robots += 1;
|
||||
}
|
||||
if !visited.contains(&temp_search) {
|
||||
visited.insert(temp_search);
|
||||
queue.push(temp_search);
|
||||
}
|
||||
}
|
||||
{
|
||||
let mut temp_search = search;
|
||||
temp_search.ore += temp_search.ore_robots;
|
||||
temp_search.clay += temp_search.clay_robots;
|
||||
temp_search.obsidian += temp_search.obsidian_robots;
|
||||
temp_search.geode += temp_search.geode_robots;
|
||||
temp_search.time_left -= 1;
|
||||
if !visited.contains(&temp_search) {
|
||||
visited.insert(temp_search);
|
||||
queue.push(temp_search);
|
||||
}
|
||||
}
|
||||
}
|
||||
max
|
||||
}
|
||||
fn part_one(data: Data) -> Output {
|
||||
for bp in data {
|
||||
let res = max_geodes(
|
||||
&bp,
|
||||
Search {
|
||||
time_left: 24,
|
||||
ore: 0,
|
||||
ore_robots: 1,
|
||||
clay: 0,
|
||||
clay_robots: 0,
|
||||
obsidian: 0,
|
||||
obsidian_robots: 0,
|
||||
geode: 0,
|
||||
geode_robots: 0,
|
||||
},
|
||||
);
|
||||
dbg!(res);
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
fn part_two(data: Data) -> Output {
|
||||
todo!()
|
||||
}
|
||||
|
||||
advent_of_code_macro::generate_tests!(
|
||||
day 19,
|
||||
parse,
|
||||
part_one,
|
||||
part_two,
|
||||
sample tests [0, 0],
|
||||
star tests [0, 0]
|
||||
);
|
||||
|
||||
// helper funtions for parsing
|
||||
fn get_cost_one(l: &str, t: &str) -> i64 {
|
||||
l.split_once(&format!("{} robot costs ", t))
|
||||
.unwrap()
|
||||
.1
|
||||
.split_once(' ')
|
||||
.unwrap()
|
||||
.0
|
||||
.parse()
|
||||
.unwrap()
|
||||
}
|
||||
fn get_cost_two(l: &str, t: &str) -> (i64, i64) {
|
||||
(
|
||||
l.split_once(&format!("{} robot costs ", t))
|
||||
.unwrap()
|
||||
.1
|
||||
.split_once(' ')
|
||||
.unwrap()
|
||||
.0
|
||||
.parse()
|
||||
.unwrap(),
|
||||
l.split_once(&format!("{} robot costs ", t))
|
||||
.unwrap()
|
||||
.1
|
||||
.split_once("and ")
|
||||
.unwrap()
|
||||
.1
|
||||
.split_once(' ')
|
||||
.unwrap()
|
||||
.0
|
||||
.parse()
|
||||
.unwrap(),
|
||||
)
|
||||
}
|
||||
fn get_id(l: &str) -> i64 {
|
||||
l.split_once(' ')
|
||||
.unwrap()
|
||||
.1
|
||||
.split_once(':')
|
||||
.unwrap()
|
||||
.0
|
||||
.parse()
|
||||
.unwrap()
|
||||
}
|
||||
@@ -14,3 +14,7 @@ mod day_12;
|
||||
mod day_13;
|
||||
mod day_14;
|
||||
mod day_15;
|
||||
mod day_16;
|
||||
mod day_17;
|
||||
mod day_18;
|
||||
mod day_19;
|
||||
|
||||
Reference in New Issue
Block a user