function value($var, $wires)
{
if (is_numeric($var)) return (int) $var;
if (is_int($wires[$var] ?? null)) return $wires[$var];
return null;
}
function compute($calc, $wires)
{
if (is_numeric($calc)) return (int) $calc;
if (count($calc) == 1) return !is_null($a = value($calc[0], $wires)) ? $a : $calc;
if ($calc[0] == "NOT") return !is_null($a = value($calc[1], $wires)) ? 65535 - $a : $calc;
$a = value($calc[0], $wires);
$b = value($calc[2], $wires);
if (is_null($a) || is_null($b)) return $calc;
switch ($calc[1]) {
case "AND": return $a & $b;
case "OR": return $a | $b;
case "LSHIFT": return $a << $b;
case "RSHIFT": return $a >> $b;
}
}
function solve($wires)
{
while (!is_int($wires["a"])) {
foreach ($wires as $letter=>&$calc) {
if (is_int($calc)) continue;
$wires[$letter] = compute($calc, $wires);
}
}
return $wires["a"];
}
// =============================================================================
// > SOLUTIONS
// =============================================================================
$wires = [];
foreach ($input->lines as $line) {
preg_match('/^([^-]+) -> ([a-z]+)$/', $line, $matches);
$wires[$matches[2]] = explode(" ", $matches[1]);
}
$solution_1 = solve($wires);
$wires["b"] = $solution_1;
$solution_2 = solve($wires);