Skip to content
advent of code 2018

day 16

chronal classification

approach

the sixteen opcodes are lambdas over a register tuple, built from three helpers (register/register, register/immediate, immediate/register) plus setr and seti. each one returns a new tuple instead of mutating. part 1 counts the samples that at least three opcodes explain.

part 2 starts every opcode number with all sixteen candidates and intersects them with the opcodes that fit each sample. then a queue of numbers with a single candidate left removes that candidate from every other number, repeating until each number maps to one opcode. the test program runs with the decoded table and register 0 is printed.

the trick

repeatedly take an opcode number that has only one candidate left and remove that candidate from all the others.

python
    q = deque([i for i in range(len(poss)) if len(poss[i]) == 1])
    done = {i for i in q}
    while q:
        for _ in range(len(q)):
            n = q.popleft()
            for i in range(len(poss)):
                if i != n:
                    poss[i] = poss[i] - poss[n]
                if i not in done and len(poss[i]) == 1:
                    q.append(i)
                    done.add(i)
    return [p.pop() for p in poss]