Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// Build a tree
- /// 1) And visit it.
- /// 2) And fix the answer.
- ///
- class Node {
- num? value;
- Node? parent;
- String name;
- bool isLeaf = false;
- List<Node> children = [];
- List<String> childrenString = [];
- String op = '';
- Node(this.name);
- static final ops = {
- '+': (num a, num b) => a + b,
- '-': (num a, num b) => a - b,
- '*': (num a, num b) => a * b,
- '/': (num a, num b) => a / b,
- };
- buildTree(Map<String, Node> ns) {
- for (var c in childrenString) {
- var n = ns[c]!;
- n.parent = this;
- children.add(n);
- n.buildTree(ns);
- }
- }
- num get buildAnswer {
- if (isLeaf) return value!;
- if (value != null) return value!;
- value = ops[op]!(children.first.buildAnswer, children.last.buildAnswer);
- return value!;
- }
- markDirty() {
- value = null;
- if (name == 'root') return;
- parent!.markDirty();
- }
- pathFromRoot({List<Node> path = const []}) =>
- (name == 'root') ? path : parent!.pathFromRoot(path: [this, ...path]);
- applyCorrectionToPath(List<Node> path, {num correctVal = 0}) {
- if (name == 'humn') {
- value = correctVal;
- return value;
- }
- var pn = path.removeAt(0);
- var on = (children.first == pn) ? children.last : children.first;
- // Just for fun...
- correctVal = (op == '+')
- ? correctVal - on.value!
- : (op == '*')
- ? correctVal / on.value!
- : (op == '-')
- ? (pn == children.first)
- ? correctVal + on.value!
- : on.value! - correctVal
- : (pn == children.first)
- ? (correctVal * on.value!)
- : correctVal / on.value!;
- return pn.applyCorrectionToPath(path, correctVal: correctVal);
- }
- @override
- int get hashCode => name.hashCode; //!!!
- @override
- bool operator ==(Object other) => other is Node && other.name == name;
- }
- MapEntry<String, Node> fromString(String l) {
- var ps = l.split(RegExp(r':? '));
- var n = Node(ps.first);
- if (ps.length == 2) {
- n.value = int.parse(ps.last);
- n.isLeaf = true;
- } else {
- n.childrenString
- ..add(ps[1])
- ..add(ps[3]);
- n.op = ps[2];
- }
- return MapEntry(n.name, n);
- }
- part1(List<String> lines) {
- var ns = Map.fromEntries(lines.map((e) => fromString(e)));
- return (ns['root']!..buildTree(ns)).buildAnswer;
- }
- part2(List<String> lines) {
- var ns = Map.fromEntries(lines.map((e) => fromString(e)));
- var root = ns['root']!..buildTree(ns);
- var humn = ns['humn']!
- ..children = []
- ..isLeaf = true
- ..markDirty()
- ..value = 0;
- return (root
- ..op = '-' // Make the root work out the needed top level answer
- ..buildAnswer)
- .applyCorrectionToPath(humn.pathFromRoot());
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement