diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-05 00:07:13 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-07-05 00:07:13 +0200 |
| commit | 061792ee76fcf2c2de3b0e966e6f5324fc9fe7bd (patch) | |
| tree | ad11af99ea9ebc9afe2a3a55cc88775a337960ee /2022/19/common.rs | |
| parent | 6a717cd07577844a7d4183caa99b75149081d010 (diff) | |
| download | aoc-061792ee76fcf2c2de3b0e966e6f5324fc9fe7bd.tar.gz aoc-061792ee76fcf2c2de3b0e966e6f5324fc9fe7bd.zip | |
Some performance improvements
Diffstat (limited to '2022/19/common.rs')
| -rw-r--r-- | 2022/19/common.rs | 58 |
1 files changed, 35 insertions, 23 deletions
diff --git a/2022/19/common.rs b/2022/19/common.rs index bfeaa9b..cc11460 100644 --- a/2022/19/common.rs +++ b/2022/19/common.rs | |||
| @@ -122,48 +122,60 @@ pub fn most_geodes( | |||
| 122 | bp: &Blueprint, | 122 | bp: &Blueprint, |
| 123 | s: Status, | 123 | s: Status, |
| 124 | m: i32, | 124 | m: i32, |
| 125 | mem: &mut HashMap<(Status, i32), i32> | 125 | mem: &mut HashMap<(Status, i32), i32>, |
| 126 | lower_bound: i32 | ||
| 126 | ) -> i32 { | 127 | ) -> i32 { |
| 127 | if let Some(r) = mem.get(&(s, m)) { return *r; } | ||
| 128 | if m == 0 { return s.resources.geo; } | 128 | if m == 0 { return s.resources.geo; } |
| 129 | if m == 1 { return s.resources.geo + s.bots.geo; } | ||
| 130 | |||
| 131 | // Estimate how much we can get at most, assuming one geode bot | ||
| 132 | // can be built each turn from now on | ||
| 133 | let upper_bound = s.resources.geo + s.bots.geo + (m-1)*(m-2)/2; | ||
| 134 | if upper_bound <= lower_bound { return 0; } | ||
| 135 | |||
| 136 | if let Some(r) = mem.get(&(s, m)) { return *r; } | ||
| 129 | 137 | ||
| 130 | let mut new_status = s; | 138 | let mut new_status = s; |
| 131 | new_status.resources += &new_status.bots; | 139 | new_status.resources += &new_status.bots; |
| 132 | 140 | ||
| 133 | let mut result = most_geodes(bp, new_status, m-1, mem); | 141 | let mut result = 0; |
| 134 | 142 | ||
| 135 | if m > 4 && s.resources >= bp.ore_bot_cost { | 143 | if m > 1 && s.resources >= bp.geo_bot_cost { |
| 136 | new_status.resources -= &bp.ore_bot_cost; | 144 | new_status.resources -= &bp.geo_bot_cost; |
| 137 | new_status.bots.ore += 1; | 145 | new_status.bots.geo += 1; |
| 138 | result = max(result, most_geodes(bp, new_status, m-1, mem)); | 146 | result = most_geodes(bp, new_status, m-1, mem, result); |
| 139 | new_status.bots.ore -= 1; | ||
| 140 | new_status.resources += &bp.ore_bot_cost; | ||
| 141 | } | ||
| 142 | 147 | ||
| 143 | if m > 3 && s.resources >= bp.cla_bot_cost { | 148 | // If a geode bot can be built, it is always the best thing to do |
| 144 | new_status.resources -= &bp.cla_bot_cost; | 149 | mem.insert((s, m), result); |
| 145 | new_status.bots.cla += 1; | 150 | return result; |
| 146 | result = max(result, most_geodes(bp, new_status, m-1, mem)); | ||
| 147 | new_status.bots.cla -= 1; | ||
| 148 | new_status.resources += &bp.cla_bot_cost; | ||
| 149 | } | 151 | } |
| 150 | 152 | ||
| 151 | if m > 2 && s.resources >= bp.obs_bot_cost { | 153 | if m > 2 && s.resources >= bp.obs_bot_cost { |
| 152 | new_status.resources -= &bp.obs_bot_cost; | 154 | new_status.resources -= &bp.obs_bot_cost; |
| 153 | new_status.bots.obs += 1; | 155 | new_status.bots.obs += 1; |
| 154 | result = max(result, most_geodes(bp, new_status, m-1, mem)); | 156 | result = max(result, most_geodes(bp, new_status, m-1, mem, result)); |
| 155 | new_status.bots.obs -= 1; | 157 | new_status.bots.obs -= 1; |
| 156 | new_status.resources += &bp.obs_bot_cost; | 158 | new_status.resources += &bp.obs_bot_cost; |
| 157 | } | 159 | } |
| 158 | 160 | ||
| 159 | if m > 1 && s.resources >= bp.geo_bot_cost { | 161 | if m > 3 && s.resources >= bp.cla_bot_cost { |
| 160 | new_status.resources -= &bp.geo_bot_cost; | 162 | new_status.resources -= &bp.cla_bot_cost; |
| 161 | new_status.bots.geo += 1; | 163 | new_status.bots.cla += 1; |
| 162 | result = max(result, most_geodes(bp, new_status, m-1, mem)); | 164 | result = max(result, most_geodes(bp, new_status, m-1, mem, result)); |
| 163 | new_status.bots.geo -= 1; | 165 | new_status.bots.cla -= 1; |
| 164 | new_status.resources += &bp.geo_bot_cost; | 166 | new_status.resources += &bp.cla_bot_cost; |
| 165 | } | 167 | } |
| 166 | 168 | ||
| 169 | if m > 4 && s.resources >= bp.ore_bot_cost { | ||
| 170 | new_status.resources -= &bp.ore_bot_cost; | ||
| 171 | new_status.bots.ore += 1; | ||
| 172 | result = max(result, most_geodes(bp, new_status, m-1, mem, result)); | ||
| 173 | new_status.bots.ore -= 1; | ||
| 174 | new_status.resources += &bp.ore_bot_cost; | ||
| 175 | } | ||
| 176 | |||
| 177 | result = max(result, most_geodes(bp, new_status, m-1, mem, result)); | ||
| 178 | |||
| 167 | mem.insert((s, m), result); | 179 | mem.insert((s, m), result); |
| 168 | result | 180 | result |
| 169 | } | 181 | } |
