Tristan 68583b1b84
All checks were successful
continuous-integration/drone/push Build is passing
Move solutions out of the source itself
2023-12-03 20:47:53 +01:00

92 lines
2.2 KiB
PHP

<?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);
}
}