AdventOfCode2020/src/2020-day-04.ts

122 lines
3.6 KiB
TypeScript

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<Passport> {
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<Passport> = 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;