• 67 Posts
  • 469 Comments
Joined 1 year ago
cake
Cake day: June 13th, 2023

help-circle













  • Nim

    Part 1 was just a simple search. Part 2 looked like it just needed a trivial modification, but with the removal of the one-way tiles, the result I was getting was getting for the example was too large. I switched to a different method of determining the path length, but didn’t yet figure out what what I had been doing wrong. Since the search space was now significantly larger, my part 2 code took almost an hour to come up with the answer.

    I rewrote part 2 to simplify the maze into a graph with a node for each intersection and for the start and goal tiles, with edge costs equal to the path length between each. This resulted in significantly faster iteration (17 seconds instead of 52 minutes), but didn’t actually reduce the search space. I’m assuming there’s some clever optimization that can be done here, but I’m not sure what it is.

    The rewrite was still getting the wrong answer, though. I eventually figured out that it was including paths that didn’t actually reach the goal, as long as they didn’t revisit any nodes. I changed my recursive search function to return a large negative result at dead ends, which fixed the issue.


  • Nim

    I sorted the bricks by their lower Z coordinate, then tried to move each of them downward, doing collision checks against all the others along the way. Once a level with collisions was found, I recorded each colliding brick as a supporter of the falling brick.

    For part 1, I made another table of which other bricks each brick was supporting. Any bricks that weren’t the sole support for any other bricks were counted as safe to disintegrate.

    For part 2, I sorted the bricks again after applying gravity. For each brick, I included it in a set of bricks that would fall if it were removed, then checked the others further down the list to see if they had any non-falling supporters. Those that didn’t would be added to the falling set.

    Initially I was getting an answer for part 2 that was too high. I turned out that I was counting bricks that were on the ground as being unsupported, so some of them were getting included in the falling sets for their neighbors. Adding a z-level check fixed this.

    Both of these have room for optimization, but non-debug builds run 0.5s and 1.0s respectively, so I didn’t feel the need to write an octree implementation or anything.


  • Nim

    My part 2 solution assumes the input has an unimpeded shortest path from the center of each garden section to its corner, and to the center of its neighbor. The possible destinations will form a diamond pattern, with “radius” equal to the number of steps. I broke down the possible section permutations:

    • Sections that are completely within the interior of the diamond

      • Even number of sections away from the starting section
      • Odd number of sections away from the starting section
    • Sections containing the points of the diamond

    • Depending on the number of steps, there may be sections adjacent to the point sections, that have two corners outside of the diamond

    • Edge sections. These will form a zig-zag pattern to cover the diamond boundary.

      • “Near” edge sections. These are the parts of the zig-zag nearer to the center of the diamond.
      • “Far” edge sections. These won’t occur if the edge of the diamond passes perfectly through the corners of the near edge sections.

    I determined how many of each of these should be present based on the number of steps, used my code from part 1 to get a destination count for each type, and then added them all up.