Please, señor software engineer was my father. Call me Bob.
swlabr
17!
p1 discussion
Simultaneously very fun and also the fucking worst.
Fun: Ooooh, I get to simulate a computer, exciting!
Worst: Literally 8 edge cases where fucking up even just one can fuck up your hour.
p2 discussion
I did this by hand. sort of. I mean I didn't code up something that found the answer.
Basically I looked at the program in the input and wrote it out, and realised that A was essentially a loop variable, where the number of iterations was the number of octal digits A would take to represent. The most significant octal digits (octits?) would determine the tail end of the output sequence, so to find the smallest A you can do a DFS starting from the MS octit. I did this by hand.
EDIT: code. Not gonna explain any of it.
class Comp {
List<int> reg;
List<int> prog;
int ip = 0;
List<int> output = [];
late List<(int, bool) Function()> ops;
int get combo => prog[ip + 1] < 4 ? prog[ip + 1] : reg[prog[ip + 1] - 4];
Comp(this.reg, this.prog) {
ops = [
() => (reg[0] = (reg[0] >> combo), false),
() => (reg[1] ^= prog[ip + 1], false),
() => (reg[1] = combo % 8, false),
() => (reg[0] != 0) ? (ip = prog[ip + 1], true) : (0, false),
() => (reg[1] ^= reg[2], false),
() {
output.add(combo % 8);
return (0, false);
},
() => (reg[1] = (reg[0] >> combo), false),
() => (reg[2] = (reg[0] >> combo), false)
];
}
compute() {
output.clear();
while (ip < prog.length) {
if (!ops[prog[ip]]().$2) {
ip += 2;
}
}
}
reset(int A) {
ip = 0;
reg[0] = A;
reg[1] = 0;
reg[2] = 0;
}
}
void d17(bool sub) {
List<String> input = getLines();
Comp c = Comp(
input.take(3).map((s) => s.split(" ").last).map(int.parse).toList(),
input.last.split(" ").last.split(",").map(int.parse).toList())
..compute();
print("Part a: ${c.output.join(",")}");
if (!sub) return;
List<int> sols = [];
bool dfs(int cur) {
bool found = false;
sols.add(cur);
int sol = sols.reduce((a, b) => 8 * a + b);
c..reset(sol)..compute();
if (c.prog
.whereIndexed((i, e) => i >= c.prog.length - c.output.length)
.foldIndexed(true, (i, p, e) => p && c.output[i] == e)) {
if (found = c.output.length == c.prog.length) {
print("Part b: $sol");
} else {
for (int i = 0; i < 8 && !(found = found || dfs(i)); i++) {}
}
}
sols.removeLast();
return found;
}
for (int a = 0; a < 8 && !dfs(a); a++) {}
}
16!
p1
I used A*, though mathematically I would have been fine with Dijkstra's. Also, here's how I remember how to spell Dijkstra: ijk is in alphabetical order.
p2
If you've implemented path/back tracking on a search algo before, this wasn't too bad, though instead of tracking best parent you need to track equivalently best parents. Woke AOC trying to normalise families with more than two parents, SMH
P2 complete
The issue with my code was that I didn't make a push atomic, i.e. I would move boxes even if their ancestors couldn't be pushed. Making a list of candidate boxes to push solved this.
Here's the visualisation of the complete solution, though it doesn't show the last 100 frames or so. Please forgive me
Day 15
p1
Pretty easy. Just check in the direction you want to push if you have space.
p2 DNF
Currently debugging with test cases from the subreddit. I’ve also created a shitty visualiser for it, stay tuned!
Oh yeah to be clear: I also find this kind of reporting to be disingenuous and disgusting.
NBC/the media really killing it with painting him as a self-radicalised spook.
I didn’t really know what they wanted in part 2, so…
lol
I made a pretty shitty animation to render the bots and paused it when the tree appeared. This took me way longer than if I had just looked at the 10000 entry text file that I had already made. If I have the energy I’ll make a screen recording.
One too many poop pills
Does a sealion have bootlicker nature? Ugh.