Skip to content

Instantly share code, notes, and snippets.

@maartenpaauw
Created December 4, 2023 18:44
Show Gist options
  • Save maartenpaauw/4de6ff5b1afee5a38564413e92b85d37 to your computer and use it in GitHub Desktop.
Save maartenpaauw/4de6ff5b1afee5a38564413e92b85d37 to your computer and use it in GitHub Desktop.
Advent of Code 2023 - Day 2
<?php
//Tinker away!
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
final readonly class GameConfiguration
{
public function __construct(
public int $red = 0,
public int $green = 0,
public int $blue = 0,
) {
}
}
final readonly class GameSet
{
public function __construct(
public int $red = 0,
public int $green = 0,
public int $blue = 0,
) {
}
private function withRed(int $red): self
{
return new self(
$red,
$this->green,
$this->blue,
);
}
private function withGreen(int $green): self
{
return new self(
$this->red,
$green,
$this->blue,
);
}
private function withBlue(int $blue): self
{
return new self(
$this->red,
$this->green,
$blue,
);
}
public static function fromString(string $notation): self
{
return Str::of($notation)
->explode(', ')
->map(static fn (string $notation): array => explode(' ', $notation))
->reduce(static function (GameSet $gameSet, array $cubes) {
[$count, $color] = $cubes;
$count = intval($count);
return match ($color) {
'red' => $gameSet->withRed($count),
'green' => $gameSet->withGreen($count),
'blue' => $gameSet->withBlue($count),
default => $gameSet,
};
}, new GameSet());
}
}
final readonly class Game
{
public function __construct(
public int $number,
private Collection $sets,
){
}
public function possible(GameConfiguration $configuration): bool
{
return $this->sets
->filter(static function (GameSet $set) use ($configuration): bool {
return $set->red <= $configuration->red
&& $set->green <= $configuration->green
&& $set->blue <= $configuration->blue;
})
->count() === $this->sets->count();
}
public function colors(): GameConfiguration
{
return $this->sets
->reduce(fn (GameConfiguration $configuration, GameSet $gameSet) => new GameConfiguration(
max($configuration->red, $gameSet->red),
max($configuration->green, $gameSet->green),
max($configuration->blue, $gameSet->blue),
), new GameConfiguration());
}
public static function fromString(string $notation): self
{
$number = Str::of($notation)
->between('Game ', ':')
->toInteger();
$sets = Str::of($notation)
->after(':')
->trim()
->explode(';')
->map(static fn (string $notation): string => trim($notation))
->map(static fn (string $notation): GameSet => GameSet::fromString($notation));
return new self($number, $sets);
}
}
$input = "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green
Game 2: 1 blue, 2 green; 3 green, 4 blue, 1 red; 1 green, 1 blue
Game 3: 8 green, 6 blue, 20 red; 5 blue, 4 red, 13 green; 5 green, 1 red
Game 4: 1 green, 3 red, 6 blue; 3 green, 6 red; 3 green, 15 blue, 14 red
Game 5: 6 red, 1 blue, 3 green; 2 blue, 1 red, 2 green";
$games = Str::of($input)
->trim()
->explode("\n")
->map(static fn (string $notation) => Game::fromString($notation));
$configuration = new GameConfiguration(12, 13, 14);
$part1 = $games->filter(static fn (Game $game): bool => $game->possible($configuration))
->map(static fn (Game $game): int => $game->number)
->sum();
$part2 = $games->map(static fn (Game $game): GameConfiguration => $game->colors())
->map(static fn (GameConfiguration $configuration): int => $configuration->red * $configuration->green * $configuration->blue)
->sum();
$result = [$part1, $part2];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment