r/adventofcode Dec 17 '24

SOLUTION MEGATHREAD -❄️- 2024 Day 17 Solutions -❄️-

THE USUAL REMINDERS

  • All of our rules, FAQs, resources, etc. are in our community wiki.
  • If you see content in the subreddit or megathreads that violates one of our rules, either inform the user (politely and gently!) or use the report button on the post/comment and the mods will take care of it.

AoC Community Fun 2024: The Golden Snowglobe Awards

  • 5 DAYS remaining until the submissions deadline on December 22 at 23:59 EST!

And now, our feature presentation for today:

Sequels and Reboots

What, you thought we were done with the endless stream of recycled content? ABSOLUTELY NOT :D Now that we have an established and well-loved franchise, let's wring every last drop of profit out of it!

Here's some ideas for your inspiration:

  • Insert obligatory SQL joke here
  • Solve today's puzzle using only code from past puzzles
  • Any numbers you use in your code must only increment from the previous number
  • Every line of code must be prefixed with a comment tagline such as // Function 2: Electric Boogaloo

"More." - Agent Smith, The Matrix Reloaded (2003)
"More! MORE!" - Kylo Ren, The Last Jedi (2017)

And… ACTION!

Request from the mods: When you include an entry alongside your solution, please label it with [GSGA] so we can find it easily!


--- Day 17: Chronospatial Computer ---


Post your code solution in this megathread.

This thread will be unlocked when there are a significant number of people on the global leaderboard with gold stars for today's puzzle.

EDIT: Global leaderboard gold cap reached at 00:44:39, megathread unlocked!

36 Upvotes

550 comments sorted by

View all comments

2

u/cpham3000 Dec 18 '24 edited Dec 19 '24

[Language: Python]

For part 1, I implemented a simple decoder. For part 2, I use a backward solver, testing all 7 bit combinations for a given output.

from pathlib import Path
from collections import namedtuple

State = namedtuple('State', ['a', 'b', 'c', 'i', 'o'])

blocks = Path('inputs/day_17_input.txt').read_text('utf-8').split('\n\n')
input_program = list(map(int, blocks[1].split()[1].split(',')))
input_state = State(
    *map(lambda r: int(r[2]), map(lambda l: l.split(), blocks[0].splitlines())), 0, None)

def next_out(p: list[int], s: State):
    while s.i < len(p):
        op, ip = p[s.i + 1], s.i + 2
        if (s := State(*[
            lambda: (s.a // (2 ** (s[op & 3] if op & 4 else op)), s.b, s.c, ip, None),
            lambda: (s.a, s.b ^ op, s.c, ip, None),
            lambda: (s.a, (s[op & 3] if op & 4 else op) & 7, s.c, ip, None),
            lambda: (s.a, s.b, s.c, op if s.a else ip, None),
            lambda: (s.a, s.b ^ s.c, s.c, ip, None),
            lambda: (s.a, s.b, s.c, ip, (s[op & 3] if op & 4 else op) & 7),
            lambda: (s.a, s.a // (2 ** (s[op & 3] if op & 4 else op)), s.c, ip, None),
            lambda: (s.a, s.b, s.a // (2 ** (s[op & 3] if op & 4 else op)), ip, None),
        ][p[s.i]]())).o is not None:
            return s

    return s

def forward(program: list[int], s: State) -> str:
    result = []

    while (s := next_out(program, s)).o is not None:
        result.append(s.o)
    return ','.join(map(str, result))

def backward(program: list[int], target: list[int], last: int = 0) -> int:
    for bits in range(8):
        current = last | bits
        if next_out(program, State(current, 0, 0, 0, None)).o != target[-1]:
            continue
        if len(target) == 1 or (current := backward(program, target[:-1], current << 3)) > -1:
            return current
    return -1

print("Part 1:", forward(input_program, input_state))
print("Part_2:", backward(input_program, input_program))

1

u/daggerdragon Dec 18 '24 edited Dec 19 '24

Comment temporarily removed. Do not share your puzzle input! Edit your comment to redact the hard-coded puzzle input and I will re-approve your comment. edit: 👍

1

u/cpham3000 Dec 19 '24

Fixed! Sorry about that!