-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
80 lines (67 loc) · 2.06 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
interface Passport {
ecl: string;
pid: string;
eyr: string;
hcl: string;
byr: string;
iyr: string;
hgt: string;
cid?: string;
}
type Predicate<T> = (value: T) => boolean;
type PassportPolicy = {
[K in keyof Passport]: Predicate<Passport[K]>;
};
enum EyeColors {
amb = "amb",
blu = "blu",
brn = "brn",
gry = "gry",
grn = "grn",
hzl = "hzl",
oth = "oth",
}
export const PASSPORT_RESTRICT_POLICY: PassportPolicy = {
byr: (value) => parseInt(value, 10) >= 1920 && parseInt(value, 10) <= 2002,
iyr: (value) => parseInt(value, 10) >= 2010 && parseInt(value, 10) <= 2020,
eyr: (value) => parseInt(value, 10) >= 2020 && parseInt(value, 10) <= 2030,
hgt: (value: string) => {
if (value.endsWith("cm")) {
return parseInt(value, 10) >= 150 && parseInt(value, 10) <= 193;
} else if (value.endsWith("in")) {
return parseInt(value, 10) >= 59 && parseInt(value, 10) <= 76;
}
return false;
},
hcl: (value) => /^#[0-9a-f]{6}$/i.test(value),
ecl: (value) => !!EyeColors[value as EyeColors],
pid: (value) => /^[\d]{9}$/.test(value),
};
export const parsePassport = (passport: string): Passport =>
passport.split(/[ \n]/).reduce((acc, field) => {
const [key, value] = field.split(":");
return { ...acc, [key]: value };
}, {}) as Passport;
export const part1 = (input: string): number => {
const passports: Passport[] = input.split("\n\n").map(parsePassport);
return passports.filter((passport: Passport) =>
Object.keys(PASSPORT_RESTRICT_POLICY).every(
(field: string) => !!passport[field as keyof Passport]
)
).length;
};
export const part2 = (input: string): number => {
const passports: Passport[] = input.split("\n\n").map(parsePassport);
return passports.filter((passport: Passport) =>
Object.entries(PASSPORT_RESTRICT_POLICY).every(([field, predicate]) => {
if (predicate === undefined) {
return true;
}
const fieldValue = passport[field as keyof Passport];
if (!fieldValue) {
return false;
}
return predicate(fieldValue);
})
).length;
};