Day 10: Hoof It

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
    arrow-up
    1
    ·
    edit-2
    2 days ago

    Dart

    I dug out the hill-climbing trail-walking code from 2022 Day 12, put it up on blocks, and stripped all the weirdness out of it.

    Ended up with just a simple flood-fill from each trailhead, so it turns out I only actually used the Graph and Node classes which I then also stripped out…

    import 'dart:math';
    import 'package:collection/collection.dart';
    import 'package:more/more.dart';
    
    late Map<Point, int> nodes;
    late Map<Point, List> nexts;
    
    /// Parse the lines, build up nodes and nexts, return starts.
    List<Point> parse(ls) {
      nodes = {
        for (var y in 0.to(ls.length))
          for (var x in 0.to(ls.first.length)) Point(x, y): int.parse(ls[y][x])
      };
      nexts = Map.fromEntries(nodes.keys.map((n) => MapEntry(
          n,
          [Point(0, 1), Point(0, -1), Point(1, 0), Point(-1, 0)]
              .map((d) => n + d)
              .where((d) => (nodes[d] ?? -1) - nodes[n]! == 1)
              .toList())));
      return nodes.keys.where((e) => nodes[e] == 0).toList();
    }
    
    /// Given a starting node, return all valid paths to any '9' on the grid.
    Set paths(Point here, [Set sofar = const {}]) {
      if (nodes[here]! == 9) return {sofar};
      return nexts[here]!
          .where((e) => !sofar.contains(e))
          .fold({}, (s, f) => s..addAll(paths(f, sofar.toSet()..add(f))));
    }
    
    /// Finds all paths from each start, then apply the fn to each and sum.
    count(lines, int Function(Set) fn) => parse(lines).map(paths).map<int>(fn).sum;
    
    part1(lines) => count(lines, (e) => e.map((p) => p.last).toSet().length);
    part2(lines) => count(lines, (e) => e.length);