-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.ts
118 lines (89 loc) · 2.75 KB
/
index.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
interface Passport {
byr?: string;
cid?: string;
ecl?: string;
eyr?: string;
hcl?: string;
hgt?: string;
iyr?: string;
pid?: string;
}
const requiredFields = ['byr', 'ecl', 'eyr', 'hcl', 'hgt', 'iyr', 'pid'];
function inRange(number: number, start: number, end: number): boolean {
return number >= start && number <= end;
}
function isBirthday(birthday: string): boolean {
const parsedBirthday = parseInt(birthday, 10);
return inRange(parsedBirthday, 1920, 2002);
}
function isCountryId(): boolean {
return true;
}
function isEyeColor(eyeColor: string): boolean {
return /^(amb|blu|brn|grn|gry|hzl|oth)$/.test(eyeColor);
}
function isExpirationYear(expirationYear: string): boolean {
const parsedExpirationYear = parseInt(expirationYear, 10);
return inRange(parsedExpirationYear, 2020, 2030);
}
function isHairColor(hairColor: string): boolean {
return /^#[0-9a-f]{6}$/.test(hairColor);
}
function isHeight(height: string): boolean {
const { groups } = height.match(/^(?<value>\d+)(?<unit>(cm|in))?$/) || [];
if (!groups) {
throw new Error('Invalid input');
}
const { value, unit } = groups;
const parsedValue = parseInt(value, 10);
if (unit === 'cm') {
return inRange(parsedValue, 150, 193);
}
if (unit === 'in') {
return inRange(parsedValue, 59, 76);
}
return false;
}
function isIssueYear(issueYear: string): boolean {
const parsedIssueYear = parseInt(issueYear, 10);
return inRange(parsedIssueYear, 2010, 2020);
}
function isPassportId(passportId: string): boolean {
return /^\d{9}$/.test(passportId);
}
interface Validation {
[key: string]: (input: string) => boolean;
}
const validation: Validation = {
byr: isBirthday,
cid: isCountryId,
ecl: isEyeColor,
eyr: isExpirationYear,
hcl: isHairColor,
hgt: isHeight,
iyr: isIssueYear,
pid: isPassportId,
};
function parsePassport(passport: string): Passport {
return Object.fromEntries(passport.split(/\s/).map((field) => field.split(':')));
}
function parsePassports(passports: string[]): Passport[] {
return passports.map(parsePassport);
}
function isValidPassport(passport: Passport): boolean {
return Object.entries(passport).every(([key, value]) => validation[key](value));
}
function isPassport(passport: Passport): boolean {
const keys = Object.keys(passport);
return requiredFields.every((requiredField) => keys.find((key) => key === requiredField));
}
function isStrictlyPassport(passport: Passport): boolean {
return isPassport(passport) && isValidPassport(passport);
}
function part1(passports: string[]): number {
return parsePassports(passports).filter(isPassport).length;
}
function part2(passports: string[]): number {
return parsePassports(passports).filter(isStrictlyPassport).length;
}
export { part1, part2 };