AoC Day 8 – Handheld Halting

This is a solution to Advent of Code 2020 day 8, written in Raku.

https://adventofcode.com/2020/day/8

Part One

Run your copy of the boot code. Immediately before any instruction is executed a second time, what value is in the accumulator?

Raku

This problem requires a very simple interpreter that keeps state of visited instruction pointers to spot an infinite loop.

  my @code = '8-input.txt'.IO.lines;

  my $seen = SetHash.new;
  my $accumulator = 0;
  my $ip = 0;

  loop {
      if $ip (elem) $seen {
          say "Infinite loop at {$ip}";
          say "Accumulator is {$accumulator}";
          last;
      }
      $seen.set($ip);

      my ($op, $arg) = @code[$ip].split(' ');

      given $op {
          when 'nop' { $ip++ }
          when 'acc' { $accumulator += $arg; $ip++ }
          when 'jmp' { $ip += $arg }
      }
  }
Infinite loop at 334
Accumulator is 1262

Part Two

Fix the program so that it terminates normally by changing exactly one jmp (to nop) or nop (to jmp). What is the value of the accumulator after the program terminates?

Raku

Part two uses a brute force search to find the statement change that allows program completion.

  my @code = '8-input.txt'.IO.lines;

  sub run(@stmts) {
      my $seen = SetHash.new;
      my $accumulator = 0;
      my $ip = 0;

      loop {
          return False if $ip (elem) $seen;
          $seen.set($ip);

          return $accumulator if $ip >= @stmts.elems;

          my ($op, $arg) = @stmts[$ip].split(' ');

          given $op {
              when 'nop' { $ip++ }
              when 'acc' { $accumulator += $arg; $ip++ }
              when 'jmp' { $ip += $arg }
          }
      }
  }

  say (^@code.elems).map(
      -> $n {
          my @stmts = flat @code;
          @stmts[$n] = @stmts[$n].trans('nop' => 'jmp', 'jmp' => 'nop');
          run @stmts
      }).grep(* > 0).first
1643
raku 
comments powered by Disqus