this post was submitted on 17 Dec 2024
9 points (100.0% liked)

Advent Of Code

995 readers
4 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 17: Chronospatial Computer

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
[โ€“] [email protected] 1 points 2 weeks ago (1 children)

Raku

I spent way to much time tweaking the part 2 code to get a working solution. The solution itself is quite simple, though.

sub MAIN($input) {
    grammar Input {
        token TOP { <register-a> "\n" <register-b> "\n" <register-c> "\n\n" <program> "\n"* }
        token register-a { "Register A: " (\d+) }
        token register-b { "Register B: " (\d+) }
        token register-c { "Register C: " (\d+) }
        token program { "Program: " (\d)+%"," }
    }
    my $parsed = Input.parsefile($input);
    my $register-a = $parsed<register-a>[0].Int;
    my $register-b = $parsed<register-b>[0].Int;
    my $register-c = $parsed<register-c>[0].Int;
    my @program = $parsed<program>[0]>>.Int;

    my $part1-solution = run-program($register-a, $register-b, $register-c, @program).join(",");
    say "part1 solution: $part1-solution";

    my $part2-solution = search-for-quine(0, $register-b, $register-c, @program, 0);
    say "part2-solution: $part2-solution";
}

sub run-program($a, $b, $c, @program) {
    my ($register-a, $register-b, $register-c) Z= ($a, $b, $c);
    my $pc = 0;
    my @output;
    while $pc < @program.elems {
        my ($opcode, $operand) Z= @program[$pc, $pc+1];
        my $combo = (given $operand {
            when 0..3 { $operand }
            when 4 { $register-a }
            when 5 { $register-b }
            when 6 { $register-c }
            when 7 { Nil }
            default { say "invalid operand $operand"; exit; }
        });
        given $opcode {
            when 0 { $register-a = $register-a div (2 ** $combo); }
            when 1 { $register-b = $register-b +^ $operand; }
            when 2 { $register-b = $combo mod 8; }
            when 3 { $pc = $operand - 2 if $register-a != 0; }
            when 4 { $register-b = $register-b +^ $register-c; }
            when 5 { @output.push($combo mod 8); }
            when 6 { $register-b = $register-a div (2 ** $combo); }
            when 7 { $register-c = $register-a div (2 ** $combo); }
            default { say "invalid opcode $opcode"; exit; }
        }
        $pc += 2;
    }
    return @output;
}

sub search-for-quine($a, $b, $c, @program, $idx) {
    return $a if $idx == @program.elems;
    for ^8 {
        my $test-solution = $a * 8 + $_;
        my @output = run-program($test-solution, $b, $c, @program);
        my @program-slice = @program[*-1-$idx..*];
        if @program-slice eqv @output {
            my $found = search-for-quine($test-solution, $b, $c, @program, $idx+1);
            if $found {
                return $found;
            }
        }
    }
    # Time to back track...
    return False;
}
[โ€“] CameronDev 1 points 1 week ago

The one disappointing part of part 2 is that there seems to be only one way to do it, which makes it kinda boring from a solutions pov. It is a really nice one though, in the sense that it was (personally) quite hard, but also quite simple when it all clicked into place.