From 55371e1dc8d19adcbe014d8eed25001b00b0585a Mon Sep 17 00:00:00 2001 From: maneatingape <44142177+maneatingape@users.noreply.github.com> Date: Sat, 14 Sep 2024 00:03:07 +0200 Subject: [PATCH] Simplify cost checks --- README.md | 6 +- src/year2023/day17.rs | 136 ++++++++++++++++++++---------------------- 2 files changed, 69 insertions(+), 73 deletions(-) diff --git a/README.md b/README.md index 5c32d9d..0404076 100644 --- a/README.md +++ b/README.md @@ -53,7 +53,7 @@ Place input files in `input/yearYYYY/dayDD.txt` including leading zeroes. For ex ## Performance Benchmarks are measured using the built-in `cargo bench` tool run on an [Apple M2 Max][apple-link]. -All 225 solutions from 2023 to 2015 complete sequentially in **581 milliseconds**. +All 225 solutions from 2023 to 2015 complete sequentially in **580 milliseconds**. Interestingly 84% of the total time is spent on just 9 solutions. Performance is reasonable even on older hardware, for example a 2011 MacBook Pro with an [Intel i7-2720QM][intel-link] processor takes 3.5 seconds to run the same 225 solutions. @@ -62,7 +62,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro | Year | Benchmark (ms) | | --- | --: | -| [2023](#2023) | 7 | +| [2023](#2023) | 6 | | [2022](#2022) | 9 | | [2021](#2021) | 9 | | [2020](#2020) | 272 | @@ -94,7 +94,7 @@ Performance is reasonable even on older hardware, for example a 2011 MacBook Pro | 14 | [Parabolic Reflector Dish](https://adventofcode.com/2023/day/14) | [Source](src/year2023/day14.rs) | 632 | | 15 | [Lens Library](https://adventofcode.com/2023/day/15) | [Source](src/year2023/day15.rs) | 84 | | 16 | [The Floor Will Be Lava](https://adventofcode.com/2023/day/16) | [Source](src/year2023/day16.rs) | 826 | -| 17 | [Clumsy Crucible](https://adventofcode.com/2023/day/17) | [Source](src/year2023/day17.rs) | 2568 | +| 17 | [Clumsy Crucible](https://adventofcode.com/2023/day/17) | [Source](src/year2023/day17.rs) | 2379 | | 18 | [Lavaduct Lagoon](https://adventofcode.com/2023/day/18) | [Source](src/year2023/day18.rs) | 17 | | 19 | [Aplenty](https://adventofcode.com/2023/day/19) | [Source](src/year2023/day19.rs) | 100 | | 20 | [Pulse Propagation](https://adventofcode.com/2023/day/20) | [Source](src/year2023/day20.rs) | 6 | diff --git a/src/year2023/day17.rs b/src/year2023/day17.rs index 506a226..c8bb4c9 100644 --- a/src/year2023/day17.rs +++ b/src/year2023/day17.rs @@ -56,12 +56,15 @@ fn astar(grid: &Grid) -> u32 { let mut index = 0; let mut todo = (0..100).map(|_| Vec::with_capacity(1000)).collect::>(); - let mut cost = vec![[0_u32; 2]; heat.len()]; + let mut cost = vec![[u32::MAX; 2]; heat.len()]; // Start from the top left corner checking both vertical and horizontal directions. todo[0].push((0, 0, 0)); todo[0].push((0, 0, 1)); + cost[0][0] = 0; + cost[0][1] = 0; + loop { // All items in the same bucket have the same priority. while let Some((x, y, direction)) = todo[index % 100].pop() { @@ -83,90 +86,83 @@ fn astar(grid: &Grid) -> u32 { if direction == 0 { // We just moved vertically so now check both left and right directions. + // Each direction loop is the same: + // * Check to see if we gone out of bounds + // * Increase the cost by the "heat" of the square we've just moved into. + // * Check if we've already been to this location with a lower cost. + // * Add new state to priority queue. + // Left - { - let mut index = index; - let mut steps = steps; - - // Each direction loop is the same: - // * Check to see if we gone out of bounds - // * Increase the cost by the "heat" of the square we've just moved into. - // * Check if we've already been to this location with a lower cost. - // * Add new state to priority queue. - for i in 1..=U { - if i > x { - break; - } - - index -= 1; - steps += heat[index]; - - if i >= L && (cost[index][1] == 0 || steps < cost[index][1]) { - todo[heuristic(x - i, y, steps)].push((x - i, y, 1)); - cost[index][1] = steps; - } + let mut next = index; + let mut extra = steps; + + for i in 1..=U { + if i > x { + break; + } + + next -= 1; + extra += heat[next]; + + if i >= L && extra < cost[next][1] { + todo[heuristic(x - i, y, extra)].push((x - i, y, 1)); + cost[next][1] = extra; } } // Right - { - let mut index = index; - let mut steps = steps; - - for i in 1..=U { - if x + i >= width { - break; - } - - index += 1; - steps += heat[index]; - - if i >= L && (cost[index][1] == 0 || steps < cost[index][1]) { - todo[heuristic(x + i, y, steps)].push((x + i, y, 1)); - cost[index][1] = steps; - } + let mut next = index; + let mut extra = steps; + + for i in 1..=U { + if x + i >= width { + break; + } + + next += 1; + extra += heat[next]; + + if i >= L && extra < cost[next][1] { + todo[heuristic(x + i, y, extra)].push((x + i, y, 1)); + cost[next][1] = extra; } } } else { // We just moved horizontally so now check both up and down directions. // Up - { - let mut index = index; - let mut steps = steps; - - for i in 1..=U { - if i > y { - break; - } - - index -= width; - steps += heat[index]; - - if i >= L && (cost[index][0] == 0 || steps < cost[index][0]) { - todo[heuristic(x, y - i, steps)].push((x, y - i, 0)); - cost[index][0] = steps; - } + let mut next = index; + let mut extra = steps; + + for i in 1..=U { + if i > y { + break; + } + + next -= width; + extra += heat[next]; + + if i >= L && extra < cost[next][0] { + todo[heuristic(x, y - i, extra)].push((x, y - i, 0)); + cost[next][0] = extra; } } // Down - { - let mut index = index; - let mut steps = steps; - - for i in 1..=U { - if y + i >= height { - break; - } - - index += width; - steps += heat[index]; - - if i >= L && (cost[index][0] == 0 || steps < cost[index][0]) { - todo[heuristic(x, y + i, steps)].push((x, y + i, 0)); - cost[index][0] = steps; - } + let mut next = index; + let mut extra = steps; + + for i in 1..=U { + if y + i >= height { + break; + } + + next += width; + extra += heat[next]; + + if i >= L && extra < cost[next][0] { + todo[heuristic(x, y + i, extra)].push((x, y + i, 0)); + cost[next][0] = extra; } } }