expeditaet
Version:
Advent of Code Solutions
41 lines (33 loc) • 1.62 kB
text/typescript
import { INTERVAL_CLOSED, task } from '@alexaegis/advent-of-code-lib';
import packageJson from '../package.json';
import { RelevantField, isPassport, parsePassports, type Passport } from './p1.js';
const CM = 'cm';
const IN = 'in';
export const passportEyeColors = ['amb', 'blu', 'brn', 'gry', 'grn', 'hzl', 'oth'];
const from1920to2002 = (1920).interval(2002, INTERVAL_CLOSED);
const from2010to2020 = (2010).interval(2020, INTERVAL_CLOSED);
const from2020to2030 = (2020).interval(2030, INTERVAL_CLOSED);
const from150to193 = (150).interval(193, INTERVAL_CLOSED);
const from59to76 = (59).interval(76, INTERVAL_CLOSED);
export const passportChecks: Record<RelevantField, (v: string) => boolean> = {
byr: (byr) => byr.toInt()?.isContainedIn(from1920to2002) ?? false,
iyr: (iyr) => iyr.toInt()?.isContainedIn(from2010to2020) ?? false,
eyr: (eyr) => eyr.toInt()?.isContainedIn(from2020to2030) ?? false,
hgt: (hgt) => {
if (hgt.endsWith(CM)) {
return hgt.split(CM)[0]?.toInt()?.isContainedIn(from150to193) ?? false;
} else if (hgt.endsWith(IN)) {
return hgt.split(IN)[0]?.toInt()?.isContainedIn(from59to76) ?? false;
} else {
return false;
}
},
hcl: (hcl) => /^#[\da-f]{6}$/.test(hcl),
ecl: (ecl) => passportEyeColors.includes(ecl),
pid: (pid) => /^\d{9}$/.test(pid),
};
export const isValidPassport = (passport: Partial<Passport>): passport is Passport =>
isPassport(passport) &&
Object.values(RelevantField).every((f) => passportChecks[f](passport[f]));
export const p2 = (input: string): number => parsePassports(input).count(isValidPassport);
await task(p2, packageJson.aoc); // 224 ~7.8ms