this post was submitted on 24 Dec 2024
13 points (100.0% liked)

Advent Of Code

920 readers
3 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

Day 24: Crossed Wires

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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] mykl 3 points 1 week ago* (last edited 1 week ago)

Dart

Not very happy with this, as for part 2 the code just told me which four pairs of bits of the output needed investigation and I then tediously worked through how they differed from the correct adder implementation in the debugger.

Spoilered as it is overly long and not very interesting.

spoiler

import 'package:collection/collection.dart';
import 'package:more/more.dart';

var nodes = <String, Node>{};

class Node {
  String name = '';
  bool? state;
  var outputGates = <String>[];
}

class Wire implements Node {
  @override
  String name;
  @override
  bool? state;
  @override
  var outputGates = <String>[];
  Wire(this.name, this.state);
  set() {
    for (var g in outputGates) {
      (nodes[g]! as Gate).set();
    }
  }
}

class Gate implements Node {
  String input1, input2, type;
  @override
  String name;
  @override
  bool? state;
  @override
  var outputGates = <String>[];
  Gate(this.name, this.input1, this.input2, this.type);
  set() {
    var a = nodes[input1]!.state;
    var b = nodes[input2]!.state;
    if (a == null || b == null) return;
    state = switch (type) { 'AND' => a && b, 'OR' => a || b, _ => a ^ b };
    for (var g in outputGates) {
      (nodes[g]! as Gate).set();
    }
  }
}

void setup(List<String> lines) {
  var parts = lines.splitAfter((e) => e.isEmpty);
  Map<String, Node> wires = Map.fromEntries(parts.first.skipLast(1).map((e) {
    var p = e.split(': ');
    return MapEntry(p[0], Wire(p[0], p[1] == '1'));
  }));
  nodes = Map.fromEntries(parts.last.map((e) {
    var p = e.split(' ');
    return MapEntry(p.last, Gate(p.last, p[0], p[2], p[1]));
  }));
  nodes.addAll(wires);
  for (var g in nodes.values) {
    if (g is! Gate) continue;
    nodes[g.input1]!.outputGates.add(g.name);
    nodes[g.input2]!.outputGates.add(g.name);
  }
}

String line(String s) => nodes.keys
    .where((e) => e.startsWith(s))
    .sorted()
    .reversed
    .map((e) => nodes[e]!.state! ? '1' : '0')
    .join('');

part1(List<String> lines) {
  setup(lines);
  nodes.values.whereType<Wire>().forEach((e) => e.set());
  return int.parse(line('z'), radix: 2);
}

part2(List<String> lines) {
  setup(lines);
  var bits = nodes.keys.count((e) => e.startsWith('x'));
  for (var b in 0.to(bits)) {
    nodes.values.whereType<Gate>().forEach((e) => e.state = null);
    nodes.values.whereType<Wire>().forEach(((e) => e.state = false));
    nodes['y${b.toString().padLeft(2, "0")}']!.state = true;
    nodes.values.whereType<Wire>().forEach((e) => e.set());
    print('${line("x")}\t${line("y")}\t${line("z")}\t$b');
    var output = line('z');
    for (var i in 0.to(bits)) {
      if (output[bits - i] != ((i == b) ? "1" : "0")) print(i);
    }
  }
  tree('z05');
  tree('z06');
  // Add break point here and inspect and solve manually using `tree`.
  print('break here');
}

tree(String s, {indent = ''}) {
  var here = nodes[s]!;
  if (here is Wire) {
    print('$indent${here.name} (wire)');
    return;
  }
  here as Gate;
  print('$indent${here.name} ${here.type}');
  tree(here.input1, indent: indent + '| ');
  tree(here.input2, indent: indent + '| ');
}