Skip to content

Commit 5c4a2da

Browse files
committed
adding day 9 super slow solution
1 parent d57c755 commit 5c4a2da

File tree

5 files changed

+741
-2
lines changed

5 files changed

+741
-2
lines changed

package-lock.json

Lines changed: 29 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
},
1616
"dependencies": {
1717
"@datastructures-js/priority-queue": "^6.3.1",
18+
"@flatten-js/core": "^1.6.8",
1819
"@graph-algorithm/minimum-cut": "^2.0.0",
1920
"@shahata/inquirer-timeout-confirm-prompt": "^1.0.1",
2021
"chart.js": "^4.5.0",
@@ -49,4 +50,4 @@
4950
}
5051
]
5152
}
52-
}
53+
}

src/2025/day09.js

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
// import { Box, BooleanOperations, Polygon } from "@flatten-js/core";
2+
// const { intersect } = BooleanOperations;
3+
4+
export function part1(input) {
5+
let points = input.split("\n").map(line => {
6+
let [x, y] = line.split(",").map(Number);
7+
return { x, y };
8+
});
9+
let maxArea = 0;
10+
for (let i = 0; i < points.length; i++) {
11+
for (let j = i + 1; j < points.length; j++) {
12+
let p1 = points[i];
13+
let p2 = points[j];
14+
let area = Math.abs(p1.x - p2.x + 1) * Math.abs(p1.y - p2.y + 1);
15+
if (area > maxArea) {
16+
maxArea = area;
17+
}
18+
}
19+
}
20+
return maxArea;
21+
}
22+
23+
function connectPoints(p1, p2, grid) {
24+
let xStep = p1.x < p2.x ? 1 : p1.x > p2.x ? -1 : 0;
25+
let yStep = p1.y < p2.y ? 1 : p1.y > p2.y ? -1 : 0;
26+
let x = p1.x;
27+
let y = p1.y;
28+
while (x !== p2.x || y !== p2.y) {
29+
grid.set(`${y},${x}`, 1);
30+
x += xStep;
31+
y += yStep;
32+
}
33+
}
34+
35+
function findPointWithinShape(grid, height, width) {
36+
for (let y = 0; y < height; y++) {
37+
for (let x = 0; x < width; x++) {
38+
x = (Math.random() * width) | 0;
39+
y = (Math.random() * height) | 0;
40+
if (grid.get(`${y},${x}`) === 1) continue;
41+
let queue = [{ x, y }];
42+
let visited = new Set();
43+
let found = true;
44+
while (queue.length > 0) {
45+
let { x: cx, y: cy } = queue.shift();
46+
let key = `${cx},${cy}`;
47+
if (visited.has(key)) continue;
48+
visited.add(key);
49+
if (cx < 0 || cx >= width || cy < 0 || cy >= height) {
50+
found = false;
51+
break;
52+
}
53+
if (grid.get(`${cy},${cx}`) === 1) continue;
54+
queue.push({ x: cx + 1, y: cy });
55+
queue.push({ x: cx - 1, y: cy });
56+
queue.push({ x: cx, y: cy + 1 });
57+
queue.push({ x: cx, y: cy - 1 });
58+
}
59+
if (found) {
60+
return { x, y };
61+
}
62+
}
63+
}
64+
return null;
65+
}
66+
67+
function fillGrid(points, grid, height, width) {
68+
for (let i = 0; i < points.length; i++) {
69+
let p1 = points[i];
70+
let p2 = points[(i + 1) % points.length];
71+
connectPoints(p1, p2, grid);
72+
}
73+
let insidePoint = findPointWithinShape(grid, height, width);
74+
let queue = [insidePoint];
75+
let visited = new Set();
76+
while (queue.length > 0) {
77+
let { x: cx, y: cy } = queue.shift();
78+
let key = `${cx},${cy}`;
79+
if (visited.has(key)) continue;
80+
visited.add(key);
81+
if (grid.get(`${cy},${cx}`) === 1) continue;
82+
grid.set(`${cy},${cx}`, 1);
83+
queue.push({ x: cx + 1, y: cy });
84+
queue.push({ x: cx - 1, y: cy });
85+
queue.push({ x: cx, y: cy + 1 });
86+
queue.push({ x: cx, y: cy - 1 });
87+
}
88+
}
89+
90+
// function test(input) {
91+
// let points = input.split("\n").map(line => {
92+
// let [x, y] = line.split(",").map(Number);
93+
// return { x, y };
94+
// });
95+
// let maxArea = 0;
96+
// let polygon = new Polygon(points.map(p => [p.x, p.y]));
97+
// for (let i = 0; i < points.length; i++) {
98+
// for (let j = i + 1; j < points.length; j++) {
99+
// let a = points[i];
100+
// let b = points[j];
101+
// let minX = Math.min(a.x, b.x);
102+
// let maxX = Math.max(a.x, b.x);
103+
// let minY = Math.min(a.y, b.y);
104+
// let maxY = Math.max(a.y, b.y);
105+
// let box = new Box(minX, minY, maxX, maxY);
106+
107+
// let boxPolygon = new Polygon(box);
108+
// try {
109+
// let intersectionArea = intersect(polygon, boxPolygon).area();
110+
// let boxArea = boxPolygon.area();
111+
// if (intersectionArea === boxArea) {
112+
// let area = Math.abs(a.x - b.x + 1) * Math.abs(a.y - b.y + 1);
113+
// if (area > maxArea) {
114+
// maxArea = area;
115+
// }
116+
// }
117+
// } catch {
118+
// //
119+
// }
120+
// }
121+
// }
122+
// return maxArea;
123+
// }
124+
125+
function slow(input) {
126+
let points = input.split("\n").map(line => {
127+
let [x, y] = line.split(",").map(Number);
128+
return { x, y };
129+
});
130+
let maxArea = 0;
131+
for (let p of points) {
132+
p.x = Math.floor(p.x / 100);
133+
p.y = Math.floor(p.y / 100);
134+
}
135+
let maxX = Math.max(...points.map(p => p.x));
136+
let maxY = Math.max(...points.map(p => p.y));
137+
let grid = new Map();
138+
fillGrid(points, grid, maxY + 1, maxX + 1);
139+
let result;
140+
for (let i = 0; i < points.length; i++) {
141+
for (let j = i + 1; j < points.length; j++) {
142+
let p1 = points[i];
143+
let p2 = points[j];
144+
let isContained = true;
145+
let minX = Math.min(p1.x, p2.x);
146+
let maxX = Math.max(p1.x, p2.x);
147+
let minY = Math.min(p1.y, p2.y);
148+
let maxY = Math.max(p1.y, p2.y);
149+
for (let y = minY; y <= maxY; y++) {
150+
for (let x = minX; x <= maxX; x++) {
151+
if (grid.get(`${y},${x}`) !== 1) {
152+
isContained = false;
153+
break;
154+
}
155+
}
156+
if (!isContained) break;
157+
}
158+
if (!isContained) continue;
159+
let area = Math.abs(p1.x - p2.x + 1) * Math.abs(p1.y - p2.y + 1);
160+
if (area > maxArea) {
161+
maxArea = area;
162+
result = { i, j };
163+
}
164+
}
165+
}
166+
points = input.split("\n").map(line => {
167+
let [x, y] = line.split(",").map(Number);
168+
return { x, y };
169+
});
170+
let p1 = points[result.i];
171+
let p2 = points[result.j];
172+
maxArea = Math.abs(p1.x - p2.x + 1) * Math.abs(p1.y - p2.y + 1);
173+
return maxArea;
174+
}
175+
176+
export function part2(input) {
177+
return slow(input);
178+
}

src/2025/day09.test.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { part1, part2 } from "./day09.js";
2+
import { describe, test, expect } from "vitest";
3+
import readInput from "../utils/read-input.js";
4+
5+
let input = readInput(import.meta.url);
6+
7+
describe("day09 2025", () => {
8+
describe("part1", () => {
9+
test("it should work for part 1 examples", () => {
10+
expect(
11+
part1(
12+
["7,1", "11,1", "11,7", "9,7", "9,5", "2,5", "2,3", "7,3"].join("\n"),
13+
),
14+
).toEqual(50);
15+
});
16+
17+
test("it should work for part 1 input", () => {
18+
expect(part1(input)).toEqual(4769758290);
19+
});
20+
});
21+
22+
describe("part2", () => {
23+
test("it should work for part 2 examples", () => {
24+
expect(
25+
part2(
26+
["7,1", "11,1", "11,7", "9,7", "9,5", "2,5", "2,3", "7,3"].join("\n"),
27+
),
28+
).toEqual(24);
29+
});
30+
31+
test("it should work for part 2 input", () => {
32+
expect(part2(input)).toEqual(1588990708);
33+
});
34+
});
35+
});

0 commit comments

Comments
 (0)