1
0
Fork 0
advent-of-code/2020/day4.php

151 lines
3.5 KiB
PHP
Raw Normal View History

2024-02-08 09:55:40 +01:00
<?php
use JetBrains\PhpStorm\Pure;
$input_file = '../inputs/day4.txt';
if (file_exists($input_file)) {
$input = file_get_contents($input_file);
if ($input != null) {
$credentials = explode("\n", $input);
print 'Part 1 answer: ' . solve_part_one($credentials) . "\n";
print 'Part 2 answer: ' . solve_part_two($credentials) . "\n";
}
}
#[Pure] function solve_part_one(array $credentials): int
{
return count(get_valid_passports($credentials));
}
function solve_part_two(array $credentials): int
{
return count(get_valid_passports_with_valid_fields($credentials));
}
function get_valid_passports_with_valid_fields(array $credentials): array
{
function validate_year(string $value, int $min, int $max): bool
{
preg_match('/^(\d{4})$/', $value, $matches);
[$match, $year] = $matches;
if (($match && ($year >= $min && $year <= $max)))
return true;
else
return false;
}
function validate_height(string $value): bool
{
if (preg_match('/^(\d.+?)(cm|in)$/', $value, $matches) > 0) {
if (($matches[2] == 'cm' && $matches[1] >= 150 && $matches[1] <= 193) || ($matches[2] == 'in' && $matches[1] >= 59 && $matches[1] <= 76))
return true;
}
return false;
}
$validate_hair_color = fn ($value) => preg_match('/^#([a-f0-9]{6})$/', $value);
$validate_eye_color = fn ($value) => preg_match('/^(amb|blu|brn|gry|grn|hzl|oth)$/', $value);
$validate_pid = fn ($value) => preg_match('/^0*(\d{9})$/', $value);
$valid_passports = [];
$passports = get_valid_passports($credentials);
foreach ($passports as $passport) {
$valid = true;
foreach ($passport as $field => $value) {
switch ($field) {
case 'byr':
if (!validate_year($value, 1920, 2002))
$valid = false;
break;
case 'iyr':
if (!validate_year($value, 2010, 2020))
$valid = false;
break;
case 'eyr':
if (!validate_year($value, 2020, 2030))
$valid = false;
break;
case 'hgt':
if (!validate_height($value))
$valid = false;
break;
case 'hcl':
if (!$validate_hair_color($value))
$valid = false;
break;
case 'ecl':
if (!$validate_eye_color($value))
$valid = false;
break;
case 'pid':
if (!$validate_pid($value))
$valid = false;
break;
}
}
if ($valid)
$valid_passports[] = $passport;
}
return $valid_passports;
}
#[Pure] function get_valid_passports(array $credentials): array
{
$passports = parse_passports($credentials);
$required_fields = ['byr', 'iyr', 'eyr', 'hgt', 'hcl', 'ecl', 'pid'];
$valid_passports = [];
foreach ($passports as $passport) {
$valid = true;
foreach ($required_fields as $required_field) {
if (!array_key_exists($required_field, $passport))
$valid = false;
}
if ($valid)
$valid_passports[] = $passport;
}
return $valid_passports;
}
#[Pure] function parse_passports(array $credentials): array
{
$passports = [];
$current_credentials = [];
for ($i = 0; $i < count($credentials); $i++) {
$cred = trim($credentials[$i]);
if ($cred == '') {
$passports[] = parse_single_passport($current_credentials);
$current_credentials = [];
} else
$current_credentials[] = $cred;
}
if (count($current_credentials) != 0)
$passports[] = parse_single_passport($current_credentials);
return $passports;
}
function parse_single_passport(array $fields): array
{
$passport = [];
foreach ($fields as $fieldlist) {
$kvps = explode(' ', $fieldlist);
foreach ($kvps as $kvp) {
[$field, $value] = explode(':', $kvp);
$passport[$field] = $value;
}
}
return $passport;
}