function getSignal($signal) { global $paths; if (is_numeric($signal)) { return intval($signal); } $inst = explode(' ', $paths[$signal]); if (count($inst) == 1) { return getSignal($paths[$signal]); } if (count($inst) == 2) { list(, $a) = $inst; $paths[$signal] = 65535 - getSignal($a); return $paths[$signal]; } list($a, $op, $b) = $inst; $a = getSignal($a); $b = getSignal($b); switch ($op) { case 'AND': $paths[$signal] = $a & $b; break; case 'OR': $paths[$signal] = $a | $b; break; case 'LSHIFT': $paths[$signal] = $a << $b; break; case 'RSHIFT': $paths[$signal] = $a >> $b; break; } return $paths[$signal]; }
function getSignal($wire) { global $wires; global $instructions; if (isset($wires[$wire])) { return $wires[$wire]; } $chunks = explode(' ', $instructions[$wire]); if (count($chunks) == 1) { if (is_numeric($chunks[0])) { $wires[$wire] = $chunks[0]; } else { $wires[$wire] = getSignal($chunks[0]); } return $wires[$wire]; } if (count($chunks) == 2) { $originalSignal = getSignal($chunks[1]); $wires[$wire] = ~$originalSignal & 0xffff; return $wires[$wire]; } else { if (is_numeric($chunks[0])) { $signal1 = $chunks[0]; } else { $signal1 = getSignal($chunks[0]); } if (is_numeric($chunks[2])) { $signal2 = $chunks[2]; } else { $signal2 = getSignal($chunks[2]); } switch ($chunks[1]) { case 'OR': $wires[$wire] = $signal1 | $signal2; break; case 'AND': $wires[$wire] = $signal1 & $signal2; break; case 'LSHIFT': $wires[$wire] = $signal1 << $signal2; break; case 'RSHIFT': $wires[$wire] = $signal1 >> $signal2; break; } return $wires[$wire]; } }
function execInstruction($instruction, &$circuit) { $exploded = explode(' ', $instruction); $wire = end($exploded); switch (count($exploded)) { case 3: $signal = getSignal($exploded[0], $circuit); break; case 4: // NOT $signal = ~getSignal($exploded[1], $circuit) & 65535; break; case 5: $signal1 = getSignal($exploded[0], $circuit); $signal2 = getSignal($exploded[2], $circuit); switch ($exploded[1]) { case 'AND': $signal = $signal1 & $signal2; break; case 'OR': $signal = $signal1 | $signal2; break; case 'LSHIFT': $signal = $signal1 << $signal2; break; case 'RSHIFT': $signal = $signal1 >> $signal2; break; } break; } $circuit[$wire] = $signal; }