-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
145 lines (141 loc) · 4.36 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
import run from 'aocrunner'
const parseInput = (rawInput: string) =>
rawInput
.trim()
.split('\n')
.map((line) => {
const sensorX = line.match(/Sensor at x=(-?\d+)/)![1]
const sensorY = line.match(/, y=(-?\d+): /)![1]
const beaconX = line.match(/beacon is at x=(-?\d+)/)![1]
const beaconY = line.match(/, y=(-?\d+)$/)![1]
return {
sensor: { x: +sensorX, y: +sensorY },
beacon: { x: +beaconX, y: +beaconY },
}
})
const part1 = (rawInput: string) => {
const input = parseInput(rawInput)
const targetRow = input.length < 30 ? 10 : 2000000
const map: Map<number, Map<number, 'S' | 'B' | '#'>> = new Map()
for (const { sensor, beacon } of input) {
const distance =
Math.abs(beacon.x - sensor.x) + Math.abs(beacon.y - sensor.y)
for (let x = sensor.x - distance; x <= sensor.x + distance; x++) {
const y = targetRow
const thisDistance = Math.abs(sensor.x - x) + Math.abs(sensor.y - y)
if (thisDistance > distance) continue
if (!map.has(y)) map.set(y, new Map())
map.get(y)!.set(x, map.get(y)!.get(x) || '#')
}
if (!map.has(sensor.y)) map.set(sensor.y, new Map())
if (!map.has(beacon.y)) map.set(beacon.y, new Map())
map.get(sensor.y)!.set(sensor.x, 'S')
map.get(beacon.y)!.set(beacon.x, 'B')
}
let freeSpaces = 0
for (const [, value] of map.get(targetRow)!) {
if (value === '#') freeSpaces++
}
return freeSpaces.toString()
}
const part2 = (rawInput: string) => {
const input = parseInput(rawInput)
const maxCoord = input.length < 30 ? 20 : 4000000
const sensors = input.map(({ sensor, beacon }) => {
return {
sensor,
range: Math.abs(beacon.x - sensor.x) + Math.abs(beacon.y - sensor.y),
}
})
for (const { sensor, range } of sensors) {
const check = { x: sensor.x, y: sensor.y - range - 1 } // start at top
const dir = { x: 1, y: 1 }
while (true) {
if (check.x > sensor.x && check.y === sensor.y) {
dir.x = -1
} else if (check.x === sensor.x && check.y > sensor.y) {
dir.y = -1
} else if (check.x < sensor.x && check.y === sensor.y) {
dir.x = 1
} else if (
dir.y === -1 &&
check.x === sensor.x &&
check.y === sensor.y - range - 1
) {
break
}
if (
!(
check.x < 0 ||
check.y < 0 ||
check.x > maxCoord ||
check.y > maxCoord
)
) {
let valid = true
for (const otherSensor of sensors) {
if (otherSensor.sensor === sensor) continue
const distance =
Math.abs(check.x - otherSensor.sensor.x) +
Math.abs(check.y - otherSensor.sensor.y)
if (distance <= otherSensor.range) {
valid = false
break
}
}
if (valid) return (check.x * 4000000 + check.y).toString()
}
check.x += dir.x
check.y += dir.y
}
}
return
}
run({
part1: {
tests: [
{
input: `Sensor at x=2, y=18: closest beacon is at x=-2, y=15
Sensor at x=9, y=16: closest beacon is at x=10, y=16
Sensor at x=13, y=2: closest beacon is at x=15, y=3
Sensor at x=12, y=14: closest beacon is at x=10, y=16
Sensor at x=10, y=20: closest beacon is at x=10, y=16
Sensor at x=14, y=17: closest beacon is at x=10, y=16
Sensor at x=8, y=7: closest beacon is at x=2, y=10
Sensor at x=2, y=0: closest beacon is at x=2, y=10
Sensor at x=0, y=11: closest beacon is at x=2, y=10
Sensor at x=20, y=14: closest beacon is at x=25, y=17
Sensor at x=17, y=20: closest beacon is at x=21, y=22
Sensor at x=16, y=7: closest beacon is at x=15, y=3
Sensor at x=14, y=3: closest beacon is at x=15, y=3
Sensor at x=20, y=1: closest beacon is at x=15, y=3`,
expected: '26',
},
],
solution: part1,
},
part2: {
tests: [
{
input: `Sensor at x=2, y=18: closest beacon is at x=-2, y=15
Sensor at x=9, y=16: closest beacon is at x=10, y=16
Sensor at x=13, y=2: closest beacon is at x=15, y=3
Sensor at x=12, y=14: closest beacon is at x=10, y=16
Sensor at x=10, y=20: closest beacon is at x=10, y=16
Sensor at x=14, y=17: closest beacon is at x=10, y=16
Sensor at x=8, y=7: closest beacon is at x=2, y=10
Sensor at x=2, y=0: closest beacon is at x=2, y=10
Sensor at x=0, y=11: closest beacon is at x=2, y=10
Sensor at x=20, y=14: closest beacon is at x=25, y=17
Sensor at x=17, y=20: closest beacon is at x=21, y=22
Sensor at x=16, y=7: closest beacon is at x=15, y=3
Sensor at x=14, y=3: closest beacon is at x=15, y=3
Sensor at x=20, y=1: closest beacon is at x=15, y=3`,
expected: '56000011',
},
],
solution: part2,
},
trimTestInputs: true,
// onlyTests: true,
})