DEV Community

Discussion on: AoC Day 19: Go With the Flow

Collapse
 
jenovs profile image
Viktors Jenovs

Part 1 was straight forward execution of the program.

For Part 2 I wasn't really sure how we were expected to solve, but I went with rewriting asm code into php and then looked for some possible optimization (early break from the loop in my case).

<?php
$input = require_once 'readFile.php';

$ip = explode(' ', array_shift($input))[1][0];
$programm = array_values(array_map(function($str) {
  return explode(' ', preg_replace("/\r|\n/", "", $str));
}, $input));

function execute($r, $programm, $ip) {
  $asm = require_once 'opcodes.php';
  while (true) {
    [$opcode, $a, $b, $c] = $programm[$r[$ip]];
    $r = $asm[$opcode]($r, $a, $b, $c);
    $r[$ip]++;

    if (empty($programm[$r[$ip]])) {
      return $r[0];
    }
  }
}

function executeOptimized($r) {
  [$r0, $r1, $r2, $r3, $r4, $r5] = $r;

  $r1 = 6 * 22 + 6;
  $r3 = 2 * 2 * 19 * 11 + $r1;

  if ($r0 == 1) {
    $r1 = (27 * 28 + 29) * 30 * 14 * 32;
    $r3 += $r1;
    $r0 = 0;
  }

  while($r4 <= $r3) {
    $r5 = 1;

    while ($r5 <= $r3) {
      $r1 = $r4 * $r5;
      if ($r1 > $r3) {
        break;
      }
      if($r1 == $r3) {
        $r0 += $r4;
      }
      $r5++;
    }
    $r4++;
  }
  return $r0;
}

$r = [0, 0, 0, 0, 0, 0];

// echo "Part 1: " . execute($r, $programm, $ip) . "\n";
echo "Part 1: " . executeOptimized($r) . "\n";
$r[0] = 1;
echo "Part 2: " . executeOptimized($r) . "\n";
?>

opcodes.php

<?php
return [
  'addr' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] + $r[$b];
    return $r;
  },
  'addi' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] + $b;
    return $r;
  },
  'mulr' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] * $r[$b];
    return $r;
  },
  'muli' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] * $b;
    return $r;
  },
  'banr' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] & $r[$b];
    return $r;
  },
  'bani' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] & $b;
    return $r;
  },
  'borr' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] | $r[$b];
    return $r;
  },
  'bori' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] | $b;
    return $r;
  },
  'setr' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a];
    return $r;
  },
  'seti' => function($r, $a, $b, $c) {
    $r[$c] = $a;
    return $r;
  },
  'gtir' => function($r, $a, $b, $c) {
    $r[$c] = $a > $r[$b] ? 1 : 0;
    return $r;
  },
  'gtri' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] > $b ? 1 : 0;
    return $r;
  },
  'gtrr' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] > $r[$b] ? 1 : 0;
    return $r;
  },
  'eqir' => function($r, $a, $b, $c) {
    $r[$c] = $a == $r[$b] ? 1 : 0;
    return $r;
  },
  'eqri' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] == $b ? 1 : 0;
    return $r;
  },
  'eqrr' => function($r, $a, $b, $c) {
    $r[$c] = $r[$a] == $r[$b] ? 1 : 0;
    return $r;
  },
];
?>

readFile.php

<?php
$file = fopen("input.txt", "r") or exit("Unable to open file");

while(!feof($file)) {
  $array[] = fgets($file);
}

fclose($file);

return array_filter($array);
?>