Move solutions out of the source itself
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-12-03 20:47:53 +01:00
parent 5c86431824
commit 68583b1b84
22 changed files with 71 additions and 69 deletions

91
data/Y23/day1/Day1.php Normal file
View File

@ -0,0 +1,91 @@
<?php
namespace trizz\AdventOfCode\Y23;
use trizz\AdventOfCode\Solution;
final class Day1 extends Solution
{
/**
* @var array<string,int>
*/
private const array NUMBER_STRING = [
'one' => 1,
'two' => 2,
'three' => 3,
'four' => 4,
'five' => 5,
'six' => 6,
'seven' => 7,
'eight' => 8,
'nine' => 9,
];
public static null|int|string $part1ExampleResult = 142;
public static null|int|string $part1Result = 53974;
public static null|int|string $part2ExampleResult = 281;
public static null|int|string $part2Result = 52840;
#[\Override]
public function part1(array $data): int
{
$total = 0;
foreach ($data as $line) {
$total += $this->extractNumbersFromLine($line);
}
return $total;
}
#[\Override]
public function part2(array $data): int
{
$total = 0;
foreach ($data as $line) {
$total += $this->extractNumbersFromLineWithText($line);
}
return $total;
}
private function extractNumbersFromLine(string $line): int
{
preg_match_all('#\d#', $line, $numbers);
if (empty($numbers[0])) {
return 0;
}
$first = $numbers[0][0];
$last = $numbers[0][array_key_last($numbers[0])];
return (int) ($first.$last);
}
private function extractNumbersFromLineWithText(string $line): int
{
preg_match_all('#\d|'.implode('|', array_keys(self::NUMBER_STRING)).'#', $line, $numbersStart);
// Same regex, but match everything in reverse, so the last is the first.
$keys = implode('|', array_map(static fn (string $k): string => '('.strrev($k).')', array_keys(self::NUMBER_STRING)));
preg_match_all('#\d|'.$keys.'#', strrev($line), $numbersEnd);
$first = $numbersStart[0][0];
$last = strrev((string) $numbersEnd[0][0]);
if (!ctype_digit((string) $first)) {
$first = self::NUMBER_STRING[$first];
}
if (!ctype_digit($last)) {
$last = self::NUMBER_STRING[$last];
}
return (int) ($first.$last);
}
}

108
data/Y23/day2/Day2.php Normal file
View File

@ -0,0 +1,108 @@
<?php
namespace trizz\AdventOfCode\Y23;
use trizz\AdventOfCode\Solution;
final class Day2 extends Solution
{
public static null|int|string $part1ExampleResult = 8;
public static null|int|string $part1Result = 2810;
public static null|int|string $part2ExampleResult = 2286;
public static null|int|string $part2Result = 69110;
/**
* @var array<string, array<string, int>>
*/
private static array $colorData = [
'red' => ['max' => 12],
'green' => ['max' => 13],
'blue' => ['max' => 14],
];
#[\Override]
public function part1(array $data): int
{
$score = 0;
foreach ($data as $line) {
[$gameId, $hands] = $this->getHand($line);
$validGame = true;
foreach ($hands as $hand) {
if ($this->isValidHand($hand)) {
continue;
}
$validGame = false;
}
if ($validGame) {
$score += (int) $gameId;
}
}
return (int) $score;
}
#[\Override]
public function part2(array $data): int
{
$score = 0;
foreach ($data as $line) {
[$gameId, $hands] = $this->getHand($line);
$handData = ['red' => 0, 'green' => 0, 'blue' => 0];
foreach ($hands as $hand) {
$colorsInHand = $this->extractColors($hand);
foreach ($handData as $color => $value) {
if (($colorsInHand[$color] ?? 0) > $value) {
$handData[$color] = $colorsInHand[$color];
}
}
}
$score += array_product($handData);
}
return (int) $score;
}
/**
* @return array<int, array<int, string>>
*/
private function getHand(string $line): array
{
[$gameId, $gameData] = explode(':', $line, 2);
[$_, $gameId] = explode(' ', $gameId);
$hands = explode(';', $gameData);
return [$gameId, $hands];
}
/**
* @return array<string, int>
*/
private function extractColors(string $hand): array
{
$colors = [];
foreach (explode(',', $hand) as $part) {
[$number, $color] = explode(' ', trim($part));
$colors[$color] = (int) $number;
}
return $colors;
}
private function isValidHand(string $hand): bool
{
$lineData = ['red' => 0, 'green' => 0, 'blue' => 0];
foreach (explode(',', $hand) as $part) {
[$number, $color] = explode(' ', trim($part));
$lineData[$color] += (int) $number;
}
return !($lineData['red'] > self::$colorData['red']['max'] || $lineData['green'] > self::$colorData['green']['max'] || $lineData['blue'] > self::$colorData['blue']['max']);
}
}

159
data/Y23/day3/Day3.php Normal file
View File

@ -0,0 +1,159 @@
<?php
namespace trizz\AdventOfCode\Y23;
use trizz\AdventOfCode\Solution;
final class Day3 extends Solution
{
public static null|int|string $part1ExampleResult = 4361;
public static null|int|string $part1Result = 539637;
public static null|int|string $part2ExampleResult = 467835;
public static null|int|string $part2Result = 82_818_007;
/**
* @var string[][]
*/
private array $matrix = [];
#[\Override]
public function part1(array $data): int
{
$this->createMatrix($data);
$score = 0;
foreach ($this->matrix as $row => $line) {
foreach (array_keys($line) as $col) {
$numbers = $this->checkLocation($row, $col);
$top = (int) $this->processNumbers($numbers['top'], sum: true);
$bottom = (int) $this->processNumbers($numbers['bottom'], sum: true);
$score += $top + $bottom + max($numbers['left']) + max($numbers['right']);
}
}
return $score;
}
#[\Override]
public function part2(array $data): int
{
$this->createMatrix($data);
$score = 0;
foreach ($this->matrix as $row => $line) {
foreach (array_keys($line) as $col) {
if ($this->matrix[$row][$col] !== '*') {
continue;
}
$numbers = $this->checkLocation($row, $col);
$top = (array) $this->processNumbers($numbers['top']);
$bottom = (array) $this->processNumbers($numbers['bottom']);
$left = max($numbers['left']);
$right = max($numbers['right']);
$filteredResults = array_filter(array_values(array_merge_recursive($top, $bottom, [$left, $right])));
if (count($filteredResults) !== 2) {
continue;
}
$score += array_product($filteredResults);
}
}
return (int) $score;
}
/**
* @param int[] $numbers
*
* @return int|int[]
*/
private function processNumbers(array $numbers, bool $sum = false): array|int
{
$result = [];
if ($numbers[0] !== 0 && $numbers[1] === 0 && $numbers[2] !== 0) {
$result[] = $numbers[0];
$result[] = $numbers[2];
} else {
$result[] = max($numbers);
}
if ($sum) {
return array_sum($result);
}
return $result;
}
/**
* @param string[] $data
*/
private function createMatrix(array $data): void
{
$this->matrix = array_map(static fn ($line): array => str_split((string) $line), $data);
}
/**
* @return array<string, array<int,int>>
*/
private function checkLocation(int $row, int $col): array
{
$current = $this->matrix[$row][$col] ?? '.';
if ($current === '.' || ctype_digit($current)) {
return ['top' => [0, 0, 0], 'left' => [0], 'right' => [0], 'bottom' => [0, 0, 0]];
}
$numbers = array_fill_keys(['top', 'left', 'right', 'bottom'], []);
$positions = [
'top' => [[$row - 1, $col - 1], [$row - 1, $col], [$row - 1, $col + 1]],
'left' => [[$row, $col - 1]],
'right' => [[$row, $col + 1]],
'bottom' => [[$row + 1, $col - 1], [$row + 1, $col], [$row + 1, $col + 1]],
];
foreach ($positions as $direction => $coords) {
foreach ($coords as $coord) {
$numbers[$direction][] = (int) $this->getNumber(...$coord);
}
}
return $numbers;
}
private function getNumber(int $row, int $col, string $direction = null): ?string
{
$number = $this->matrix[$row][$col] ?? null;
if ($number === null || $number === '.' || !ctype_digit($number)) {
return null;
}
$toLeft = null;
$toRight = null;
if ($direction === null || $direction === 'left') {
$toLeft = $this->getNumber($row, $col - 1, 'left');
}
if ($direction === null || $direction === 'right') {
$toRight = $this->getNumber($row, $col + 1, 'right');
}
if ($toLeft !== null) {
$number = $toLeft.$number;
}
if ($toRight !== null) {
return $number.$toRight;
}
return $number;
}
}