Advertisement
mykdavies

AOC 2022 Day 21

Dec 21st, 2022 (edited)
1,031
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Dart 2.80 KB | None | 0 0
  1. /// Build a tree
  2. /// 1) And visit it.
  3. /// 2) And fix the answer.
  4. ///
  5.  
  6. class Node {
  7.   num? value;
  8.   Node? parent;
  9.   String name;
  10.   bool isLeaf = false;
  11.   List<Node> children = [];
  12.   List<String> childrenString = [];
  13.   String op = '';
  14.   Node(this.name);
  15.  
  16.   static final ops = {
  17.     '+': (num a, num b) => a + b,
  18.     '-': (num a, num b) => a - b,
  19.     '*': (num a, num b) => a * b,
  20.     '/': (num a, num b) => a / b,
  21.   };
  22.  
  23.   buildTree(Map<String, Node> ns) {
  24.     for (var c in childrenString) {
  25.       var n = ns[c]!;
  26.       n.parent = this;
  27.       children.add(n);
  28.       n.buildTree(ns);
  29.     }
  30.   }
  31.  
  32.   num get buildAnswer {
  33.     if (isLeaf) return value!;
  34.     if (value != null) return value!;
  35.     value = ops[op]!(children.first.buildAnswer, children.last.buildAnswer);
  36.     return value!;
  37.   }
  38.  
  39.   markDirty() {
  40.     value = null;
  41.     if (name == 'root') return;
  42.     parent!.markDirty();
  43.   }
  44.  
  45.   pathFromRoot({List<Node> path = const []}) =>
  46.       (name == 'root') ? path : parent!.pathFromRoot(path: [this, ...path]);
  47.  
  48.   applyCorrectionToPath(List<Node> path, {num correctVal = 0}) {
  49.     if (name == 'humn') {
  50.       value = correctVal;
  51.       return value;
  52.     }
  53.     var pn = path.removeAt(0);
  54.     var on = (children.first == pn) ? children.last : children.first;
  55.  
  56.     // Just for fun...
  57.     correctVal = (op == '+')
  58.         ? correctVal - on.value!
  59.         : (op == '*')
  60.             ? correctVal / on.value!
  61.             : (op == '-')
  62.                 ? (pn == children.first)
  63.                     ? correctVal + on.value!
  64.                     : on.value! - correctVal
  65.                 : (pn == children.first)
  66.                     ? (correctVal * on.value!)
  67.                     : correctVal / on.value!;
  68.  
  69.     return pn.applyCorrectionToPath(path, correctVal: correctVal);
  70.   }
  71.  
  72.   @override
  73.   int get hashCode => name.hashCode; //!!!
  74.  
  75.   @override
  76.   bool operator ==(Object other) => other is Node && other.name == name;
  77. }
  78.  
  79. MapEntry<String, Node> fromString(String l) {
  80.   var ps = l.split(RegExp(r':? '));
  81.   var n = Node(ps.first);
  82.   if (ps.length == 2) {
  83.     n.value = int.parse(ps.last);
  84.     n.isLeaf = true;
  85.   } else {
  86.     n.childrenString
  87.       ..add(ps[1])
  88.       ..add(ps[3]);
  89.     n.op = ps[2];
  90.   }
  91.   return MapEntry(n.name, n);
  92. }
  93.  
  94. part1(List<String> lines) {
  95.   var ns = Map.fromEntries(lines.map((e) => fromString(e)));
  96.   return (ns['root']!..buildTree(ns)).buildAnswer;
  97. }
  98.  
  99. part2(List<String> lines) {
  100.   var ns = Map.fromEntries(lines.map((e) => fromString(e)));
  101.   var root = ns['root']!..buildTree(ns);
  102.  
  103.   var humn = ns['humn']!
  104.     ..children = []
  105.     ..isLeaf = true
  106.     ..markDirty()
  107.     ..value = 0;
  108.  
  109.   return (root
  110.         ..op = '-' // Make the root work out the needed top level answer
  111.         ..buildAnswer)
  112.       .applyCorrectionToPath(humn.pathFromRoot());
  113. }
  114.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement