Skip to content

Instantly share code, notes, and snippets.

@maartenpaauw
Created December 4, 2023 18:42
Show Gist options
  • Save maartenpaauw/5bc47203332027f657e4530f31119052 to your computer and use it in GitHub Desktop.
Save maartenpaauw/5bc47203332027f657e4530f31119052 to your computer and use it in GitHub Desktop.
Advent of Code 2023 - Day 3
<?php
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
$input = "467..114..
...*......
..35..633.
......#...
617*......
.....+.58.
..592.....
......755.
...$.*....
.664.598..";
final readonly class PartNumber
{
public function __construct(
public int $value,
public int $xStart,
public int $xEnd,
public int $y,
) {
}
public function isNextTo(Collection $symbols): bool
{
return $symbols
->filter(function (Symbol $symbol): bool {
return $symbol->x >= $this->xStart - 1
&& $symbol->x <= $this->xEnd + 1
&& $symbol->y >= $this->y - 1
&& $symbol->y <= $this->y + 1;
})
->isNotEmpty();
}
}
final readonly class Symbol
{
public function __construct(
public string $value,
public int $x,
public int $y,
) {
}
public function adjacentPartNumbers(Collection $partNumbers): Collection
{
return $partNumbers
->filter(function (PartNumber $partNumber): bool {
$xRange = range($this->x - 1, $this->x + 1);
$yRange = range($this->y - 1, $this->y + 1);
return in_array($partNumber->y, $yRange)
&& ! empty(array_intersect($xRange, range($partNumber->xStart, $partNumber->xEnd)));
})
->values();
}
}
$lines = Str::of($input)->explode("\n");
$symbols = $lines
->map(function (string $line, int $y): array {
preg_match_all('/(?!\d+)(?!\.)./', $line, $symbols, PREG_OFFSET_CAPTURE);
return Arr::map($symbols[0], static fn ($symbol) => new Symbol(
value: $symbol[0],
x: intval($symbol[1]),
y: $y,
));
})
->filter()
->flatten(1);
$gears = $symbols->filter(static fn (Symbol $symbol): bool => $symbol->value === '*');
$partNumbers = $lines
->map(function (string $line, int $y): array {
preg_match_all('/\d+/', $line, $numbers, PREG_OFFSET_CAPTURE);
return Arr::map($numbers[0], static fn ($number) => new PartNumber(
value: intval($number[0]),
xStart: $number[1],
xEnd: $number[1] + (strlen($number[0]) - 1),
y: $y,
));
})
->filter()
->flatten(1);
$part1 = $partNumbers
->filter(static fn (PartNumber $partNumber): bool => $partNumber->isNextTo($symbols))
->map(static fn (PartNumber $partNumber): int => $partNumber->value)
->sum();
$part2 = $gears
->map(static fn (Symbol $gear): Collection => $gear->adjacentPartNumbers($partNumbers))
->filter(static fn (Collection $partNumbers): bool => $partNumbers->count() === 2)
->map(static fn (Collection $partNumbers): int => $partNumbers->first()->value * $partNumbers->last()->value)
->sum();
$day3 = [$part1, $part2];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment