From ede5141783e8d7ff8870c8de01435f8d9302431f Mon Sep 17 00:00:00 2001 From: Tobias Marschner Date: Wed, 10 Apr 2024 07:39:06 +0200 Subject: [PATCH] Change integer sizes to significantly reduce memory footprint --- 2022/day19-part1/src/main.rs | 70 +++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/2022/day19-part1/src/main.rs b/2022/day19-part1/src/main.rs index aab0646..33297a3 100644 --- a/2022/day19-part1/src/main.rs +++ b/2022/day19-part1/src/main.rs @@ -3,16 +3,16 @@ use std::{cmp::Ordering, collections::HashSet}; #[derive(Debug)] struct Blueprint { // The id and costs parsed from the input. - id: usize, - ore_robot_ore_cost: usize, - clay_robot_ore_cost: usize, - obsidian_robot_ore_cost: usize, - obsidian_robot_clay_cost: usize, - geode_robot_ore_cost: usize, - geode_robot_obsidian_cost: usize, + id: u16, + ore_robot_ore_cost: u16, + clay_robot_ore_cost: u16, + obsidian_robot_ore_cost: u16, + obsidian_robot_clay_cost: u16, + geode_robot_ore_cost: u16, + geode_robot_obsidian_cost: u16, // The maximal number of geodes that can be collected by this blueprint. // Initialized to 0 and overwritten by the solver, once it concludes. - optimal_geode_count: usize, + optimal_geode_count: u16, } impl Blueprint { @@ -123,7 +123,8 @@ impl Blueprint { println!(" initial next_hs.len(): {}", next_hs.len()); // For the last few timesteps, pruning isn't worth it. Just calculate the rest in that case. - if ts > 3 { + let worst_case = next_hs.len() * 5usize.pow(ts as u32); + if worst_case > 100_000_000 && ts > 4 { // Pruning runs in a nested loop over the elements of the set. // In the inner loop we collect strictly inferior elements until we've met a // threshold of the original count. @@ -159,8 +160,8 @@ impl Blueprint { // Have we found enough elements yet? // Or have we reached the limit in terms of comparisons? if (strictly_inferior_hs.len() as f32) / initial_elems >= INNER_LOOP_CUTOFF - || comp_count >= TOTAL_COMP_COUNT - { + || comp_count >= TOTAL_COMP_COUNT { + // if comp_count >= TOTAL_COMP_COUNT { break; } } @@ -185,7 +186,10 @@ impl Blueprint { } } } else { - println!("Final 3 - no more pruning."); + println!( + "{} calculations left / timeslot {} - no need to prune.", + worst_case, ts + ); } println!(" final next_hs.len(): {}\n", next_hs.len()); } @@ -203,27 +207,27 @@ impl Blueprint { #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] struct RecursionState { // The currently active fleet of robots. - ore_robots: usize, - clay_robots: usize, - obsidian_robots: usize, - geode_robots: usize, + ore_robots: u8, + clay_robots: u8, + obsidian_robots: u8, + geode_robots: u8, // Our resources. - ore: usize, - clay: usize, - obsidian: usize, - geode: usize, + ore: u16, + clay: u16, + obsidian: u16, + geode: u16, // How much time is left in the simulation. - remaining_time: usize, + remaining_time: u8, } impl RecursionState { // Let one unit of time pass on this RecursionState. // Collects all the resources from the currently active robots. fn pass_time(&mut self) { - self.ore += self.ore_robots; - self.clay += self.clay_robots; - self.obsidian += self.obsidian_robots; - self.geode += self.geode_robots; + self.ore += self.ore_robots as u16; + self.clay += self.clay_robots as u16; + self.obsidian += self.obsidian_robots as u16; + self.geode += self.geode_robots as u16; // One unit of time passes. self.remaining_time -= 1; } @@ -347,13 +351,13 @@ fn main() { .collect::>() .iter() .map(|l| Blueprint { - id: l[1].trim_end_matches(':').parse::().unwrap(), - ore_robot_ore_cost: l[6].parse::().unwrap(), - clay_robot_ore_cost: l[12].parse::().unwrap(), - obsidian_robot_ore_cost: l[18].parse::().unwrap(), - obsidian_robot_clay_cost: l[21].parse::().unwrap(), - geode_robot_ore_cost: l[27].parse::().unwrap(), - geode_robot_obsidian_cost: l[30].parse::().unwrap(), + id: l[1].trim_end_matches(':').parse::().unwrap(), + ore_robot_ore_cost: l[6].parse::().unwrap(), + clay_robot_ore_cost: l[12].parse::().unwrap(), + obsidian_robot_ore_cost: l[18].parse::().unwrap(), + obsidian_robot_clay_cost: l[21].parse::().unwrap(), + geode_robot_ore_cost: l[27].parse::().unwrap(), + geode_robot_obsidian_cost: l[30].parse::().unwrap(), optimal_geode_count: 0, }) .collect::>(); @@ -370,6 +374,6 @@ fn main() { blueprints .iter() .map(|b| b.id * b.optimal_geode_count) - .sum::() + .sum::() ); }