-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path03.ts
68 lines (61 loc) · 2.15 KB
/
03.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
import { V2, Vec2, Vec2Map } from "../../common/vector2.ts";
type Claim = {
id: number;
position: Vec2;
size: Vec2;
};
const parseClaim = (line: string): Claim => {
const match = line.match(/#(\d+) @ (\d+),(\d+): (\d+)x(\d+)/);
if (!match) throw new Error(`Invalid claim: ${line}`);
const [, id, left, top, width, height] = match.map((n) => parseInt(n));
return {
id,
position: { x: left, y: top },
size: { x: width, y: height },
};
};
const getClaimsMap = (claims: Claim[]): Vec2Map<number> => {
const map = new V2.Map<number>();
for (const claim of claims) {
for (let x = claim.position.x; x < claim.position.x + claim.size.x; x++) {
for (let y = claim.position.y; y < claim.position.y + claim.size.y; y++) {
const position = { x, y };
const value = map.get(position) || 0;
map.set(position, value + 1);
}
}
}
return map;
};
const getMultiClaimedPositionsTotal = (claimMap: Vec2Map<number>): number =>
Array.from(claimMap.values()).filter((n) => n > 1).length;
const findFullyExclusiveClaimId = (
claims: Claim[],
claimsMap: Vec2Map<number>,
): number => {
const isExclusive = (claim: Claim): boolean => {
for (let x = claim.position.x; x < claim.position.x + claim.size.x; x++) {
for (let y = claim.position.y; y < claim.position.y + claim.size.y; y++) {
const position = { x, y };
const claims = claimsMap.get(position) ?? 0;
if (claims > 1) return false;
}
}
return true;
};
const exclusiveClaim = claims.find(isExclusive);
if (!exclusiveClaim) throw new Error("Could not find exclusive claim");
return exclusiveClaim.id;
};
// "How many square inches of fabric are within two or more claims?"
export function part1(input: string): number {
const claims = input.split("\n").map(parseClaim);
const claimsMap = getClaimsMap(claims);
return getMultiClaimedPositionsTotal(claimsMap);
}
// "What is the ID of the only claim that doesn't overlap?"
export function part2(input: string): number {
const claims = input.split("\n").map(parseClaim);
const claimsMap = getClaimsMap(claims);
return findFullyExclusiveClaimId(claims, claimsMap);
}