<?php declare(strict_types=1); use Illuminate\\Support\\Collection; \$input = <<<\'PHP\' 47|53 97|13 97|61 97|47 75|29 61|13 75|53 29|13 97|29 53|29 61|53 97|53 61|29 47|13 75|47 97|75 47|61 75|61 47|29 75|13 53|13 75,47,61,53,29 97,61,53,29,13 75,29,13 75,97,47,61,53 61,13,29 97,13,75,29,47 PHP; [\$rules, \$updates] = explode(\"\\n\\n\", \$input); \$rules = Collection::make(array_map(static fn (string \$rule): Rule => Rule::fromNotation(\$rule), explode(\"\\n\", \$rules))); \$updates = Collection::make(array_map(static fn (string \$update): Update => Update::fromNotation(\$update), explode(\"\\n\", \$updates))); return \$updates ->filter(static fn (Update \$update): bool => ! \$update->validate(\$rules)) ->map(static fn (Update \$update): Update => \$update->reorder(\$rules)) ->map(static fn (Update \$update): int => \$update->middle()) ->sum(); final readonly class Rule \{ public function __construct( public int \$before, public int \$after, ) \{\} public function appliesTo(Update \$update): bool \{ return \$update->pages->contains(\$this->after) && \$update->pages->contains(\$this->before); \} public function validate(Update \$update): bool \{ return \$update->pages->search(\$this->before, true) <= \$update->pages->search(\$this->after, true); \} public function hasBoth(int \$a, int \$b): bool \{ return (\$this->after === \$a && \$this->before === \$b) || (\$this->after === \$b && \$this->before === \$a); \} public static function fromNotation(string \$notation): self \{ [\$left, \$right] = explode(\'|\', \$notation, 2); return new self((int) \$left, (int) \$right); \} \} final readonly class Update \{ /** * @param Collection<array-key, int> \$pages */ public function __construct( public Collection \$pages, ) \{\} public function middle(): int \{ return \$this->pages->get((int) floor(\\count(\$this->pages) / 2)); \} /** * @param Collection<array-key, Rule> \$rules */ public function validate(Collection \$rules): bool \{ return \$rules->every(fn (Rule \$rule): bool => ! \$rule->appliesTo(\$this) || \$rule->validate(\$this)); \} public function reorder(Collection \$rules): self \{ return new self( \$this->pages ->sort(static function (int \$a, int \$b) use (\$rules): int \{ /** @var Rule \$rule */ \$rule = \$rules->firstOrFail(static fn (Rule \$rule): bool => \$rule->hasBoth(\$a, \$b)); return \$rule->before === \$a && \$rule->after === \$b ? -1 : 1; \}) ->values(), ); \} public static function fromNotation(string \$notation): self \{ return new self(Collection::make(array_map(\'intval\', explode(\',\', \$notation)))); \} \}