Skip to content

Commit 5f3f02a

Browse files
Solve day 15 ⚠️
1 parent 531a420 commit 5f3f02a

File tree

3 files changed

+112
-1
lines changed

3 files changed

+112
-1
lines changed

src/day14.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {_} from './util/lodash.ts'
22
import {getInput, printSolutions} from './util/io.ts'
3+
import type {Coord} from './util/types.ts'
34

4-
type Coord = {x: number, y: number}
55
type Tile = "sand" | "rock"
66

77
const buildMap = (coords: Coord[]): Map<string, Tile> => {

src/day15.ts

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
// First day where I had no clue what to do...
2+
// Solution I based mine on: https://www.reddit.com/r/adventofcode/comments/zmcn64/comment/j0axxpo
3+
4+
import {_} from './util/lodash.ts'
5+
import {getInput, printSolutions} from './util/io.ts'
6+
import type {Coord} from './util/types.ts'
7+
8+
type DataPoint = {
9+
sensor: Coord
10+
beacon: Coord
11+
}
12+
13+
const parseInput = (input: string[]) => {
14+
return input.map((line): DataPoint => {
15+
const firstSlice = line
16+
.slice(
17+
line.indexOf('x='),
18+
line.indexOf(':'))
19+
.split(',')
20+
.map((it) => Number.parseInt(it.trim().slice(2)))
21+
22+
const secondSlice = line
23+
.slice(line.indexOf('is at') + 'is at'.length)
24+
.split(',')
25+
.map((it) => Number.parseInt(it.trim().slice(2)))
26+
27+
return {
28+
sensor: {
29+
x: firstSlice[0],
30+
y: firstSlice[1],
31+
},
32+
beacon: {
33+
x: secondSlice[0],
34+
y: secondSlice[1],
35+
}
36+
}
37+
})
38+
}
39+
40+
const solve1 = (input: string[]) => {
41+
const row = 2000000
42+
43+
const resultSet = new Set()
44+
45+
// .map() has failed me... or have I failed .map()..?
46+
parseInput(input).forEach(({sensor, beacon}) => {
47+
const dist = Math.abs(sensor.x - beacon.x) + Math.abs(sensor.y - beacon.y)
48+
const restDist = dist - Math.abs(row - sensor.y)
49+
50+
if (restDist < 0) {
51+
return
52+
}
53+
54+
if (!(sensor.x === beacon.x && row === beacon.y)) {
55+
resultSet.add(sensor.x)
56+
}
57+
58+
for(let i = 1; i < restDist + 1; i += 1) {
59+
if (!(sensor.x - i === beacon.x && row === beacon.y)) {
60+
resultSet.add(sensor.x - i)
61+
}
62+
63+
if (!(sensor.x + i === beacon.x && row === beacon.y)) {
64+
resultSet.add(sensor.x + i)
65+
}
66+
}
67+
})
68+
69+
return resultSet.size
70+
}
71+
72+
const solve2 = (input: string[]) => {
73+
for (let row = 0; row <= 4000000; row += 1) {
74+
const ranges: {start: number, end: number}[] = []
75+
parseInput(input).forEach(({sensor, beacon}) => {
76+
const dist = Math.abs(sensor.x - beacon.x) + Math.abs(sensor.y - beacon.y)
77+
const restDist = dist - Math.abs(row - sensor.y)
78+
79+
if (restDist < 0) return
80+
ranges.push({start: sensor.x - restDist, end: sensor.x + restDist})
81+
})
82+
83+
ranges.sort((a, b) => a.start - b.start)
84+
const merged = []
85+
for (let i = 0; i < ranges.length - 1; i += 1) {
86+
const curr = ranges[i]
87+
const next = ranges[i+1]
88+
89+
if ((next.start <= curr.end && curr.end <= next.end) || next.start === curr.end + 1) {
90+
ranges[i + 1] = {start: curr.start, end: next.end}
91+
} else if (curr.start <= next.start && curr.end >= next.end) {
92+
ranges[i + 1] = curr
93+
} else {
94+
merged.push(curr)
95+
}
96+
}
97+
merged.push(ranges[ranges.length - 1])
98+
if (merged.length > 1) {
99+
return (merged[0].end + 1) * 4000000 + row
100+
}
101+
}
102+
}
103+
104+
const input = await getInput(15, false)
105+
printSolutions(solve1, solve2, input)
106+

src/util/types.ts

+5
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,8 @@ export type Pair<T, U> = {
88
second: U
99
}
1010

11+
export type Coord = {
12+
x: number
13+
y: number
14+
}
15+

0 commit comments

Comments
 (0)