78 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
 | 
						|
 | 
						|
const MODE_POSITION = 0;
 | 
						|
const MODE_IMMEDIATE = 1;
 | 
						|
 | 
						|
$input = explode(',', file_get_contents('input.txt'));
 | 
						|
 | 
						|
function debug($message)
 | 
						|
{
 | 
						|
    echo $message."\n";
 | 
						|
}
 | 
						|
 | 
						|
function run_opcode(array $input, $first_input = 1)
 | 
						|
{
 | 
						|
    $i = 0;
 | 
						|
    $output = 0;
 | 
						|
    do {
 | 
						|
        [$instruction, $first, $second, $position] = array_slice($input, $i, 4);
 | 
						|
        $instruction = str_pad($instruction, 5, '0', STR_PAD_LEFT);
 | 
						|
        $operation = (int) substr($instruction, -2);
 | 
						|
        $modes = array_map('intval', str_split(strrev(substr($instruction, 0, 3))));
 | 
						|
        $first = (int) ($modes[0] === MODE_IMMEDIATE ? $first : $input[$first]);
 | 
						|
        $second = (int) ($modes[1] === MODE_IMMEDIATE ? $second : $input[$second]);
 | 
						|
        switch ($operation) {
 | 
						|
            case 1:
 | 
						|
                $input[$position] = $first + $second;
 | 
						|
                debug(sprintf('Operation 1 : putting %s + %s = %s in position %s', $first, $second, ($first + $second), $position));
 | 
						|
                $i += 4;
 | 
						|
                break;
 | 
						|
            case 2:
 | 
						|
                $input[$position] = $first * $second;
 | 
						|
                debug(sprintf('Operation 1 : putting %s * %s = %s in position %s', $first, $second, ($first * $second), $position));
 | 
						|
                $i += 4;
 | 
						|
                break;
 | 
						|
            case 3:
 | 
						|
                $input[$input[$i+1]] = $first_input;
 | 
						|
                debug(sprintf('Operation 3 : putting %s in position %s', $first_input, $input[$i + 1]));
 | 
						|
                $i += 2;
 | 
						|
                break;
 | 
						|
            case 4:
 | 
						|
                $output = $input[$input[$i+1]];
 | 
						|
                debug(sprintf('Operation 4 : Outputting %s', $output));
 | 
						|
                $i += 2;
 | 
						|
                break;
 | 
						|
            case 5:
 | 
						|
                if ($first != 0) {
 | 
						|
                    $i = $second;
 | 
						|
                } else {
 | 
						|
                    $i += 3;
 | 
						|
                }
 | 
						|
                break;
 | 
						|
            case 6:
 | 
						|
                if ($first == 0) {
 | 
						|
                    $i = $second;
 | 
						|
                } else {
 | 
						|
                    $i += 3;
 | 
						|
                }
 | 
						|
                break;
 | 
						|
            case 7:
 | 
						|
                $input[$position] = $first < $second ? 1 : 0;
 | 
						|
                $i += 4;
 | 
						|
                break;
 | 
						|
            case 8:
 | 
						|
                $input[$position] = $first == $second ? 1 : 0;
 | 
						|
                $i += 4;
 | 
						|
                break;
 | 
						|
            case 99:
 | 
						|
                return $output;
 | 
						|
                exit;
 | 
						|
            default:
 | 
						|
                echo 'unknown operation : ' . $operation . '('.$i.')';
 | 
						|
                exit;
 | 
						|
        }
 | 
						|
    } while ($input[$i] !== 99);
 | 
						|
 | 
						|
    return $output;
 | 
						|
} |