Advent of code 2016/10
Ajax Direct

Answer

Part 1 :
Part 2 :
$chips    = [];
$compares = [];

// ==================================================
// > PARSE INPUT
// ==================================================
foreach ($input->lines as $line) {
    // Value
    if (preg_match("/value (\d+) goes to bot (\d+)/", $line, $matches)) {
        $chips["bot"][$matches[2]][] = $matches[1];
    }

    // Campares
    if (preg_match("/bot (\d+) gives low to (bot|output) (\d+) and high to (bot|output) (\d+)/", $line, $matches)) {
        $compares[$matches[1]] = [
            "low"  => [$matches[2], $matches[3]],
            "high" => [$matches[4], $matches[5]],
        ];
    }
}

// ==================================================
// > SIMULATE CHIPS MOVEMENT
// ==================================================
while (true) {
    $stop = true;

    foreach ($chips["bot"] as $bot=>$bot_chips) {
        if (count($bot_chips) != 2) continue;
        sort($bot_chips);

        if ($bot_chips[0] == 17 && $bot_chips[1] == 61) {
            $solution_1 = $bot;
        }

        $chips[$compares[$bot]["low"][0]][$compares[$bot]["low"][1]][] = $bot_chips[0];
        $chips[$compares[$bot]["high"][0]][$compares[$bot]["high"][1]][] = $bot_chips[1];
        $chips["bot"][$bot] = [];
        $stop = false;
    }

    if ($stop) break;
}

$solution_2 = set($chips["output"])->sortKeys()->slice(0, 3)->merge()->multiply();