Advent of code 2024/5
Ajax Direct

Answer

Part 1 :
Part 2 :
[$rules, $pages] = $input->split("\n\n");

$rules = $rules->lines->reduce(function ($rules, $rule) {
    [$l, $r] = $rule->split("|");
    $rules[$l->int][$r->int] = true;
    $rules[$r->int][$l->int] = false;
    return $rules;
}, []);

function solve($rules, $lines, $good, $sort = null) {
    return $lines
    ->map(fn ($l) => $l->split(","))
    ->filter(function ($nums) use ($rules, $good) {
        for ($i = 0; $i < $nums->count(); $i++) {
            // Left check
            for ($l = 0; $l < $i; $l++) {
                if (!($rules[$nums[$l]->int][$nums[$i]->int]??true)) {
                    return !$good;
                }
            }
            // Right check
            for ($r = $i + 1; $r < $nums->count(); $r++) {
                if (!($rules[$nums[$i]->int][$nums[$r]->int]??true)) {
                    return !$good;
                }
            }
        }
        return $good;
    })
    ->map($sort)
    ->map(fn ($nums) => $nums[($nums->count() - 1) / 2]->int)
    ->sum();
}

// ==================================================
// > SOLVE
// ==================================================
$solution_1 = solve($rules, $pages->lines, true);

$solution_2 = solve($rules, $pages->lines, false, function ($nums) use ($rules) {
    return $nums->sort(fn ($l, $r) =>
        match ($rules[$l->int][$r->int] ?? null) {
            true => -1,
            false => 1,
            null => 0
        }
    )->values();
});