Add day 8
This commit is contained in:
parent
55e4e62d97
commit
68438e8e75
@ -1,8 +1,39 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace AdventOfCode21\Utils;
|
namespace trizz\AdventOfCode\Utils;
|
||||||
|
|
||||||
class Arr
|
class Arr
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Flatten a multi-dimensional array into a single level.
|
||||||
|
*
|
||||||
|
* Based on:
|
||||||
|
*
|
||||||
|
* @see https://github.com/laravel/framework/blob/c16367a1af68d8f3a1addc1a819f9864334e2c66/src/Illuminate/Collections/Arr.php#L221-L249
|
||||||
|
*
|
||||||
|
* @param iterable $array
|
||||||
|
* @param float|int $depth
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function flatten(iterable $array, float|int $depth = INF)
|
||||||
|
{
|
||||||
|
$result = [];
|
||||||
|
|
||||||
|
foreach ($array as $item) {
|
||||||
|
if (!is_array($item)) {
|
||||||
|
$result[] = $item;
|
||||||
|
} else {
|
||||||
|
$values = $depth === 1
|
||||||
|
? array_values($item)
|
||||||
|
: static::flatten($item, $depth - 1);
|
||||||
|
|
||||||
|
foreach ($values as $value) {
|
||||||
|
$result[] = $value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
35
src/Utils/Str.php
Normal file
35
src/Utils/Str.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace trizz\AdventOfCode\Utils;
|
||||||
|
|
||||||
|
class Str
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Check if the entirety of string two matches string one.
|
||||||
|
*
|
||||||
|
* @see https://github.com/MueR/adventofcode/blob/master/src/Util/StringUtil.php
|
||||||
|
*/
|
||||||
|
public static function matchesAll(string $one, string $two): bool
|
||||||
|
{
|
||||||
|
for ($index = 0, $length = strlen($two); $index < $length; $index++) {
|
||||||
|
if (!str_contains($one, $two[$index])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alphabetically sort characters in a string.
|
||||||
|
*
|
||||||
|
* @see https://github.com/MueR/adventofcode/blob/master/src/Util/StringUtil.php
|
||||||
|
*/
|
||||||
|
public static function sort(string $string): string
|
||||||
|
{
|
||||||
|
$letters = array_unique(str_split($string));
|
||||||
|
sort($letters, SORT_STRING);
|
||||||
|
|
||||||
|
return implode('', $letters);
|
||||||
|
}
|
||||||
|
}
|
129
src/Y21/Day8.php
Normal file
129
src/Y21/Day8.php
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace trizz\AdventOfCode\Y21;
|
||||||
|
|
||||||
|
use trizz\AdventOfCode\Solution;
|
||||||
|
use trizz\AdventOfCode\Utils\Arr;
|
||||||
|
use trizz\AdventOfCode\Utils\Str;
|
||||||
|
|
||||||
|
class Day8 extends Solution
|
||||||
|
{
|
||||||
|
public static int|string|null $part1ExampleResult = 26;
|
||||||
|
|
||||||
|
public static int|string|null $part1Result = 397;
|
||||||
|
|
||||||
|
public static int|string|null $part2ExampleResult = 61229;
|
||||||
|
|
||||||
|
public static int|string|null $part2Result = 1027422;
|
||||||
|
|
||||||
|
private array $digitPatterns;
|
||||||
|
|
||||||
|
private array $patternDigits;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function part1(array $data): int
|
||||||
|
{
|
||||||
|
$values = array_map(
|
||||||
|
static fn ($item) => strlen($item),
|
||||||
|
Arr::flatten(
|
||||||
|
array_map(
|
||||||
|
static fn ($item) => explode(' ', $item),
|
||||||
|
array_map(
|
||||||
|
static fn ($item) => explode(' | ', $item)[1],
|
||||||
|
$data
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return (count(array_intersect($values, [2, 4, 3, 7])));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function part2(array $data): int|string
|
||||||
|
{
|
||||||
|
$sequences = [];
|
||||||
|
|
||||||
|
foreach ($data as $line) {
|
||||||
|
$item = explode(' | ', $line);
|
||||||
|
$sequences[] = [
|
||||||
|
'patterns' => array_map([Str::class, 'sort'], explode(' ', $item[0])),
|
||||||
|
'shown' => array_map([Str::class, 'sort'], explode(' ', $item[1])),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
$results = [];
|
||||||
|
foreach ($sequences as $sequence) {
|
||||||
|
$this->mapDigits($sequence['patterns']);
|
||||||
|
$output = '';
|
||||||
|
|
||||||
|
foreach ($sequence['shown'] as $pattern) {
|
||||||
|
$output .= $this->patternDigits[$pattern];
|
||||||
|
}
|
||||||
|
|
||||||
|
$results[] = (int) $output;
|
||||||
|
}
|
||||||
|
|
||||||
|
return array_sum($results);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $patterns
|
||||||
|
*
|
||||||
|
* Code based on (sorry, didn't have a clue to solve this one, so I needed some inspiration):
|
||||||
|
*
|
||||||
|
* @see https://github.com/MueR/adventofcode/blob/master/src/AdventOfCode2021/Day08/Day08.php
|
||||||
|
*/
|
||||||
|
public function mapDigits(array $patterns): void
|
||||||
|
{
|
||||||
|
/** @noinspection PackedHashtableOptimizationInspection */
|
||||||
|
$findDigit = [
|
||||||
|
// 1 is the only one with 2 segments
|
||||||
|
1 => static fn (string $pattern) => strlen($pattern) === 2,
|
||||||
|
// 7 is the only one with 3 segments
|
||||||
|
7 => static fn (string $pattern) => strlen($pattern) === 3,
|
||||||
|
// 4 is the only one with 4 segments
|
||||||
|
4 => static fn (string $pattern) => strlen($pattern) === 4,
|
||||||
|
// 8 is the only one with 7 segments
|
||||||
|
8 => static fn (string $pattern) => strlen($pattern) === 7,
|
||||||
|
// 9 is 6 segments, matches segments for 4
|
||||||
|
9 => fn (string $pattern) => strlen($pattern) === 6 && Str::matchesAll(
|
||||||
|
$pattern,
|
||||||
|
$this->digitPatterns[4] ?? ''
|
||||||
|
),
|
||||||
|
// 0 is 6 segments, matching 1's segments (9 is already out)
|
||||||
|
0 => fn (string $pattern) => strlen($pattern) === 6 && Str::matchesAll(
|
||||||
|
$pattern,
|
||||||
|
$this->digitPatterns[1] ?? ''
|
||||||
|
),
|
||||||
|
// 6 is 6 segments, the only one left
|
||||||
|
6 => static fn (string $pattern) => strlen($pattern) === 6,
|
||||||
|
// 3 is 5 segments and matches 1's segments
|
||||||
|
3 => fn (string $pattern) => strlen($pattern) === 5 && Str::matchesAll(
|
||||||
|
$pattern,
|
||||||
|
$this->digitPatterns[1] ?? ''
|
||||||
|
),
|
||||||
|
// 5 is 5 segments, and 9 has all the segments of 5
|
||||||
|
5 => fn (string $pattern) => strlen($pattern) === 5 && Str::matchesAll(
|
||||||
|
$this->digitPatterns[9] ?? '',
|
||||||
|
$pattern
|
||||||
|
),
|
||||||
|
// 2 is the only one remaining
|
||||||
|
2 => static fn (string $pattern) => true,
|
||||||
|
];
|
||||||
|
|
||||||
|
foreach ($findDigit as $digit => $test) {
|
||||||
|
foreach ($patterns as $key => $pattern) {
|
||||||
|
if (!$test($pattern)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
unset($patterns[$key]);
|
||||||
|
$this->patternDigits[$pattern] = $digit;
|
||||||
|
$this->digitPatterns[$digit] = $pattern;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user