Add day 8

This commit is contained in:
Tristan 2021-12-09 23:22:12 +01:00
parent 55e4e62d97
commit 68438e8e75
Signed by: trizz
GPG Key ID: 0A93DEC67165EB47
3 changed files with 196 additions and 1 deletions

View File

@ -1,8 +1,39 @@
<?php
namespace AdventOfCode21\Utils;
namespace trizz\AdventOfCode\Utils;
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
View 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
View 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;
}
}
}
}