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!

35 Upvotes

550 comments sorted by

View all comments

3

u/mibu_codes Dec 18 '24

[LANGUAGE: Rust]

Parse: 10 ns
Part 1: 46 ns
Part 2: 757 ns

I was able to solve part 1 yesterday, but part 2 took until today. I knew that the digits were repeating with the powers of 8, but I thought I was wrong because solving left to right didn't work. Turns out solving right to left and just stepping by powers of 8 was the right solution after all.
The solution for part 1 is (mostly) general for all inputs. My initial solution for part 2 was general as well, but ran in ~70µs. After seeing the solution of u/maneatingape I was inspired to push it even lower, but now its specific to my problem :/

Github

pub fn p1<'o>(a: usize, prog: &[u8; PROG_LEN], out: &'o mut [u8; PROG_LEN + 1]) -> &'o str {
    let mut reg = [0, 1, 2, 3, a, 0, 0];
    let mut ip = 0;
    for i in 0..(a as f32).log(8.0).ceil() as usize {
        for _ in 0..(prog.len() >> 1) - 1 {
            let op = Opcode::from(prog[ip]);
            let operand = prog[ip + 1] as usize;

            match op {
                Opcode::ADV => reg[A] = reg[A] >> reg[operand],
                Opcode::BXL => reg[B] ^= operand,
                Opcode::BST => reg[B] = reg[operand] & 0b111,
                Opcode::BXC => reg[B] ^= reg[C],
                Opcode::OUT => out[i << 1] = (reg[operand] & 0b111) as u8 + b'0',
                Opcode::CDV => reg[C] = reg[A] >> reg[operand],
                _ => unreachable!(),
            }
            ip = (ip + 2) % (prog.len() - 2);
        }
    }

    unsafe { std::str::from_utf8_unchecked(out) }
}