Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 33193f9

Browse files
feat(js): add modular solution and documentation for hard challenge 5 - Line Sweep Closest Points
1 parent b71f394 commit 33193f9

File tree

3 files changed

+265
-0
lines changed

3 files changed

+265
-0
lines changed
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
# Line Sweep Algorithm - Closest Pair of Points
2+
3+
## English
4+
5+
The line sweep algorithm is a powerful technique in computational geometry for solving proximity problems efficiently. It reduces the complexity of finding the closest pair of points from O(n^2) to O(n log n) by sweeping a line across the plane and maintaining a dynamic set of candidate points.
6+
7+
This challenge involves using the line sweep algorithm to find the closest pair of points in a set of 2D coordinates.
8+
9+
### Relevant Code Snippet
10+
11+
```javascript
12+
class ClosestPoints {
13+
constructor(points) {
14+
this.points = points.slice().sort((a, b) => a[0] - b[0]);
15+
}
16+
17+
distance(p1, p2) {
18+
return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2);
19+
}
20+
21+
findClosestPair() {
22+
const active = [];
23+
let bestPair = [null, null];
24+
let bestDist = Infinity;
25+
let left = 0;
26+
27+
const bisectLeft = (arr, x) => {
28+
let low = 0, high = arr.length;
29+
while (low < high) {
30+
const mid = Math.floor((low + high) / 2);
31+
if (arr[mid] < x) low = mid + 1;
32+
else high = mid;
33+
}
34+
return low;
35+
};
36+
37+
const bisectRight = (arr, x) => {
38+
let low = 0, high = arr.length;
39+
while (low < high) {
40+
const mid = Math.floor((low + high) / 2);
41+
if (arr[mid] <= x) low = mid + 1;
42+
else high = mid;
43+
}
44+
return low;
45+
};
46+
47+
for (const point of this.points) {
48+
while (active.length > 0 && point[0] - this.points[left][0] > bestDist) {
49+
const idx = bisectLeft(active, this.points[left][1]);
50+
if (idx < active.length && active[idx] === this.points[left][1]) {
51+
active.splice(idx, 1);
52+
}
53+
left++;
54+
}
55+
56+
const yLower = point[1] - bestDist;
57+
const yUpper = point[1] + bestDist;
58+
const i = bisectLeft(active, yLower);
59+
const j = bisectRight(active, yUpper);
60+
61+
for (let k = i; k < j; k++) {
62+
const candidate = [point[0], active[k]];
63+
const dist = this.distance(point, candidate);
64+
if (dist < bestDist) {
65+
bestDist = dist;
66+
bestPair = [point, candidate];
67+
}
68+
}
69+
70+
const pos = bisectLeft(active, point[1]);
71+
active.splice(pos, 0, point[1]);
72+
}
73+
74+
return { pair: bestPair, distance: bestDist };
75+
}
76+
}
77+
```
78+
79+
### History
80+
81+
The line sweep algorithm has been widely used in computational geometry for efficient proximity queries and spatial optimization problems.
82+
83+
---
84+
85+
## Español
86+
87+
Algoritmo de Barrido Lineal - Par de Puntos Más Cercanos
88+
89+
El algoritmo de barrido lineal es una técnica poderosa en geometría computacional para resolver problemas de proximidad eficientemente. Reduce la complejidad de encontrar el par de puntos más cercanos de O(n^2) a O(n log n) al barrer una línea a través del plano y mantener un conjunto dinámico de puntos candidatos.
90+
91+
Este reto consiste en usar el algoritmo de barrido lineal para encontrar el par de puntos más cercanos en un conjunto de coordenadas 2D.
92+
93+
### Fragmento de Código Relevante
94+
95+
```javascript
96+
class ClosestPoints {
97+
constructor(points) {
98+
this.points = points.slice().sort((a, b) => a[0] - b[0]);
99+
}
100+
101+
distance(p1, p2) {
102+
return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2);
103+
}
104+
105+
findClosestPair() {
106+
const active = [];
107+
let bestPair = [null, null];
108+
let bestDist = Infinity;
109+
let left = 0;
110+
111+
const bisectLeft = (arr, x) => {
112+
let low = 0, high = arr.length;
113+
while (low < high) {
114+
const mid = Math.floor((low + high) / 2);
115+
if (arr[mid] < x) low = mid + 1;
116+
else high = mid;
117+
}
118+
return low;
119+
};
120+
121+
const bisectRight = (arr, x) => {
122+
let low = 0, high = arr.length;
123+
while (low < high) {
124+
const mid = Math.floor((low + high) / 2);
125+
if (arr[mid] <= x) low = mid + 1;
126+
else high = mid;
127+
}
128+
return low;
129+
};
130+
131+
for (const point of this.points) {
132+
while (active.length > 0 && point[0] - this.points[left][0] > bestDist) {
133+
const idx = bisectLeft(active, this.points[left][1]);
134+
if (idx < active.length && active[idx] === this.points[left][1]) {
135+
active.splice(idx, 1);
136+
}
137+
left++;
138+
}
139+
140+
const yLower = point[1] - bestDist;
141+
const yUpper = point[1] + bestDist;
142+
const i = bisectLeft(active, yLower);
143+
const j = bisectRight(active, yUpper);
144+
145+
for (let k = i; k < j; k++) {
146+
const candidate = [point[0], active[k]];
147+
const dist = this.distance(point, candidate);
148+
if (dist < bestDist) {
149+
bestDist = dist;
150+
bestPair = [point, candidate];
151+
}
152+
}
153+
154+
const pos = bisectLeft(active, point[1]);
155+
active.splice(pos, 0, point[1]);
156+
}
157+
158+
return { pair: bestPair, distance: bestDist };
159+
}
160+
}
161+
```
162+
163+
### Historia
164+
165+
El algoritmo de barrido lineal ha sido ampliamente usado en geometría computacional para consultas de proximidad eficientes y problemas de optimización espacial.
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// ClosestPoints.js - Line Sweep Algorithm to find closest pair of points in JavaScript
2+
3+
class ClosestPoints {
4+
constructor(points) {
5+
this.points = points.slice().sort((a, b) => a[0] - b[0]);
6+
}
7+
8+
distance(p1, p2) {
9+
return Math.sqrt((p1[0] - p2[0]) ** 2 + (p1[1] - p2[1]) ** 2);
10+
}
11+
12+
findClosestPair() {
13+
const active = [];
14+
let bestPair = [null, null];
15+
let bestDist = Infinity;
16+
let left = 0;
17+
18+
const bisectLeft = (arr, x) => {
19+
let low = 0,
20+
high = arr.length;
21+
while (low < high) {
22+
const mid = Math.floor((low + high) / 2);
23+
if (arr[mid] < x) low = mid + 1;
24+
else high = mid;
25+
}
26+
return low;
27+
};
28+
29+
const bisectRight = (arr, x) => {
30+
let low = 0,
31+
high = arr.length;
32+
while (low < high) {
33+
const mid = Math.floor((low + high) / 2);
34+
if (arr[mid] <= x) low = mid + 1;
35+
else high = mid;
36+
}
37+
return low;
38+
};
39+
40+
for (const point of this.points) {
41+
while (active.length > 0 && point[0] - this.points[left][0] > bestDist) {
42+
// Remove points[left][1] from active using binary search
43+
const idx = bisectLeft(active, this.points[left][1]);
44+
if (idx < active.length && active[idx] === this.points[left][1]) {
45+
active.splice(idx, 1);
46+
}
47+
left++;
48+
}
49+
50+
const yLower = point[1] - bestDist;
51+
const yUpper = point[1] + bestDist;
52+
const i = bisectLeft(active, yLower);
53+
const j = bisectRight(active, yUpper);
54+
55+
for (let k = i; k < j; k++) {
56+
const candidate = [point[0], active[k]];
57+
const dist = this.distance(point, candidate);
58+
if (dist < bestDist) {
59+
bestDist = dist;
60+
bestPair = [point, candidate];
61+
}
62+
}
63+
64+
// Insert point[1] into active in sorted order
65+
const pos = bisectLeft(active, point[1]);
66+
active.splice(pos, 0, point[1]);
67+
}
68+
69+
return { pair: bestPair, distance: bestDist };
70+
}
71+
}
72+
73+
export default ClosestPoints;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
Challenge:
3+
Use the line sweep algorithm to find the closest pair of points in a set of 2D coordinates.
4+
5+
This solution follows DRY principles and is implemented in JavaScript.
6+
*/
7+
8+
import ClosestPoints from "./ClosestPoints.js";
9+
10+
function main() {
11+
const points = [
12+
[2, 3],
13+
[12, 30],
14+
[40, 50],
15+
[5, 1],
16+
[12, 10],
17+
[3, 4],
18+
];
19+
20+
const closestPoints = new ClosestPoints(points);
21+
const result = closestPoints.findClosestPair();
22+
23+
console.log("Closest pair of points:", result.pair);
24+
console.log("Distance between closest points:", result.distance);
25+
}
26+
27+
main();

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /