Created
December 8, 2023 12:37
-
-
Save maartenpaauw/b4fd0821b52d079e33cdf5dbfda0d42f to your computer and use it in GitHub Desktop.
Advent of Code 2023 - Day 8
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Illuminate\Support\Collection; | |
use Illuminate\Support\Str; | |
use Illuminate\Support\Stringable; | |
$input = "LR | |
11A = (11B, XXX) | |
11B = (XXX, 11Z) | |
11Z = (11B, XXX) | |
22A = (22B, XXX) | |
22B = (22C, 22C) | |
22C = (22Z, 22Z) | |
22Z = (22B, 22B) | |
XXX = (XXX, XXX)"; | |
final readonly class Node | |
{ | |
public function __construct( | |
public string $current, | |
public string $left, | |
public string $right, | |
) { | |
} | |
public function isStart(): bool | |
{ | |
return str_ends_with($this->current, 'A'); | |
} | |
public function isDestination(): bool | |
{ | |
return str_ends_with($this->current, 'Z'); | |
} | |
public function next(string $instruction): string | |
{ | |
return match ($instruction) { | |
'L' => $this->left, | |
'R' => $this->right, | |
default => throw new LogicException(), | |
}; | |
} | |
} | |
/** @var Collection<array-key, Stringable> $lines */ | |
$lines = Str::of($input) | |
->split("/\n/") | |
->filter() | |
->mapInto(Stringable::class); | |
$instructions = new InfiniteIterator( | |
$lines | |
->shift() | |
->matchAll("/L|R/") | |
->getIterator(), | |
); | |
/** @var Collection<string, Node> $nodes */ | |
$nodes = $lines | |
->map(static fn (Stringable $node) => new Node(...$node->matchAll('/[0-9A-Z]+/'))) | |
->keyBy(static fn (Node $node): string => $node->current); | |
$startNodes = $nodes | |
->filter(static fn (Node $node): bool => $node->isStart()) | |
->map(static function (Node $node) use ($instructions, $nodes): int { | |
$instructions->rewind(); | |
$steps = 0; | |
do { | |
$position = $node->next($instructions->current()); | |
$node = $nodes->get($position); | |
$instructions->next(); | |
$steps++; | |
} while ($instructions->valid() && ! $node->isDestination()); | |
return $steps; | |
}) | |
->reduce(static fn (int $lcm, int $steps): int => intval(gmp_lcm($lcm, $steps)), 1); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment