Day 16: The Floor Will Be Lava

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • @mykl@lemmy.world
    link
    fedilink
    1
    edit-2
    1 year ago

    Dart

    I’m cheating a bit by posting this as it does take 11s for the full part 2 solution, but having tracked down and eliminated the excessively long path for part 1, I can’t be bothered to do it again for part 2.

    I’m an idiot. Avoiding recursively adding the same points to the seen set dropped total runtime to a hair under 0.5s, so line-seconds are around 35.

    Map, Set>> seen = {};
    
    Map fire(List> grid, Point here, Point dir) {
      seen = {};
      return _fire(grid, here, dir);
    }
    
    Map, Set>> _fire(
        List> grid, Point here, Point dir) {
      while (true) {
        here += dir;
        if (!here.x.between(0, grid.first.length - 1) ||
            !here.y.between(0, grid.length - 1)) {
          return seen;
        }
        if (seen[here]?.contains(dir) ?? false) return seen;
        seen[here] = (seen[here] ?? >{})..add(dir);
    
        Point split() {
          _fire(grid, here, Point(-dir.y, -dir.x));
          return Point(dir.y, dir.x);
        }
    
        dir = switch (grid[here.y][here.x]) {
          '/' => Point(-dir.y, -dir.x),
          r'\' => Point(dir.y, dir.x),
          '|' => (dir.x.abs() == 1) ? split() : dir,
          '-' => (dir.y.abs() == 1) ? split() : dir,
          _ => dir,
        };
      }
    }
    
    parse(List lines) => lines.map((e) => e.split('').toList()).toList();
    
    part1(List lines) =>
        fire(parse(lines), Point(-1, 0), Point(1, 0)).length;
    
    part2(List lines) {
      var grid = parse(lines);
      var ret = 0.to(grid.length).fold(
          0,
          (s, t) => [
                s,
                fire(grid, Point(-1, t), Point(1, 0)).length,
                fire(grid, Point(grid.first.length, t), Point(-1, 0)).length
              ].max);
      return 0.to(grid.first.length).fold(
          ret,
          (s, t) => [
                s,
                fire(grid, Point(t, -1), Point(0, 1)).length,
                fire(grid, Point(t, grid.length), Point(0, -1)).length
              ].max);
    }