Skip to content

Commit 276eda8

Browse files
committed
Merge remote-tracking branch 'origin/main' into build/bun-migration
2 parents ade07ea + c1e7282 commit 276eda8

File tree

10 files changed

+1036
-13
lines changed

10 files changed

+1036
-13
lines changed

2024/08/index.ts

Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
import { getPuzzle } from "../../utils";
2+
3+
const puzzleInput = getPuzzle(__dirname).trim();
4+
5+
const map = puzzleInput.split("\n").map((row) => row.split(""));
6+
7+
const WIDTH = map[0].length;
8+
const HEIGHT = map.length;
9+
10+
// Part 1
11+
(() => {
12+
console.time("part 1");
13+
14+
const antennas = new Map<string, Set<string>>();
15+
16+
for (let y = 0; y < HEIGHT; y++) {
17+
for (let x = 0; x < WIDTH; x++) {
18+
const cell = map[y][x];
19+
20+
if (cell === ".") {
21+
continue;
22+
}
23+
24+
if (antennas.has(cell)) {
25+
antennas.get(cell).add(`${x},${y}`);
26+
} else {
27+
antennas.set(cell, new Set<string>([`${x},${y}`]));
28+
}
29+
}
30+
}
31+
32+
const antinodes = new Set<string>();
33+
34+
for (const antenna of antennas.values()) {
35+
const comparedPositions = new Set<string>();
36+
37+
for (const currentCoord of antenna) {
38+
const [currentX, currentY] = currentCoord.split(",").map(Number);
39+
40+
for (const otherCoord of antenna) {
41+
if (
42+
otherCoord !== currentCoord &&
43+
(!comparedPositions.has(`${currentCoord}_${otherCoord}`) ||
44+
!comparedPositions.has(`${otherCoord}_${currentCoord}`))
45+
) {
46+
const [otherX, otherY] = otherCoord.split(",").map(Number);
47+
48+
const diffX = Math.abs(currentX - otherX);
49+
const diffY = Math.abs(currentY - otherY);
50+
51+
const currentAntinodeX =
52+
currentX < otherX ? currentX - diffX : currentX + diffX;
53+
const currentAntinodeY =
54+
currentY < otherY ? currentY - diffY : currentX + diffY;
55+
56+
const otherAntinodeX =
57+
currentX < otherX ? otherX + diffX : otherX - diffX;
58+
const otherAntinodeY =
59+
currentY < otherY ? otherY + diffY : otherY + diffY;
60+
61+
if (
62+
currentAntinodeX >= 0 &&
63+
currentAntinodeX < WIDTH &&
64+
currentAntinodeY >= 0 &&
65+
currentAntinodeY < HEIGHT
66+
) {
67+
antinodes.add(`${currentAntinodeX},${currentAntinodeY}`);
68+
}
69+
70+
if (
71+
otherAntinodeX >= 0 &&
72+
otherAntinodeX < WIDTH &&
73+
otherAntinodeY >= 0 &&
74+
otherAntinodeY < HEIGHT
75+
) {
76+
antinodes.add(`${otherAntinodeX},${otherAntinodeY}`);
77+
}
78+
79+
comparedPositions.add(`${currentCoord}_${otherCoord}`);
80+
comparedPositions.add(`${otherCoord}_${currentCoord}`);
81+
}
82+
}
83+
}
84+
}
85+
86+
console.log("part 1 antinode count ::", antinodes.size);
87+
console.timeEnd("part 1");
88+
})();
89+
90+
// Part 2
91+
(() => {
92+
console.time("part 2");
93+
const antennas = new Map<string, Set<string>>();
94+
95+
for (let y = 0; y < HEIGHT; y++) {
96+
for (let x = 0; x < WIDTH; x++) {
97+
const cell = map[y][x];
98+
99+
if (cell === ".") {
100+
continue;
101+
}
102+
103+
if (antennas.has(cell)) {
104+
antennas.get(cell).add(`${x},${y}`);
105+
} else {
106+
antennas.set(cell, new Set<string>([`${x},${y}`]));
107+
}
108+
}
109+
}
110+
111+
const antinodes = new Set<string>();
112+
113+
for (const antenna of antennas.values()) {
114+
const comparedPositions = new Set<string>();
115+
116+
for (const currentCoord of antenna) {
117+
const [currentX, currentY] = currentCoord.split(",").map(Number);
118+
119+
for (const otherCoord of antenna) {
120+
if (
121+
otherCoord !== currentCoord &&
122+
(!comparedPositions.has(`${currentCoord}_${otherCoord}`) ||
123+
!comparedPositions.has(`${otherCoord}_${currentCoord}`))
124+
) {
125+
const [otherX, otherY] = otherCoord.split(",").map(Number);
126+
127+
const diffX = Math.abs(currentX - otherX);
128+
const diffY = Math.abs(currentY - otherY);
129+
130+
const currentAntinodeX =
131+
currentX < otherX ? currentX - diffX : currentX + diffX;
132+
const currentAntinodeY =
133+
currentY < otherY ? currentY - diffY : currentX + diffY;
134+
135+
if (
136+
currentAntinodeX >= 0 &&
137+
currentAntinodeX < WIDTH &&
138+
currentAntinodeY >= 0 &&
139+
currentAntinodeY < HEIGHT
140+
) {
141+
antinodes.add(`${currentAntinodeX},${currentAntinodeY}`);
142+
143+
let newX = currentAntinodeX;
144+
let newY = currentAntinodeY;
145+
146+
while (true) {
147+
newX = currentX < otherX ? newX - diffX : newX + diffX;
148+
newY = currentY < otherY ? newY - diffY : newY + diffY;
149+
150+
if (newX >= 0 && newX < WIDTH && newY >= 0 && newY < HEIGHT) {
151+
antinodes.add(`${newX},${newY}`);
152+
} else {
153+
break;
154+
}
155+
}
156+
}
157+
158+
const otherAntinodeX =
159+
currentX < otherX ? otherX + diffX : otherX - diffX;
160+
const otherAntinodeY =
161+
currentY < otherY ? otherY + diffY : otherY + diffY;
162+
163+
if (
164+
otherAntinodeX >= 0 &&
165+
otherAntinodeX < WIDTH &&
166+
otherAntinodeY >= 0 &&
167+
otherAntinodeY < HEIGHT
168+
) {
169+
antinodes.add(`${otherAntinodeX},${otherAntinodeY}`);
170+
171+
let newX = otherAntinodeX;
172+
let newY = otherAntinodeY;
173+
174+
while (true) {
175+
newX = currentX < otherX ? newX + diffX : newX - diffX;
176+
newY = currentY < otherY ? newY + diffY : newY - diffY;
177+
178+
if (newX >= 0 && newX < WIDTH && newY >= 0 && newY < HEIGHT) {
179+
antinodes.add(`${newX},${newY}`);
180+
} else {
181+
break;
182+
}
183+
}
184+
}
185+
186+
comparedPositions.add(`${currentCoord}_${otherCoord}`);
187+
comparedPositions.add(`${otherCoord}_${currentCoord}`);
188+
}
189+
}
190+
}
191+
}
192+
193+
for (const [, antena] of antennas) {
194+
if (antena.size > 0) {
195+
for (const coord of antena) {
196+
antinodes.add(coord);
197+
}
198+
}
199+
}
200+
201+
console.log("part 2 antinode count ::", antinodes.size);
202+
console.timeEnd("part 2");
203+
})();

2024/09/index.ts

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
import { getPuzzle } from "../../utils";
2+
3+
const puzzleInput = getPuzzle(__dirname).trim();
4+
const diskMap = puzzleInput.split("");
5+
6+
// Part 1
7+
(() => {
8+
console.time("part 1");
9+
let representation = "";
10+
11+
for (let i = 0; i < diskMap.length; i++) {
12+
const entry = Number(diskMap[i]);
13+
const isFile = i % 2 === 0;
14+
15+
for (let j = 0; j < entry; j++) {
16+
representation += `${isFile ? i / 2 : "."}_`;
17+
}
18+
}
19+
20+
let representationArr = representation
21+
.split("_")
22+
.filter((e) => e !== "")
23+
.map((e) => (e === "." ? e : Number(e)));
24+
25+
let firstFreeSpaceBlockIndex = representationArr.indexOf(".");
26+
let lastFileBlockIndex = representationArr.findLastIndex((e) => e !== ".");
27+
28+
while (lastFileBlockIndex > firstFreeSpaceBlockIndex) {
29+
const lastEntry = representationArr.pop();
30+
31+
if (lastEntry !== ".") {
32+
representationArr[firstFreeSpaceBlockIndex] = lastEntry;
33+
}
34+
35+
firstFreeSpaceBlockIndex = representationArr.indexOf(".");
36+
lastFileBlockIndex = representationArr.findLastIndex((e) => e !== ".");
37+
38+
if (firstFreeSpaceBlockIndex === -1) {
39+
break;
40+
}
41+
}
42+
43+
let checksum = 0;
44+
45+
for (let i = 0; i < representationArr.length; i++) {
46+
const block = representationArr[i];
47+
48+
if (block !== ".") {
49+
checksum += block * i;
50+
}
51+
}
52+
53+
console.log("part 1 checksum ::", checksum);
54+
console.timeEnd("part 1");
55+
})();
56+
57+
// Part 2
58+
(() => {
59+
console.time("part 2");
60+
let representation = "";
61+
62+
for (let i = 0; i < diskMap.length; i++) {
63+
const entry = Number(diskMap[i]);
64+
const isFile = i % 2 === 0;
65+
66+
for (let j = 0; j < entry; j++) {
67+
representation += `${isFile ? i / 2 : "."}_`;
68+
}
69+
}
70+
71+
let representationArr = representation
72+
.split("_")
73+
.filter((e) => e !== "")
74+
.map((e) => (e === "." ? e : Number(e)));
75+
76+
const checkedNumbers = new Set<number>();
77+
78+
let i = representationArr.length;
79+
80+
while (true) {
81+
i = i - 1;
82+
83+
if (i <= 0) {
84+
break;
85+
}
86+
87+
const num = representationArr[i];
88+
89+
if (num === "." || checkedNumbers.has(num)) {
90+
continue;
91+
}
92+
93+
checkedNumbers.add(num);
94+
95+
if (num === 0) {
96+
break;
97+
}
98+
99+
let fileSize = 1;
100+
let j = i;
101+
102+
while (true) {
103+
j = j - 1;
104+
if (representationArr[j] === num) {
105+
fileSize++;
106+
} else {
107+
break;
108+
}
109+
}
110+
111+
const availableSpace = representationArr.findIndex((entry, i, arr) => {
112+
if (entry === ".") {
113+
let match = true;
114+
115+
for (let k = 0; k < fileSize; k++) {
116+
if (arr[i + k] !== ".") {
117+
match = false;
118+
}
119+
}
120+
121+
return match;
122+
}
123+
124+
return false;
125+
});
126+
127+
if (availableSpace === -1 || availableSpace > j) {
128+
continue;
129+
}
130+
131+
for (let k = 0; k < fileSize; k++) {
132+
representationArr[availableSpace + k] = num;
133+
134+
representationArr[j + 1 + k] = ".";
135+
}
136+
}
137+
138+
let checksum = 0;
139+
140+
for (let i = 0; i < representationArr.length; i++) {
141+
const block = representationArr[i];
142+
143+
if (block !== ".") {
144+
checksum += block * i;
145+
}
146+
}
147+
148+
console.log("part 2 checksum ::", checksum);
149+
console.timeEnd("part 2");
150+
})();

0 commit comments

Comments
 (0)