$instruction) { $altered_instructions = $original_instructions; switch ($instruction[0]) { case 'jmp': $altered_instructions[$idx][0] = 'nop'; break; case 'nop': $altered_instructions[$idx][0] = 'jmp'; break; } if (terminates_correctly($altered_instructions)) return get_acc($altered_instructions); } return 0; } #[Pure] function terminates_correctly(array $instructions): bool { $acc = 0; $ip = 0; $execution_count = []; while ($ip < count($instructions)) { if (array_key_exists($ip, $execution_count) && $execution_count[$ip] != 0) return false; $execution_count[$ip] = 1; [$acc, $ip] = run_instruction($instructions[$ip], [$acc, $ip]); } return true; } #[Pure] function get_acc(array $instructions): int { $acc = 0; $ip = 0; $execution_count = []; while ($ip < count($instructions)) { if (array_key_exists($ip, $execution_count) && $execution_count[$ip] != 0) return $acc; $execution_count[$ip] = 1; [$acc, $ip] = run_instruction($instructions[$ip], [$acc, $ip]); } return $acc; } function run_instruction(array $instruction, array $regs): array { [$inst, $arg] = $instruction; [$acc, $ip] = $regs; switch ($inst) { case 'acc': $acc += $arg; $ip += 1; break; case 'jmp': $ip += $arg; break; case 'nop': $ip += 1; break; } // print 'Executed ' . $inst . ', $acc = ' . $acc . ', $ip = ' . $ip . "\n"; return [$acc, $ip]; } function parse_instructions(array $instructions): array { $parsed_instructions = []; foreach ($instructions as $instruction) { if (preg_match('/^(acc|jmp|nop) ([+\-\d]+)$/', trim($instruction), $matches)) { [, $inst, $arg] = $matches; $parsed_instructions[] = [$inst, $arg]; } } return $parsed_instructions; }