import 'mocha'; import assert from 'assert'; import { readFileSync } from 'fs'; let input = readFileSync('./input/2020-day-04.txt', 'utf-8') let example: string = `ecl:gry pid:860033327 eyr:2020 hcl:#fffffd byr:1937 iyr:2017 cid:147 hgt:183cm iyr:2013 ecl:amb cid:350 eyr:2023 pid:028048884 hcl:#cfa07d byr:1929 hcl:#ae17e1 iyr:2013 eyr:2024 ecl:brn pid:760753108 byr:1931 hgt:179cm hcl:#cfa07d eyr:2025 pid:166559648 iyr:2011 ecl:brn hgt:59in`; let tasksResults: any[] = ['N/A', 'N/A']; describe('Day 04', () => { let sample: Passport[]; let passports: Passport[]; before(() => { sample = filterInvalid(parseData(example)); passports = filterInvalid(parseData(input)); }) describe('task01', () => { it('parse data', () => { assert.strictEqual(sample.length, 2); tasksResults[0] = passports.length; }) }); describe('test02', () => { it('Calculate', () => { passports = filterIncorrect(parseData(input)); tasksResults[1] = passports.length; }); }); after(() => { console.log('\ntask 01:', tasksResults[0]); console.log('\ntask 02:', tasksResults[1]); }); }); function task01(panels: number, input: string[], down: number = 1, right: number = 3) { } function task02(right: number, down: number, input: string[]) { } type PassKey = "byr" | "iyr" | "eyr" | "hgt" | "hcl" | "ecl" | "pid" | "cid"; function parseData(input: string): Passport[] { let passports: Passport[] = []; let passport: Passport = new Passport(); input.split('\n').forEach((line: string) => { if (!line.length) { passports.push(passport); passport = new Passport(); } let fields: string[] = line.split(' '); fields.forEach((field: string) => { let [key, value]: string[] = field.split(':'); passport[key as PassKey] = value; }); }); return passports; } function filterInvalid(input: Passport[]): Passport[] { return input.filter(p => p.valid()); } function filterIncorrect(input: Passport[]): Passport[] { return input.filter(p => p.correct); } class Passport { byr?: string; // (Birth Year) iyr?: string; // (Issue Year) eyr?: string; // (Expiration Year) hgt?: string; // (Height) hcl?: string; // (Hair Color) ecl?: string; // (Eye Color) pid?: string; // (Passport ID) cid?: string; // (Country ID) valid(): this is Required { return !!(this.byr && this.iyr && this.eyr && this.hgt && this.hcl && this.ecl && this.pid); } get correct() { try { assert.ok(this.valid()); let valid: Required = this; assert.ok(isInRange(parseInt(valid.byr, 10), 1920, 2002)); assert.ok(isInRange(parseInt(valid.iyr, 10), 2010, 2020)); assert.ok(isInRange(parseInt(valid.eyr, 10), 2020, 2030)); assert.match(valid.hcl, /^#[0-9a-f]{6}$/); assert.match(valid.pid, /^\d{9}$/); assert.match(valid.ecl, /^(amb|blu|brn|gry|grn|hzl|oth)$/); assert.match(valid.hgt, /(\d+)(cm|in)/); let [_, measure, unit] = valid.hgt.match(/(\d+)(cm|in)/) as [string, string, string]; (unit === 'cm') ? assert.ok(isInRange(parseInt(measure, 10), 150, 193)) : assert.ok(isInRange(parseInt(measure, 10), 59, 76)); } catch (_ignore) { return false; } return true; } } const isInRange = (i: number, min: number, max: number): boolean => (i - min) * (i - max) <= 0;