Closest-pair problem: Difference between revisions

m
(Updated first D entry)
m (→‎{{header|Wren}}: Minor tidy)
(100 intermediate revisions by 44 users not shown)
Line 1:
[[Category:Geometry]]
{{task|Classic CS problems and programs}}{{Wikipedia|Closest pair of points problem}}
{{task|Classic CS problems and programs}}
The aim of this task is to provide a function to find the closest two points among a set of given points in two dimensions, i.e. to solve the [[wp:Closest pair of points problem|Closest pair of points problem]] in the ''planar'' case.
{{Wikipedia|Closest pair of points problem}}
 
 
The straightforward solution is a O(n<sup>2</sup>) algorithm (which we can call ''brute-force algorithm''); the pseudocode (using indexes) could be simply:
;Task:
Provide a function to find the closest two points among a set of given points in two dimensions, &nbsp; i.e. to solve the &nbsp; [[wp:Closest pair of points problem|Closest pair of points problem]] &nbsp; in the &nbsp; ''planar'' &nbsp; case.
 
The straightforward solution is a &nbsp; O(n<sup>2</sup>) &nbsp; algorithm &nbsp; (which we can call ''brute-force algorithm''); &nbsp; the pseudo-code (using indexes) could be simply:
 
'''bruteForceClosestPair''' of P(1), P(2), ... P(N)
Line 21 ⟶ 26:
'''endif'''
 
A better algorithm is based on the recursive divide&amp;conquer approach, &nbsp; as explained also at &nbsp; [[wp:Closest pair of points problem#Planar_case|Wikipedia's Closest pair of points problem]], &nbsp; which is &nbsp; O(''n'' log ''n''); &nbsp; a pseudocodepseudo-code could be:
 
'''closestPair''' of (xP, yP)
Line 56 ⟶ 61:
 
 
''';References and further readings''':
* &nbsp; [[wp:Closest pair of points problem|Closest pair of points problem]]
* &nbsp; [http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html Closest Pair (McGill)]
* &nbsp; [http://www.cs.ucsb.edu/~suri/cs235/ClosestPair.pdf Closest Pair (UCSB)]
* &nbsp; [http://classes.cec.wustl.edu/~cse241/handouts/closestpair.pdf Closest pair (WUStL)]
* &nbsp; [http://www.cs.iupui.edu/~xkzou/teaching/CS580/Divide-and-conquer-closestPair.ppt Closest pair (IUPUI)]
<br><br>
 
=={{header|360 Assembly}}==
<syntaxhighlight lang="360asm">* Closest Pair Problem 10/03/2017
CLOSEST CSECT
USING CLOSEST,R13 base register
B 72(R15) skip savearea
DC 17F'0' savearea
STM R14,R12,12(R13) save previous context
ST R13,4(R15) link backward
ST R15,8(R13) link forward
LR R13,R15 set addressability
LA R6,1 i=1
LA R7,2 j=2
BAL R14,DDCALC dd=(px(i)-px(j))^2+(py(i)-py(j))^2
BAL R14,DDSTORE ddmin=dd; ii=i; jj=j
LA R6,1 i=1
DO WHILE=(C,R6,LE,N) do i=1 to n
LA R7,1 j=1
DO WHILE=(C,R7,LE,N) do j=1 to n
BAL R14,DDCALC dd=(px(i)-px(j))^2+(py(i)-py(j))^2
IF CP,DD,GT,=P'0' THEN if dd>0 then
IF CP,DD,LT,DDMIN THEN if dd<ddmin then
BAL R14,DDSTORE ddmin=dd; ii=i; jj=j
ENDIF , endif
ENDIF , endif
LA R7,1(R7) j++
ENDDO , enddo j
LA R6,1(R6) i++
ENDDO , enddo i
ZAP WPD,DDMIN ddmin
DP WPD,=PL8'2' ddmin/2
ZAP SQRT2,WPD(8) sqrt2=ddmin/2
ZAP SQRT1,DDMIN sqrt1=ddmin
DO WHILE=(CP,SQRT1,NE,SQRT2) do while sqrt1<>sqrt2
ZAP SQRT1,SQRT2 sqrt1=sqrt2
ZAP WPD,DDMIN ddmin
DP WPD,SQRT1 /sqrt1
ZAP WP1,WPD(8) ddmin/sqrt1
AP WP1,SQRT1 +sqrt1
ZAP WPD,WP1 ~
DP WPD,=PL8'2' /2
ZAP SQRT2,WPD(8) sqrt2=(sqrt1+(ddmin/sqrt1))/2
ENDDO , enddo while
MVC PG,=CL80'the minimum distance '
ZAP WP1,SQRT2 sqrt2
BAL R14,EDITPK edit
MVC PG+21(L'WC),WC output
XPRNT PG,L'PG print buffer
XPRNT =CL22'is between the points:',22
MVC PG,PGP init buffer
L R1,II ii
SLA R1,4 *16
LA R4,PXY-16(R1) @px(ii)
MVC WP1,0(R4) px(ii)
BAL R14,EDITPK edit
MVC PG+3(L'WC),WC output
MVC WP1,8(R4) py(ii)
BAL R14,EDITPK edit
MVC PG+21(L'WC),WC output
XPRNT PG,L'PG print buffer
MVC PG,PGP init buffer
L R1,JJ jj
SLA R1,4 *16
LA R4,PXY-16(R1) @px(jj)
MVC WP1,0(R4) px(jj)
BAL R14,EDITPK edit
MVC PG+3(L'WC),WC output
MVC WP1,8(R4) py(jj)
BAL R14,EDITPK edit
MVC PG+21(L'WC),WC output
XPRNT PG,L'PG print buffer
L R13,4(0,R13) restore previous savearea pointer
LM R14,R12,12(R13) restore previous context
XR R15,R15 rc=0
BR R14 exit
DDCALC EQU * ---- dd=(px(i)-px(j))^2+(py(i)-py(j))^2
LR R1,R6 i
SLA R1,4 *16
LA R4,PXY-16(R1) @px(i)
LR R1,R7 j
SLA R1,4 *16
LA R5,PXY-16(R1) @px(j)
ZAP WP1,0(8,R4) px(i)
ZAP WP2,0(8,R5) px(j)
SP WP1,WP2 px(i)-px(j)
ZAP WPS,WP1 =
MP WP1,WPS (px(i)-px(j))*(px(i)-px(j))
ZAP WP2,8(8,R4) py(i)
ZAP WP3,8(8,R5) py(j)
SP WP2,WP3 py(i)-py(j)
ZAP WPS,WP2 =
MP WP2,WPS (py(i)-py(j))*(py(i)-py(j))
AP WP1,WP2 (px(i)-px(j))^2+(py(i)-py(j))^2
ZAP DD,WP1 dd=(px(i)-px(j))^2+(py(i)-py(j))^2
BR R14 ---- return
DDSTORE EQU * ---- ddmin=dd; ii=i; jj=j
ZAP DDMIN,DD ddmin=dd
ST R6,II ii=i
ST R7,JJ jj=j
BR R14 ---- return
EDITPK EQU * ----
MVC WM,MASK set mask
EDMK WM,WP1 edit and mark
BCTR R1,0 -1
MVC 0(1,R1),WM+17 set sign
MVC WC,WM len17<-len18
BR R14 ---- return
N DC A((PGP-PXY)/16)
PXY DC PL8'0.654682',PL8'0.925557',PL8'0.409382',PL8'0.619391'
DC PL8'0.891663',PL8'0.888594',PL8'0.716629',PL8'0.996200'
DC PL8'0.477721',PL8'0.946355',PL8'0.925092',PL8'0.818220'
DC PL8'0.624291',PL8'0.142924',PL8'0.211332',PL8'0.221507'
DC PL8'0.293786',PL8'0.691701',PL8'0.839186',PL8'0.728260'
PGP DC CL80' [+xxxxxxxxx.xxxxxx,+xxxxxxxxx.xxxxxx]'
MASK DC C' ',7X'20',X'21',X'20',C'.',6X'20',C'-' CL18 15num
II DS F
JJ DS F
DD DS PL8
DDMIN DS PL8
SQRT1 DS PL8
SQRT2 DS PL8
WP1 DS PL8
WP2 DS PL8
WP3 DS PL8
WPS DS PL8
WPD DS PL16
WM DS CL18
WC DS CL17
PG DS CL80
YREGS
END CLOSEST</syntaxhighlight>
{{out}}
<pre>
the minimum distance 0.077910
is between the points:
[ 0.891663, 0.888594]
[ 0.925092, 0.818220]
</pre>
=={{header|Ada}}==
Dimension independantindependent, but has to be defined at procedure call time (could be a parameter). Output is simple, can be formatted using Float_IO.
(could be a parameter).
Output is simple, can be formatted using Float_IO.
 
closest.adb: (uses brute force algorithm)
<langsyntaxhighlight Adalang="ada">with Ada.Numerics.Generic_Elementary_Functions;
with Ada.Text_IO;
 
Line 133 ⟶ 277:
Ada.Text_IO.Put_Line ("P2: " & Float'Image (Second_Points (2) (1)) & " " & Float'Image (Second_Points (2) (2)));
Ada.Text_IO.Put_Line ("Distance: " & Float'Image (Distance (Second_Points (1), Second_Points (2))));
end Closest;</langsyntaxhighlight>
 
{{out}}
Output:
<pre>Closest Points:
P1: 8.00000E+00 4.00000E+00
Line 144 ⟶ 288:
P2: 9.25092E-01 8.18220E-01
Distance: 7.79101E-02</pre>
=={{header|AutoHotkey}}==
 
<syntaxhighlight lang="autohotkey">ClosestPair(points){
if (points.count() <= 3)
return bruteForceClosestPair(points)
split := xSplit(Points)
LP := split.1 ; left points
LD := ClosestPair(LP) ; recursion : left closest pair
RP := split.2 ; right points
RD := ClosestPair(RP) ; recursion : right closest pair
minD := min(LD, RD) ; minimum of LD & RD
xmin := Split.3 - minD ; strip left boundary
xmax := Split.3 + minD ; strip right boundary
S := strip(points, xmin, xmax)
if (s.count()>=2)
{
SD := ClosestPair(S) ; recursion : strip closest pair
return min(SD, minD)
}
return minD
}
;---------------------------------------------------------------
strip(points, xmin, xmax){
strip:=[]
for i, coord in points
if (coord.1 >= xmin) && (coord.1 <= xmax)
strip.push([coord.1, coord.2])
return strip
}
;---------------------------------------------------------------
bruteForceClosestPair(points){
minD := []
loop, % points.count()-1{
p1 := points.RemoveAt(1)
loop, % points.count(){
p2 := points[A_Index]
d := dist(p1, p2)
minD.push(d)
}
}
return min(minD*)
}
;---------------------------------------------------------------
dist(p1, p2){
return Sqrt((p2.1-p1.1)**2 + (p2.2-p1.2)**2)
}
;---------------------------------------------------------------
xSplit(Points){
xL := [], xR := []
p := xSort(Points)
Loop % Ceil(p.count()/2)
xL.push(p.RemoveAt(1))
while p.count()
xR.push(p.RemoveAt(1))
mid := (xL[xl.count(),1] + xR[1,1])/2
return [xL, xR, mid]
}
;---------------------------------------------------------------
xSort(Points){
S := [], Res :=[]
for i, coord in points
S[coord.1, coord.2] := true
for x, coord in S
for y, v in coord
res.push([x, y])
return res
}
;---------------------------------------------------------------</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">points := [[1, 1], [12, 30], [40, 50], [5, 1], [12, 10], [3, 4], [17,25], [45,50],[51,34],[2,1],[2,2],[10,10]]
MsgBox % ClosestPair(points)</syntaxhighlight>
{{out}}
<pre>1.000000</pre>
=={{header|AWK}}==
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f CLOSEST-PAIR_PROBLEM.AWK
BEGIN {
Line 173 ⟶ 387:
exit(0)
}
</syntaxhighlight>
</lang>
{{out}}
<p>output:</p>
<pre>
distance between (0.891663,0.888594) and (0.925092,0.818220) is 0.0779102
</pre>
 
=={{header|BBC BASIC}}==
=={{header|BASIC}}==
To find the closest pair it is sufficient to compare the squared-distances, it is not necessary to perform the square root for each pair!
==={{header|BASIC256}}===
<lang bbcbasic> DIM x(9), y(9)
'''Versión de fuerza bruta:
<syntaxhighlight lang="basic256">
Dim x(9)
x = {0.654682, 0.409382, 0.891663, 0.716629, 0.477721, 0.925092, 0.624291, 0.211332, 0.293786, 0.839186}
Dim y(9)
y = {0.925557, 0.619391, 0.888594, 0.996200, 0.946355, 0.818220, 0.142924, 0.221507, 0.691701, 0.728260}
 
minDist = 1^30
For i = 0 To 8
For j = i+1 To 9
dist = (x[i] - x[j])^2 + (y[i] - y[j])^2
If dist < minDist Then minDist = dist : minDisti = i : minDistj = j
Next j
Next i
Print "El par más cercano es "; minDisti; " y "; minDistj; " a una distancia de "; Sqr(minDist)
End
</syntaxhighlight>
{{out}}
<pre>
El par más cercano es 2 y 5 a una distancia de 0,077910191355
</pre>
 
==={{header|BBC BASIC}}===
To find the closest pair it is sufficient to compare the squared-distances,
it is not necessary to perform the square root for each pair!
<syntaxhighlight lang="bbcbasic"> DIM x(9), y(9)
FOR I% = 0 TO 9
Line 206 ⟶ 446:
DATA 0.293786, 0.691701
DATA 0.839186, 0.728260
</syntaxhighlight>
</lang>
{{out}}
Output:
<pre>Closest pair is 2 and 5 at distance 0.0779101913</pre>
 
=={{header|C}}==
See [[Closest-pair problem/C]]
=={{header|C sharp|C#}}==
We provide a small helper class for distance comparisons:
<syntaxhighlight lang="csharp">class Segment
{
public Segment(PointF p1, PointF p2)
{
P1 = p1;
P2 = p2;
}
 
public readonly PointF P1;
public readonly PointF P2;
 
public float Length()
{
return (float)Math.Sqrt(LengthSquared());
}
 
public float LengthSquared()
{
return (P1.X - P2.X) * (P1.X - P2.X)
+ (P1.Y - P2.Y) * (P1.Y - P2.Y);
}
}</syntaxhighlight>
 
Brute force:
<syntaxhighlight lang="csharp">Segment Closest_BruteForce(List<PointF> points)
{
int n = points.Count;
var result = Enumerable.Range( 0, n-1)
.SelectMany( i => Enumerable.Range( i+1, n-(i+1) )
.Select( j => new Segment( points[i], points[j] )))
.OrderBy( seg => seg.LengthSquared())
.First();
 
return result;
}</syntaxhighlight>
 
 
And divide-and-conquer.
<syntaxhighlight lang="csharp">
public static Segment MyClosestDivide(List<PointF> points)
{
return MyClosestRec(points.OrderBy(p => p.X).ToList());
}
 
private static Segment MyClosestRec(List<PointF> pointsByX)
{
int count = pointsByX.Count;
if (count <= 4)
return Closest_BruteForce(pointsByX);
 
// left and right lists sorted by X, as order retained from full list
var leftByX = pointsByX.Take(count/2).ToList();
var leftResult = MyClosestRec(leftByX);
 
var rightByX = pointsByX.Skip(count/2).ToList();
var rightResult = MyClosestRec(rightByX);
 
var result = rightResult.Length() < leftResult.Length() ? rightResult : leftResult;
 
// There may be a shorter distance that crosses the divider
// Thus, extract all the points within result.Length either side
var midX = leftByX.Last().X;
var bandWidth = result.Length();
var inBandByX = pointsByX.Where(p => Math.Abs(midX - p.X) <= bandWidth);
 
// Sort by Y, so we can efficiently check for closer pairs
var inBandByY = inBandByX.OrderBy(p => p.Y).ToArray();
 
int iLast = inBandByY.Length - 1;
for (int i = 0; i < iLast; i++ )
{
var pLower = inBandByY[i];
 
for (int j = i + 1; j <= iLast; j++)
{
var pUpper = inBandByY[j];
 
// Comparing each point to successivly increasing Y values
// Thus, can terminate as soon as deltaY is greater than best result
if ((pUpper.Y - pLower.Y) >= result.Length())
break;
 
if (Segment.Length(pLower, pUpper) < result.Length())
result = new Segment(pLower, pUpper);
}
}
 
return result;
}
</syntaxhighlight>
 
However, the difference in speed is still remarkable.
<syntaxhighlight lang="csharp">var randomizer = new Random(10);
var points = Enumerable.Range( 0, 10000).Select( i => new PointF( (float)randomizer.NextDouble(), (float)randomizer.NextDouble())).ToList();
Stopwatch sw = Stopwatch.StartNew();
var r1 = Closest_BruteForce(points);
sw.Stop();
Debugger.Log(1, "", string.Format("Time used (Brute force) (float): {0} ms", sw.Elapsed.TotalMilliseconds));
Stopwatch sw2 = Stopwatch.StartNew();
var result2 = Closest_Recursive(points);
sw2.Stop();
Debugger.Log(1, "", string.Format("Time used (Divide & Conquer): {0} ms",sw2.Elapsed.TotalMilliseconds));
Assert.Equal(r1.Length(), result2.Length());</syntaxhighlight>
 
{{out}}
<pre>Time used (Brute force) (float): 145731.8935 ms
Time used (Divide & Conquer): 1139.2111 ms</pre>
 
Non Linq Brute Force:
<syntaxhighlight lang="csharp">
Segment Closest_BruteForce(List<PointF> points)
{
Trace.Assert(points.Count >= 2);
 
int count = points.Count;
// Seed the result - doesn't matter what points are used
// This just avoids having to do null checks in the main loop below
var result = new Segment(points[0], points[1]);
var bestLength = result.Length();
 
for (int i = 0; i < count; i++)
for (int j = i + 1; j < count; j++)
if (Segment.Length(points[i], points[j]) < bestLength)
{
result = new Segment(points[i], points[j]);
bestLength = result.Length();
}
 
return result;
}</syntaxhighlight>
 
Targeted Search: Much simpler than divide and conquer, and actually runs faster for the random points. Key optimization is that if the distance along the X axis is greater than the best total length you already have, you can terminate the inner loop early. However, as only sorts in the X direction, it degenerates into an N^2 algorithm if all the points have the same X.
 
<syntaxhighlight lang="csharp">
Segment Closest(List<PointF> points)
{
Trace.Assert(points.Count >= 2);
 
int count = points.Count;
points.Sort((lhs, rhs) => lhs.X.CompareTo(rhs.X));
 
var result = new Segment(points[0], points[1]);
var bestLength = result.Length();
 
for (int i = 0; i < count; i++)
{
var from = points[i];
 
for (int j = i + 1; j < count; j++)
{
var to = points[j];
 
var dx = to.X - from.X;
if (dx >= bestLength)
{
break;
}
 
if (Segment.Length(from, to) < bestLength)
{
result = new Segment(from, to);
bestLength = result.Length();
}
}
}
 
return result;
}
</syntaxhighlight>
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">/*
Author: Kevin Bacon
Date: 04/03/2014
Line 265 ⟶ 676:
std::copy(std::begin(xP), std::begin(xP) + (N / 2), std::back_inserter(xL));
std::copy(std::begin(xP) + (N / 2), std::end(xP), std::back_inserter(xR));
auto xM = xP.at((N-1) / 2).first;
auto yL = std::vector<point_t>();
auto yR = std::vector<point_t>();
Line 327 ⟶ 738:
print_point(answer.second.second);
return 0;
}</langsyntaxhighlight>
 
{{out}}
Output:
<pre>Min distance (brute): 6.95886 (932.735, 1002.7), (939.216, 1000.17)
Min distance (optimized): 6.95886 (932.735, 1002.7), (939.216, 1000.17)</pre>
 
=={{header|Clojure}}==
 
<langsyntaxhighlight lang="clojure">
(defn distance [[x1 y1] [x2 y2]]
(let [dx (- x2 x1), dy (- y2 y1)]
Line 372 ⟶ 782:
{yS true} (group-by (fn [[px _]] (< (Math/abs (- xm px)) dmin)) yP)]
(combine yS [dmin pmin1 pmin2])))))
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
 
Points are conses whose cars are x coördinates and whose cdrs are y coördinates. This version includes the optimizations given in the [http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairDQ.html McGill description] of the algorithm.
 
<langsyntaxhighlight lang="lisp">(defun point-distance (p1 p2)
(destructuring-bind (x1 . y1) p1
(destructuring-bind (x2 . y2) p2
Line 432 ⟶ 841:
(multiple-value-bind (pair distance)
(cp (sort (copy-list points) '< :key 'car))
(values pair distance))))</langsyntaxhighlight>
=={{header|Crystal}}==
 
=={{header|C sharp|C#}}==
We provide a small helper class for distance comparisons:
<lang csharp>class Segment
{
public Segment(PointF p1, PointF p2)
{
P1 = p1;
P2 = p2;
}
 
public readonly PointF P1;
public readonly PointF P2;
 
public float Length()
{
return (float)Math.Sqrt(LengthSquared());
}
 
public float LengthSquared()
{
return (P1.X - P2.X) * (P1.X - P2.X)
+ (P1.Y - P2.Y) * (P1.Y - P2.Y);
}
}</lang>
 
Brute force:
<lang csharp>Segment Closest_BruteForce(List<PointF> points)
{
int n = points.Count;
var result = Enumerable.Range( 0, n-1)
.SelectMany( i => Enumerable.Range( i+1, n-(i+1) )
.Select( j => new Segment( points[i], points[j] )))
.OrderBy( seg => seg.LengthSquared())
.First();
 
return result;
}</lang>
 
 
And divide-and-conquer.
<lang csharp>
public static Segment MyClosestDivide(List<PointF> points)
{
return MyClosestRec(points.OrderBy(p => p.X).ToList());
}
 
private static Segment MyClosestRec(List<PointF> pointsByX)
{
int count = pointsByX.Count;
if (count <= 4)
return Closest_BruteForce(pointsByX);
 
// left and right lists sorted by X, as order retained from full list
var leftByX = pointsByX.Take(count/2).ToList();
var leftResult = MyClosestRec(leftByX);
 
var rightByX = pointsByX.Skip(count/2).ToList();
var rightResult = MyClosestRec(rightByX);
 
var result = rightResult.Length() < leftResult.Length() ? rightResult : leftResult;
 
// There may be a shorter distance that crosses the divider
// Thus, extract all the points within result.Length either side
var midX = leftByX.Last().X;
var bandWidth = result.Length();
var inBandByX = pointsByX.Where(p => Math.Abs(midX - p.X) <= bandWidth);
 
// Sort by Y, so we can efficiently check for closer pairs
var inBandByY = inBandByX.OrderBy(p => p.Y).ToArray();
 
int iLast = inBandByY.Length - 1;
for (int i = 0; i < iLast; i++ )
{
var pLower = inBandByY[i];
 
for (int j = i + 1; j <= iLast; j++)
{
var pUpper = inBandByY[j];
 
// Comparing each point to successivly increasing Y values
// Thus, can terminate as soon as deltaY is greater than best result
if ((pUpper.Y - pLower.Y) >= result.Length())
break;
 
if (Segment.Length(pLower, pUpper) < result.Length())
result = new Segment(pLower, pUpper);
}
}
 
return result;
}
</lang>
 
However, the difference in speed is still remarkable.
<lang csharp>var randomizer = new Random(10);
var points = Enumerable.Range( 0, 10000).Select( i => new PointF( (float)randomizer.NextDouble(), (float)randomizer.NextDouble())).ToList();
Stopwatch sw = Stopwatch.StartNew();
var r1 = Closest_BruteForce(points);
sw.Stop();
Debugger.Log(1, "", string.Format("Time used (Brute force) (float): {0} ms", sw.Elapsed.TotalMilliseconds));
Stopwatch sw2 = Stopwatch.StartNew();
var result2 = Closest_Recursive(points);
sw2.Stop();
Debugger.Log(1, "", string.Format("Time used (Divide & Conquer): {0} ms",sw2.Elapsed.TotalMilliseconds));
Assert.Equal(r1.Length(), result2.Length());</lang>
 
Output:
<lang>Time used (Brute force) (float): 145731.8935 ms
Time used (Divide & Conquer): 1139.2111 ms</lang>
 
Non Linq Brute Force:
<lang csharp>
Segment Closest_BruteForce(List<PointF> points)
{
Trace.Assert(points.Count >= 2);
 
int count = points.Count;
// Seed the result - doesn't matter what points are used
// This just avoids having to do null checks in the main loop below
var result = new Segment(points[0], points[1]);
var bestLength = result.Length();
 
for (int i = 0; i < count; i++)
for (int j = i + 1; j < count; j++)
if (Segment.Length(points[i], points[j]) < bestLength)
{
result = new Segment(points[i], points[j]);
bestLength = result.Length();
}
 
return result;
}</lang>
 
Targeted Search: Much simpler than divide and conquer, and actually runs faster for the random points. Key optimization is that if the distance along the X axis is greater than the best total length you already have, you can terminate the inner loop early. However, as only sorts in the X direction, it degenerates into an N^2 algorithm if all the points have the same X.
 
<lang csharp>
Segment Closest(List<PointF> points)
{
Trace.Assert(points.Count >= 2);
 
int count = points.Count;
points.Sort((lhs, rhs) => lhs.X.CompareTo(rhs.X));
 
var result = new Segment(points[0], points[1]);
var bestLength = result.Length();
 
for (int i = 0; i < count; i++)
{
var from = points[i];
 
for (int j = i + 1; j < count; j++)
{
var to = points[j];
 
var dx = to.X - from.X;
if (dx >= bestLength)
{
break;
}
 
if (Segment.Length(from, to) < bestLength)
{
result = new Segment(from, to);
bestLength = result.Length();
}
}
}
 
return result;
}
</lang>
 
=={{header|D}}==
===Compact Versions===
<langsyntaxhighlight lang="d">import std.stdio, std.typecons, std.math, std.algorithm,
std.random, std.traits, std.range, std.complex;
 
Line 682 ⟶ 918:
writeln("bruteForceClosestPair: ", points.bruteForceClosestPair);
writeln(" closestPair: ", points.closestPair);
}</langsyntaxhighlight>
{{out}}
<pre>[5+9i, 9+3i, 2+0i, 8+4i, 7+4i, 9+10i, 1+9i, 8+2i, 0+10i, 9+6i]
Line 692 ⟶ 928:
 
===Faster Brute-force Version===
<langsyntaxhighlight lang="d">import std.stdio, std.random, std.math, std.typecons, std.complex,
std.traits;
 
Line 730 ⟶ 966:
writefln("Closest pair: Distance: %f p1, p2: %f, %f",
abs(pts[ij[0]] - pts[ij[1]]), pts[ij[0]], pts[ij[1]]);
}</langsyntaxhighlight>
{{out}}
<pre>Closest pair: Distance: 0.019212 p1, p2: 9.74223+119.419i, 9.72306+119.418i</pre>
About 0.12 seconds run-time for brute-force version 2 (10_000 points) with with LDC2 compiler.
=={{header|Delphi}}==
See [https://rosettacode.org/wiki/Closest-pair_problem#Pascal Pascal].
=={{header|EasyLang}}==
{{trans|AWK}}
<syntaxhighlight>
# bruteforce
numfmt 4 0
x[] = [ 0.654682 0.409382 0.891663 0.716629 0.477721 0.925092 0.624291 0.211332 0.293786 0.839186 ]
y[] = [ 0.925557 0.619391 0.888594 0.996200 0.946355 0.818220 0.142924 0.221507 0.691701 0.728260 ]
n = len x[]
min = 1 / 0
for i to n - 1
for j = i + 1 to n
dx = x[i] - x[j]
dy = y[i] - y[j]
dsq = dx * dx + dy * dy
if dsq < min
min = dsq
mini = i
minj = j
.
.
.
print "distance between (" & x[mini] & " " & y[mini] & ") and (" & x[minj] & " " & y[minj] & ") is " & sqrt min
</syntaxhighlight>
 
=={{header|Elixir}}==
<syntaxhighlight lang="elixir">defmodule Closest_pair do
# brute-force algorithm:
def bruteForce([p0,p1|_] = points), do: bf_loop(points, {distance(p0, p1), {p0, p1}})
defp bf_loop([_], acc), do: acc
defp bf_loop([h|t], acc), do: bf_loop(t, bf_loop(h, t, acc))
defp bf_loop(_, [], acc), do: acc
defp bf_loop(p0, [p1|t], {minD, minP}) do
dist = distance(p0, p1)
if dist < minD, do: bf_loop(p0, t, {dist, {p0, p1}}),
else: bf_loop(p0, t, {minD, minP})
end
defp distance({p0x,p0y}, {p1x,p1y}) do
:math.sqrt( (p1x - p0x) * (p1x - p0x) + (p1y - p0y) * (p1y - p0y) )
end
# recursive divide&conquer approach:
def recursive(points) do
recursive(Enum.sort(points), Enum.sort_by(points, fn {_x,y} -> y end))
end
def recursive(xP, _yP) when length(xP) <= 3, do: bruteForce(xP)
def recursive(xP, yP) do
{xL, xR} = Enum.split(xP, div(length(xP), 2))
{xm, _} = hd(xR)
{yL, yR} = Enum.partition(yP, fn {x,_} -> x < xm end)
{dL, pairL} = recursive(xL, yL)
{dR, pairR} = recursive(xR, yR)
{dmin, pairMin} = if dL<dR, do: {dL, pairL}, else: {dR, pairR}
yS = Enum.filter(yP, fn {x,_} -> abs(xm - x) < dmin end)
merge(yS, {dmin, pairMin})
end
defp merge([_], acc), do: acc
defp merge([h|t], acc), do: merge(t, merge_loop(h, t, acc))
defp merge_loop(_, [], acc), do: acc
defp merge_loop(p0, [p1|_], {dmin,_}=acc) when dmin <= elem(p1,1) - elem(p0,1), do: acc
defp merge_loop(p0, [p1|t], {dmin, pair}) do
dist = distance(p0, p1)
if dist < dmin, do: merge_loop(p0, t, {dist, {p0, p1}}),
else: merge_loop(p0, t, {dmin, pair})
end
end
 
data = [{0.654682, 0.925557}, {0.409382, 0.619391}, {0.891663, 0.888594}, {0.716629, 0.996200},
{0.477721, 0.946355}, {0.925092, 0.818220}, {0.624291, 0.142924}, {0.211332, 0.221507},
{0.293786, 0.691701}, {0.839186, 0.728260}]
 
IO.inspect Closest_pair.bruteForce(data)
IO.inspect Closest_pair.recursive(data)
 
data2 = for _ <- 1..5000, do: {:rand.uniform, :rand.uniform}
IO.puts "\nBrute-force:"
IO.inspect :timer.tc(fn -> Closest_pair.bruteForce(data2) end)
IO.puts "Recursive divide&conquer:"
IO.inspect :timer.tc(fn -> Closest_pair.recursive(data2) end)</syntaxhighlight>
 
{{out}}
<pre>
{0.07791019135517516, {{0.891663, 0.888594}, {0.925092, 0.81822}}}
{0.07791019135517516, {{0.891663, 0.888594}, {0.925092, 0.81822}}}
 
Brute-force:
{9579000,
{2.068674444452469e-4,
{{0.9397601102440695, 0.020420581980209674},
{0.9399398976079764, 0.020522908141823986}}}}
Recursive divide&conquer:
{109000,
{2.068674444452469e-4,
{{0.9397601102440695, 0.020420581980209674},
{0.9399398976079764, 0.020522908141823986}}}}
</pre>
 
=={{header|F Sharp|F#}}==
Brute force:
<langsyntaxhighlight lang="fsharp">
let closest_pairs (xys: Point []) =
let n = xys.Length
Line 744 ⟶ 1,083:
yield xys.[i], xys.[j] }
|> Seq.minBy (fun (p0, p1) -> (p1 - p0).LengthSquared)
</syntaxhighlight>
</lang>
For example:
<langsyntaxhighlight lang="fsharp">
closest_pairs
[|Point(0.0, 0.0); Point(1.0, 0.0); Point (2.0, 2.0)|]
</syntaxhighlight>
</lang>
gives:
<langsyntaxhighlight lang="fsharp">
(0,0, 1,0)
</syntaxhighlight>
</lang>
 
Divide And Conquer:
 
<langsyntaxhighlight lang="fsharp">
 
open System;
Line 848 ⟶ 1,187:
printfn "Closest Pair '%A'. Distance %f" closest (Length closest)
printfn "Took %d [ms]" takenMs
</syntaxhighlight>
</lang>
 
=={{header|Fantom}}==
 
(Based on the Ruby example.)
 
<langsyntaxhighlight lang="fantom">
class Point
{
Line 973 ⟶ 1,311:
}
}
</syntaxhighlight>
</lang>
 
Output:
 
{{out}}
<pre>
$ fan closestPoints 1000
Line 989 ⟶ 1,326:
Time taken: 228ms
</pre>
 
=={{header|Fortran}}==
See [[Closest pair problem/Fortran]]
=={{header|FreeBASIC}}==
'''Versión de fuerza bruta:
<syntaxhighlight lang="freebasic">
Dim As Integer i, j
Dim As Double minDist = 1^30
Dim As Double x(9), y(9), dist, mini, minj
 
Data 0.654682, 0.925557
Data 0.409382, 0.619391
Data 0.891663, 0.888594
Data 0.716629, 0.996200
Data 0.477721, 0.946355
Data 0.925092, 0.818220
Data 0.624291, 0.142924
Data 0.211332, 0.221507
Data 0.293786, 0.691701
Data 0.839186, 0.728260
 
For i = 0 To 9
Read x(i), y(i)
Next i
 
For i = 0 To 8
For j = i+1 To 9
dist = (x(i) - x(j))^2 + (y(i) - y(j))^2
If dist < minDist Then
minDist = dist
mini = i
minj = j
End If
Next j
Next i
 
Print "El par más cercano es "; mini; " y "; minj; " a una distancia de "; Sqr(minDist)
End
</syntaxhighlight>
{{out}}
<pre>
El par más cercano es 2 y 5 a una distancia de 0.07791019135517516
</pre>
 
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
_elements = 9
 
local fn ClosetPairProblem
long i, j
double minDist = 1000000
double dist, minDisti, minDistj
double x(_elements), y(_elements)
x(0) = 0.654682 : y(0) = 0.925557
x(1) = 0.409382 : y(1) = 0.619391
x(2) = 0.891663 : y(2) = 0.888594
x(3) = 0.716629 : y(3) = 0.996200
x(4) = 0.477721 : y(4) = 0.946355
x(5) = 0.925092 : y(5) = 0.818220
x(6) = 0.624291 : y(6) = 0.142924
x(7) = 0.211332 : y(7) = 0.221507
x(8) = 0.293786 : y(8) = 0.691701
x(9) = 0.839186 : y(9) = 0.728260
for i = 0 to 8
for j = i + 1 to 9
dist = ( x(i) - x(j) )^2 + ( y(i) - y(j) )^2
if dist < minDist then minDist = dist : minDisti = i : minDistj = j
next
next
print "The closest pair is "; minDisti; " and "; minDistj; " at a distance of "; sqr(minDist)
end fn
 
fn ClosetPairProblem
 
HandleEvents
</syntaxhighlight>
{{output}}
<pre>
The closest pair is 2 and 5 at a distance of 0.07791019135517516
</pre>
 
 
=={{header|Go}}==
'''Brute force'''
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,000 ⟶ 1,419:
"math"
"math/rand"
"time"
)
 
Line 1,007 ⟶ 1,427:
 
const n = 1000
const scale = 1100.
 
func d(p1, p2 xy) float64 {
dx :=return math.Hypot(p2.x - p1.x, p2.y-p1.y)
dy := p2.y - p1.y
return math.Sqrt(dx*dx + dy*dy)
}
 
func main() {
rand.Seed(time.Now().Unix())
points := make([]xy, n)
for i := range points {
points[i] = xy{rand.Float64() * scale, rand.Float64() * scale}
}
p1, p2 := closestPair(points)
Line 1,039 ⟶ 1,458:
}
return
}</langsyntaxhighlight>
'''O(n)'''
<langsyntaxhighlight lang="go">// implementation following algorithm described in
// http://www.cs.umd.edu/~samir/grant/cp.pdf
package main
Line 1,049 ⟶ 1,468:
"math"
"math/rand"
"time"
)
 
Line 1,056 ⟶ 1,476:
// size of bounding box for points.
// x and y will be random with uniform distribution in the range [0,scale).
const scale = 1100.
 
// point struct
Line 1,064 ⟶ 1,484:
}
 
// Euclidian distance
func d(p1, p2 xy) float64 {
dx :=return math.Hypot(p2.x - p1.x, p2.y-p1.y)
dy := p2.y - p1.y
return math.Sqrt(dx*dx + dy*dy)
}
 
func main() {
rand.Seed(time.Now().Unix())
points := make([]xy, n)
for i := range points {
points[i] = xy{rand.Float64() * scale, rand.Float64() * scale, 0}
}
p1, p2 := closestPair(points)
Line 1,107 ⟶ 1,525:
// construct map as a histogram:
// key is index into mesh. value is count of points in cell
hm := make(map[int64]int){}
for ip, p := range s1 {
key := int64(p.x*invB)*mx + int64(p.y*invB)
Line 1,114 ⟶ 1,532:
}
// construct s2 = s1 less the points without neighbors
var s2 := make([]xy, 0, len(s1))
nx := []int64{-mx - 1, -mx, -mx + 1, -1, 0, 1, mx - 1, mx, mx + 1}
for i, p := range s1 {
Line 1,136 ⟶ 1,554:
invB := 1 / dxi
mx := int64(scale*invB) + 1
hm := make(map[int64][]int){}
for i, p := range s {
key := int64(p.x*invB)*mx + int64(p.y*invB)
Line 1,144 ⟶ 1,562:
nx := []int64{-mx - 1, -mx, -mx + 1, -1, 0, 1, mx - 1, mx, mx + 1}
var min = scale * 2
for ip, p := range s {
for _, ofs := range nx {
for _, iq := range hm[p.key+ofs] {
Line 1,157 ⟶ 1,575:
}
return p1, p2
}</langsyntaxhighlight>
 
=={{header|Groovy}}==
Point class:
<langsyntaxhighlight lang="groovy">class Point {
final Number x, y
Point(Number x = 0, Number y = 0) { this.x = x; this.y = y }
Number distance(Point that) { ((this.x - that.x)**2 + (this.y - that.y)**2)**0.5 }
String toString() { "{x:${x}, y:${y}}" }
}</langsyntaxhighlight>
 
Brute force solution. Incorporates X-only and Y-only pre-checks in two places to cut down on the square root calculations:
<langsyntaxhighlight lang="groovy">def bruteClosest(Collection pointCol) {
assert pointCol
List l = pointCol
Line 1,191 ⟶ 1,608:
}
answer
}</langsyntaxhighlight>
 
Elegant (divide-and-conquer reduction) solution. Incorporates X-only and Y-only pre-checks in two places (four if you count the inclusion of the brute force solution) to cut down on the square root calculations:
<langsyntaxhighlight lang="groovy">def elegantClosest(Collection pointCol) {
assert pointCol
List xList = (pointCol as List).sort { it.x }
Line 1,241 ⟶ 1,658:
}
answer
}</langsyntaxhighlight>
 
Benchmark/Test:
<langsyntaxhighlight lang="groovy">def random = new Random()
 
(1..4).each {
Line 1,271 ⟶ 1,688:
=========================================
"""
}</langsyntaxhighlight>
 
Results:
Line 1,328 ⟶ 1,745:
Speedup ratio (B/E): 26.3500255493
=========================================</pre>
 
=={{header|Haskell}}==
BF solution:
<langsyntaxhighlight Haskelllang="haskell">import Data.List (minimumBy, tails, unfoldr, foldl1') --'
import System.Random
import Control.Monad
import Control.Arrow
import Data.Ord
 
import System.Random (newStdGen, randomRs)
vecLeng [[a,b],[p,q]] = sqrt $ (a-p)^2+(b-q)^2
 
import Control.Arrow ((&&&))
findClosestPair = foldl1' ((minimumBy (comparing vecLeng). ). (. return). (:)) .
concatMap (\(x:xs) -> map ((x:).return) xs) . init . tails
 
import Data.Ord (comparing)
testCP = do
g <- newStdGen
let pts :: [[Double]]
pts = take 1000. unfoldr (Just. splitAt 2) $ randomRs(-1,1) g
print . (id &&& vecLeng ) . findClosestPair $ pts</lang>
Output example:
<lang Haskell>*Main> testCP
([[0.8347201880148426,0.40774840545089647],[0.8348731214261784,0.4087113189531284]],9.749825850154334e-4)
(4.02 secs, 488869056 bytes)</lang>
 
vecLeng [[a, b], [p, q]] = sqrt $ (a - p) ^ 2 + (b - q) ^ 2
 
findClosestPair =
foldl1'' ((minimumBy (comparing vecLeng) .) . (. return) . (:)) .
concatMap (\(x:xs) -> map ((x :) . return) xs) . init . tails
 
testCP = do
g <- newStdGen
let pts :: [[Double]]
pts = take 1000 . unfoldr (Just . splitAt 2) $ randomRs (-1, 1) g
print . (id &&& vecLeng) . findClosestPair $ pts
 
main = testCP
 
foldl1'' = foldl1'
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="haskell">*Main> testCP
([[0.8347201880148426,0.40774840545089647],[0.8348731214261784,0.4087113189531284]],9.749825850154334e-4)
(4.02 secs, 488869056 bytes)</syntaxhighlight>
=={{header|Icon}} and {{header|Unicon}}==
This is a brute force solution. It combines reading the points with computing the closest
It combines reading the points with computing the closest pair seen so far.
<langsyntaxhighlight lang="unicon">record point(x,y)
 
procedure main()
Line 1,379 ⟶ 1,802:
procedure dSquared(p1,p2) # Compute the square of the distance
return (p2.x-p1.x)^2 + (p2.y-p1.y)^2 # (sufficient for closeness)
end</langsyntaxhighlight>
=={{header|IS-BASIC}}==
 
<syntaxhighlight lang="is-basic">100 PROGRAM "Closestp.bas"
110 NUMERIC X(1 TO 10),Y(1 TO 10)
120 FOR I=1 TO 10
130 READ X(I),Y(I)
140 PRINT X(I),Y(I)
150 NEXT
160 LET MN=INF
170 FOR I=1 TO 9
180 FOR J=I+1 TO 10
190 LET DSQ=(X(I)-X(J))^2+(Y(I)-Y(J))^2
200 IF DSQ<MN THEN LET MN=DSQ:LET MINI=I:LET MINJ=J
210 NEXT
220 NEXT
230 PRINT "Closest pair is (";X(MINI);",";Y(MINI);") and (";X(MINJ);",";Y(MINJ);")":PRINT "at distance";SQR(MN)
240 DATA 0.654682,0.925557
250 DATA 0.409382,0.619391
260 DATA 0.891663,0.888594
270 DATA 0.716629,0.996200
280 DATA 0.477721,0.946355
290 DATA 0.925092,0.818220
300 DATA 0.624291,0.142924
310 DATA 0.211332,0.221507
320 DATA 0.293786,0.691701
330 DATA 0.839186,0.728260</syntaxhighlight>
=={{header|J}}==
Solution of the simpler (brute-force) problem:
<langsyntaxhighlight lang="j">vecl =: +/"1&.:*: NB. length of each of vectorsvector
dist =: <@:vecl@:({: -"1 }:)\ NB. calculate all distances among vectors
minpair=: ({~ > {.@($ #: I.@,)@:= <./@;)dist NB. find one pair of the closest points
closestpairbf =: (; vecl@:-/)@minpair NB. the pair and their distance</langsyntaxhighlight>
Examples of use:
<langsyntaxhighlight lang="j"> ]pts=:10 2 ?@$ 0
0.654682 0.925557
0.409382 0.619391
Line 1,404 ⟶ 1,851:
|0.891663 0.888594|0.0779104|
|0.925092 0.81822| |
+-----------------+---------+</langsyntaxhighlight>
The program also works for higher dimensional vectors:
<langsyntaxhighlight lang="j"> ]pts=:10 4 ?@$ 0
0.559164 0.482993 0.876 0.429769
0.217911 0.729463 0.97227 0.132175
Line 1,422 ⟶ 1,869:
|0.217911 0.729463 0.97227 0.132175|0.708555|
|0.316673 0.797519 0.745821 0.0598321| |
+------------------------------------+--------+</langsyntaxhighlight>
 
=={{header|Java}}==
 
Line 1,429 ⟶ 1,875:
 
'''Code:'''
<langsyntaxhighlight Javalang="java">import java.util.*;
 
public class ClosestPair
Line 1,614 ⟶ 2,060:
System.out.println("MISMATCH");
}
}</langsyntaxhighlight>
 
{{out}}
'''Example output:'''
<pre>java ClosestPair 10000
Generated 10000 random points
Brute force (1594 ms): (0.9246533850872104, 0.098709007587097)-(0.924591196030625, 0.09862206991823985) : 1.0689077146927108E-4
Divide and conquer (250 ms): (0.924591196030625, 0.09862206991823985)-(0.9246533850872104, 0.098709007587097) : 1.0689077146927108E-4</pre>
 
=={{header|JavaScript}}==
Using bruteforce algorithm, the ''bruteforceClosestPair'' method below expects an array of objects with x- and y-members set to numbers, and returns an object containing the members ''distance'' and ''points''.
 
<langsyntaxhighlight lang="javascript">function distance(p1, p2) {
var dx = Math.abs(p1.x - p2.x);
var dy = Math.abs(p1.y - p2.y);
Line 1,651 ⟶ 2,096:
};
}
}</langsyntaxhighlight>
 
divide-and-conquer method:
<syntaxhighlight lang="javascript">
 
var Point = function(x, y) {
this.x = x;
this.y = y;
};
Point.prototype.getX = function() {
return this.x;
};
Point.prototype.getY = function() {
return this.y;
};
 
var mergeSort = function mergeSort(points, comp) {
if(points.length < 2) return points;
 
 
var n = points.length,
i = 0,
j = 0,
leftN = Math.floor(n / 2),
rightN = leftN;
 
 
var leftPart = mergeSort( points.slice(0, leftN), comp),
rightPart = mergeSort( points.slice(rightN), comp );
 
var sortedPart = [];
 
while((i < leftPart.length) && (j < rightPart.length)) {
if(comp(leftPart[i], rightPart[j]) < 0) {
sortedPart.push(leftPart[i]);
i += 1;
}
else {
sortedPart.push(rightPart[j]);
j += 1;
}
}
while(i < leftPart.length) {
sortedPart.push(leftPart[i]);
i += 1;
}
while(j < rightPart.length) {
sortedPart.push(rightPart[j]);
j += 1;
}
return sortedPart;
};
 
var closestPair = function _closestPair(Px, Py) {
if(Px.length < 2) return { distance: Infinity, pair: [ new Point(0, 0), new Point(0, 0) ] };
if(Px.length < 3) {
//find euclid distance
var d = Math.sqrt( Math.pow(Math.abs(Px[1].x - Px[0].x), 2) + Math.pow(Math.abs(Px[1].y - Px[0].y), 2) );
return {
distance: d,
pair: [ Px[0], Px[1] ]
};
}
 
var n = Px.length,
leftN = Math.floor(n / 2),
rightN = leftN;
 
var Xl = Px.slice(0, leftN),
Xr = Px.slice(rightN),
Xm = Xl[leftN - 1],
Yl = [],
Yr = [];
//separate Py
for(var i = 0; i < Py.length; i += 1) {
if(Py[i].x <= Xm.x)
Yl.push(Py[i]);
else
Yr.push(Py[i]);
}
 
var dLeft = _closestPair(Xl, Yl),
dRight = _closestPair(Xr, Yr);
 
var minDelta = dLeft.distance,
closestPair = dLeft.pair;
if(dLeft.distance > dRight.distance) {
minDelta = dRight.distance;
closestPair = dRight.pair;
}
 
 
//filter points around Xm within delta (minDelta)
var closeY = [];
for(i = 0; i < Py.length; i += 1) {
if(Math.abs(Py[i].x - Xm.x) < minDelta) closeY.push(Py[i]);
}
//find min within delta. 8 steps max
for(i = 0; i < closeY.length; i += 1) {
for(var j = i + 1; j < Math.min( (i + 8), closeY.length ); j += 1) {
var d = Math.sqrt( Math.pow(Math.abs(closeY[j].x - closeY[i].x), 2) + Math.pow(Math.abs(closeY[j].y - closeY[i].y), 2) );
if(d < minDelta) {
minDelta = d;
closestPair = [ closeY[i], closeY[j] ]
}
}
}
 
return {
distance: minDelta,
pair: closestPair
};
};
 
 
var points = [
new Point(0.748501, 4.09624),
new Point(3.00302, 5.26164),
new Point(3.61878, 9.52232),
new Point(7.46911, 4.71611),
new Point(5.7819, 2.69367),
new Point(2.34709, 8.74782),
new Point(2.87169, 5.97774),
new Point(6.33101, 0.463131),
new Point(7.46489, 4.6268),
new Point(1.45428, 0.087596)
];
 
var sortX = function (a, b) { return (a.x < b.x) ? -1 : ((a.x > b.x) ? 1 : 0); }
var sortY = function (a, b) { return (a.y < b.y) ? -1 : ((a.y > b.y) ? 1 : 0); }
 
var Px = mergeSort(points, sortX);
var Py = mergeSort(points, sortY);
 
console.log(JSON.stringify(closestPair(Px, Py))) // {"distance":0.0894096443343775,"pair":[{"x":7.46489,"y":4.6268},{"x":7.46911,"y":4.71611}]}
 
var points2 = [new Point(37100, 13118), new Point(37134, 1963), new Point(37181, 2008), new Point(37276, 21611), new Point(37307, 9320)];
 
Px = mergeSort(points2, sortX);
Py = mergeSort(points2, sortY);
 
console.log(JSON.stringify(closestPair(Px, Py))); // {"distance":65.06919393998976,"pair":[{"x":37134,"y":1963},{"x":37181,"y":2008}]}
 
</syntaxhighlight>
=={{header|jq}}==
{{works with|jq|1.4}}
The solution presented here is essentially a direct translation into jq of the pseudo-code presented in the task description,
but "closest_pair" is added so that any list of [x,y] points can be presented, and extra lines are added to ensure that xL and yL have the same lengths.
 
'''Infrastructure''':
<syntaxhighlight lang="jq"># This definition of "until" is included in recent versions (> 1.4) of jq
# Emit the first input that satisfied the condition
def until(cond; next):
def _until:
if cond then . else (next|_until) end;
_until;
 
# Euclidean 2d distance
def dist(x;y):
[x[0] - y[0], x[1] - y[1]] | map(.*.) | add | sqrt;</syntaxhighlight>
<syntaxhighlight lang="jq">
# P is an array of points, [x,y].
# Emit the solution in the form [dist, [P1, P2]]
def bruteForceClosestPair(P):
(P|length) as $length
| if $length < 2 then null
else
reduce range(0; $length-1) as $i
( null;
reduce range($i+1; $length) as $j
(.;
dist(P[$i]; P[$j]) as $d
| if . == null or $d < .[0] then [$d, [ P[$i], P[$j] ] ] else . end ) )
end;
 
def closest_pair:
 
def abs: if . < 0 then -. else . end;
def ceil: floor as $floor
| if . == $floor then $floor else $floor + 1 end;
 
# xP is an array [P(1), .. P(N)] sorted by x coordinate, and
# yP is an array [P(1), .. P(N)] sorted by y coordinate (ascending order).
# if N <= 3 then return closest points of xP using the brute-force algorithm.
def closestPair(xP; yP):
if xP|length <= 3 then bruteForceClosestPair(xP)
else
((xP|length)/2|ceil) as $N
| xP[0:$N] as $xL
| xP[$N:] as $xR
| xP[$N-1][0] as $xm # middle
| (yP | map(select(.[0] <= $xm ))) as $yL0 # might be too long
| (yP | map(select(.[0] > $xm ))) as $yR0 # might be too short
| (if $yL0|length == $N then $yL0 else $yL0[0:$N] end) as $yL
| (if $yL0|length == $N then $yR0 else $yL0[$N:] + $yR0 end) as $yR
| closestPair($xL; $yL) as $pairL # [dL, pairL]
| closestPair($xR; $yR) as $pairR # [dR, pairR]
| (if $pairL[0] < $pairR[0] then $pairL else $pairR end) as $pair # [ dmin, pairMin]
| (yP | map(select( (($xm - .[0])|abs) < $pair[0]))) as $yS
| ($yS | length) as $nS
| $pair[0] as $dmin
| reduce range(0; $nS - 1) as $i
( [0, $pair]; # state: [k, [d, [P1,P2]]]
.[0] = $i + 1
| until( .[0] as $k | $k >= $nS or ($yS[$k][1] - $yS[$i][1]) >= $dmin;
.[0] as $k
| dist($yS[$k]; $yS[$i]) as $d
| if $d < .[1][0]
then [$k+1, [ $d, [$yS[$k], $yS[$i]]]]
else .[0] += 1
end) )
| .[1]
end;
closestPair( sort_by(.[0]); sort_by(.[1])) ;</syntaxhighlight>
'''Example from the Mathematica section''':
<syntaxhighlight lang="jq">def data:
[[0.748501, 4.09624],
[3.00302, 5.26164],
[3.61878, 9.52232],
[7.46911, 4.71611],
[5.7819, 2.69367],
[2.34709, 8.74782],
[2.87169, 5.97774],
[6.33101, 0.463131],
[7.46489, 4.6268],
[1.45428, 0.087596] ];
 
data | closest_pair</syntaxhighlight>
{{Out}}
$jq -M -c -n -f closest_pair.jq
[0.0894096443343775,[[7.46489,4.6268],[7.46911,4.71611]]]
=={{header|Julia}}==
{{works with|Julia|0.6}}
Brute-force algorithm:
<syntaxhighlight lang="julia">function closestpair(P::Vector{Vector{T}}) where T <: Number
N = length(P)
if N < 2 return (Inf, ()) end
mindst = norm(P[1] - P[2])
minpts = (P[1], P[2])
for i in 1:N-1, j in i+1:N
tmpdst = norm(P[i] - P[j])
if tmpdst < mindst
mindst = tmpdst
minpts = (P[i], P[j])
end
end
return mindst, minpts
end
 
closestpair([[0, -0.3], [1., 1.], [1.5, 2], [2, 2], [3, 3]])</syntaxhighlight>
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.2
 
typealias Point = Pair<Double, Double>
 
fun distance(p1: Point, p2: Point) = Math.hypot(p1.first- p2.first, p1.second - p2.second)
 
fun bruteForceClosestPair(p: List<Point>): Pair<Double, Pair<Point, Point>> {
val n = p.size
if (n < 2) throw IllegalArgumentException("Must be at least two points")
var minPoints = p[0] to p[1]
var minDistance = distance(p[0], p[1])
for (i in 0 until n - 1)
for (j in i + 1 until n) {
val dist = distance(p[i], p[j])
if (dist < minDistance) {
minDistance = dist
minPoints = p[i] to p[j]
}
}
return minDistance to Pair(minPoints.first, minPoints.second)
}
 
fun optimizedClosestPair(xP: List<Point>, yP: List<Point>): Pair<Double, Pair<Point, Point>> {
val n = xP.size
if (n <= 3) return bruteForceClosestPair(xP)
val xL = xP.take(n / 2)
val xR = xP.drop(n / 2)
val xm = xP[n / 2 - 1].first
val yL = yP.filter { it.first <= xm }
val yR = yP.filter { it.first > xm }
val (dL, pairL) = optimizedClosestPair(xL, yL)
val (dR, pairR) = optimizedClosestPair(xR, yR)
var dmin = dR
var pairMin = pairR
if (dL < dR) {
dmin = dL
pairMin = pairL
}
val yS = yP.filter { Math.abs(xm - it.first) < dmin }
val nS = yS.size
var closest = dmin
var closestPair = pairMin
for (i in 0 until nS - 1) {
var k = i + 1
while (k < nS && (yS[k].second - yS[i].second < dmin)) {
val dist = distance(yS[k], yS[i])
if (dist < closest) {
closest = dist
closestPair = Pair(yS[k], yS[i])
}
k++
}
}
return closest to closestPair
}
 
 
fun main(args: Array<String>) {
val points = listOf(
listOf(
5.0 to 9.0, 9.0 to 3.0, 2.0 to 0.0, 8.0 to 4.0, 7.0 to 4.0,
9.0 to 10.0, 1.0 to 9.0, 8.0 to 2.0, 0.0 to 10.0, 9.0 to 6.0
),
listOf(
0.654682 to 0.925557, 0.409382 to 0.619391, 0.891663 to 0.888594,
0.716629 to 0.996200, 0.477721 to 0.946355, 0.925092 to 0.818220,
0.624291 to 0.142924, 0.211332 to 0.221507, 0.293786 to 0.691701,
0.839186 to 0.728260
)
)
for (p in points) {
val (dist, pair) = bruteForceClosestPair(p)
println("Closest pair (brute force) is ${pair.first} and ${pair.second}, distance $dist")
val xP = p.sortedBy { it.first }
val yP = p.sortedBy { it.second }
val (dist2, pair2) = optimizedClosestPair(xP, yP)
println("Closest pair (optimized) is ${pair2.first} and ${pair2.second}, distance $dist2\n")
}
}</syntaxhighlight>
 
{{out}}
<pre>
Closest pair (brute force) is (8.0, 4.0) and (7.0, 4.0), distance 1.0
Closest pair (optimized) is (7.0, 4.0) and (8.0, 4.0), distance 1.0
 
Closest pair (brute force) is (0.891663, 0.888594) and (0.925092, 0.81822), distance 0.07791019135517516
Closest pair (optimized) is (0.891663, 0.888594) and (0.925092, 0.81822), distance 0.07791019135517516
</pre>
=={{header|Liberty BASIC}}==
NB array terms can not be READ directly.
<syntaxhighlight lang="lb">
<lang lb>
N =10
 
Line 1,698 ⟶ 2,480:
data 0.839186, 0.72826
 
</syntaxhighlight>
</lang>
Distance =0.77910191e-1 between ( 0.891663, 0.888594) and ( 0.925092, 0.81822)
=={{header|Maple}}==
<syntaxhighlight lang="maple">ClosestPair := module()
 
local
=={{header|Mathematica}}==
ModuleApply := proc(L::list,$)
<lang Mathematica>nearestPair[data_] :=
local Lx, Ly, out;
Ly := sort(L, 'key'=(i->i[2]), 'output'='permutation');
Lx := sort(L, 'key'=(i->i[1]), 'output'='permutation');
out := Recurse(L, Lx, Ly, 1, numelems(L));
return sqrt(out[1]), out[2];
end proc; # ModuleApply
 
local
BruteForce := proc(L, Lx, r1:=1, r2:=numelems(L), $)
local d, p, n, i, j;
d := infinity;
for i from r1 to r2-1 do
for j from i+1 to r2 do
n := dist( L[Lx[i]], L[Lx[j]] );
if n < d then
d := n;
p := [ L[Lx[i]], L[Lx[j]] ];
end if;
end do; # j
end do; # i
return (d, p);
end proc; # BruteForce
 
local dist := (p, q)->(( (p[1]-q[1])^2+(p[2]-q[2])^2 ));
 
local Recurse := proc(L, Lx, Ly, r1, r2)
local m, xm, rDist, rPair, lDist, lPair, minDist, minPair, S, i, j, Lyr, Lyl;
 
if r2-r1 <= 3 then
return BruteForce(L, Lx, r1, r2);
end if;
 
m := ceil((r2-r1)/2)+r1;
xm := (L[Lx[m]][1] + L[Lx[m-1]][1])/2;
 
(Lyr, Lyl) := selectremove( i->L[i][1] < xm, Ly);
 
(rDist, rPair) := thisproc(L, Lx, Lyr, r1, m-1);
(lDist, lPair) := thisproc(L, Lx, Lyl, m, r2);
 
if rDist < lDist then
minDist := rDist;
minPair := rPair;
else
minDist := lDist;
minPair := lPair;
end if;
 
S := [ seq( `if`(abs(xm - L[i][1])^2< minDist, L[i], NULL ), i in Ly ) ];
 
for i from 1 to nops(S)-1 do
for j from i+1 to nops(S) do
if abs( S[i][2] - S[j][2] )^2 >= minDist then
break;
elif dist(S[i], S[j]) < minDist then
minDist := dist(S[i], S[j]);
minPair := [S[i], S[j]];
end if;
end do;
end do;
 
return (minDist, minPair);
 
end proc; #Recurse
 
end module; #ClosestPair</syntaxhighlight>
 
{{out}}<syntaxhighlight lang="maple">
> L := RandomTools:-Generate(list(list(float(range=0..1),2),512)):
> ClosestPair(L);
0.002576770304, [[0.4265584800, 0.7443097852], [0.4240649736, 0.7449595321]]
</syntaxhighlight>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
'''O(''n''<sup>2</sup>)'''
<syntaxhighlight lang="mathematica">nearestPair[data_] :=
Block[{pos, dist = N[Outer[EuclideanDistance, data, data, 1]]},
pos = Position[dist, Min[DeleteCases[Flatten[dist], 0.]]];
data[[pos[[1]]]]]</langsyntaxhighlight>
 
'''O(''n''<sup>2</sup>) output:'''
Output
<presyntaxhighlight lang="mathematica">nearestPair[{{0.748501, 4.09624}, {3.00302, 5.26164}, {3.61878,
9.52232}, {7.46911, 4.71611}, {5.7819, 2.69367}, {2.34709,
8.74782}, {2.87169, 5.97774}, {6.33101, 0.463131}, {7.46489,
4.6268}, {1.45428, 0.087596}}]
 
{{7.46911, 4.71611}, {7.46489, 4.6268}}</presyntaxhighlight>
 
 
''' O(''n''log ''n'') '''
<syntaxhighlight lang="mathematica">closestPair[ptsIn_] :=
Module[{xP, yP,
pts},(*Top level function.Sorts the pts by x and by y and then \
calls closestPairR[]*)pts = N[ptsIn];
xP = Sort[pts, #1[[1]] < #2[[1]] &];
yP = Sort[pts, #1[[2]] < #2[[2]] &];
closestPairR[xP, yP]]
 
closestPairR[xP_, yP_] :=
Module[{n, mid, xL, xR, xm, yL, yR, dL, pairL, dmin, pairMin, yS, nS,
closest, closestP, k,
cDist},(*where xP is P(1).. P(n) sorted by x coordinate,
and yP is P(1).. P(n) sorted by y coordinate (ascending order)*)
n = Length[xP];
If[n <= 3,(*Brute Force*)
Piecewise[{{{\[Infinity], {}},
n < 2}, {{EuclideanDistance[xP[[1]], xP[[2]]], {xP[[1]],
xP[[2]]}},
n == 2}, {Last@
MinimalBy[{{EuclideanDistance[xP[[1]], xP[[2]]], {xP[[1]],
xP[[2]]}}, {EuclideanDistance[xP[[1]], xP[[3]]], {xP[[1]],
xP[[3]]}}, {EuclideanDistance[xP[[3]], xP[[2]]], {xP[[3]],
xP[[2]]}}}, First], n == 3}}], mid = Ceiling[n/2];
xL = xP[[1 ;; mid]];
xR = xP[[mid + 1 ;; n]];
xm = xP[[mid]];
yL = Select[yP, #[[1]] <= xm[[1]] &];
yR = Select[yP, #[[1]] > xm[[1]] &];
{dL, pairL} = closestPairR[xL, yL];
{dmin, pairMin} = closestPairR[xR, yR];
If[dL < dmin, {dmin, pairMin} = {dL, pairL}];
yS = Select[yP, Abs[#[[1]] - xm[[1]]] <= dmin &];
nS = Length[yS];
{closest, closestP} = {dmin, pairMin};
Table[k = i + 1;
While[(k <= nS) && (yS[[k, 2]] - yS[[i, 2]] < dmin),
cDist = EuclideanDistance[yS[[k]], yS[[i]]];
If[cDist <
closest, {closest, closestP} = {cDist, {yS[[k]], yS[[i]]}}];
k = k + 1], {i, 1, nS - 1}];
{closest, closestP}](*end if*)]
 
</syntaxhighlight>
 
''' O(''n''log''n'') output: '''
<syntaxhighlight lang="mathematica">closestPair[{{0.748501, 4.09624}, {3.00302, 5.26164}, {3.61878,
9.52232}, {7.46911, 4.71611}, {5.7819, 2.69367}, {2.34709,
8.74782}, {2.87169, 5.97774}, {6.33101, 0.463131}, {7.46489,
4.6268}, {1.45428, 0.087596}}]
 
{0.0894096, {{7.46489, 4.6268}, {7.46911, 4.71611}}}</syntaxhighlight>
=={{header|MATLAB}}==
 
This solution is an almost direct translation of the above pseudo-code into MATLAB.
<langsyntaxhighlight MATLABlang="matlab">function [closest,closestpair] = closestPair(xP,yP)
 
N = numel(xP);
Line 1,788 ⟶ 2,700:
end %for
end %if (N <= 3)
end %closestPair</langsyntaxhighlight>
 
{{out}}
Sample Output:
<langsyntaxhighlight MATLABlang="matlab">[distance,pair]=closestPair({[0 -.3],[1 1],[1.5 2],[2 2],[3 3]},{[0 -.3],[1 1],[1.5 2],[2 2],[3 3]})
 
distance =
Line 1,800 ⟶ 2,712:
pair =
 
[1x2 double] [1x2 double] %The pair is [1.5 2] and [2 2] which is correct</langsyntaxhighlight>
=={{header|Microsoft Small Basic}}==
<syntaxhighlight lang="smallbasic">' Closest Pair Problem
s="0.654682,0.925557,0.409382,0.619391,0.891663,0.888594,0.716629,0.996200,0.477721,0.946355,0.925092,0.818220,0.624291,0.142924,0.211332,0.221507,0.293786,0.691701,0.839186,0.728260,"
i=0
While s<>""
i=i+1
For j=1 To 2
k=Text.GetIndexOf(s,",")
ss=Text.GetSubText(s,1,k-1)
s=Text.GetSubTextToEnd(s,k+1)
pxy[i][j]=ss
EndFor
EndWhile
n=i
i=1
j=2
dd=Math.Power(pxy[i][1]-pxy[j][1],2)+Math.Power(pxy[i][2]-pxy[j][2],2)
ddmin=dd
ii=i
jj=j
For i=1 To n
For j=1 To n
dd=Math.Power(pxy[i][1]-pxy[j][1],2)+Math.Power(pxy[i][2]-pxy[j][2],2)
If dd>0 Then
If dd<ddmin Then
ddmin=dd
ii=i
jj=j
EndIf
EndIf
EndFor
EndFor
sqrt1=ddmin
sqrt2=ddmin/2
For i=1 To 20
If sqrt1=sqrt2 Then
Goto exitfor
EndIf
sqrt1=sqrt2
sqrt2=(sqrt1+(ddmin/sqrt1))/2
EndFor
exitfor:
TextWindow.WriteLine("the minimum distance "+sqrt2)
TextWindow.WriteLine("is between the points:")
TextWindow.WriteLine(" ["+pxy[ii][1]+","+pxy[ii][2]+"] and")
TextWindow.WriteLine(" ["+pxy[jj][1]+","+pxy[jj][2]+"]")</syntaxhighlight>
{{out}}
<pre>
the minimum distance 0,0779101913551750943201426138
is between the points:
[0.891663,0.888594] and
[0.925092,0.818220]
</pre>
=={{header|Nim}}==
<syntaxhighlight lang="nim">import math, algorithm
 
type
 
Point = tuple[x, y: float]
Pair = tuple[p1, p2: Point]
Result = tuple[minDist: float; minPoints: Pair]
 
#---------------------------------------------------------------------------------------------------
 
template sqr(x: float): float = x * x
 
#---------------------------------------------------------------------------------------------------
 
func dist(point1, point2: Point): float =
sqrt(sqr(point2.x - point1.x) + sqr(point2.y - point1.y))
 
#---------------------------------------------------------------------------------------------------
 
func bruteForceClosestPair*(points: openArray[Point]): Result =
 
doAssert(points.len >= 2, "At least two points required.")
 
result.minDist = Inf
for i in 0..<points.high:
for j in (i + 1)..points.high:
let d = dist(points[i], points[j])
if d < result.minDist:
result = (d, (points[i], points[j]))
 
#---------------------------------------------------------------------------------------------------
 
func closestPair(xP, yP: openArray[Point]): Result =
## Recursive function which takes two open arrays as arguments: the first
## sorted by increasing values of x, the second sorted by increasing values of y.
 
if xP.len <= 3:
return xP.bruteForceClosestPair()
 
let m = xP.high div 2
let xL = xP[0..m]
let xR = xP[(m + 1)..^1]
 
let xm = xP[m].x
var yL, yR: seq[Point]
for p in yP:
if p.x <= xm: yL.add(p)
else: yR.add(p)
 
let (dL, pairL) = closestPair(xL, yL)
let (dR, pairR) = closestPair(xR, yR)
let (dMin, pairMin) = if dL < dR: (dL, pairL) else: (dR, pairR)
 
var yS: seq[Point]
for p in yP:
if abs(xm - p.x) < dmin: yS.add(p)
 
result = (dMin, pairMin)
for i in 0..<yS.high:
var k = i + 1
while k < yS.len and ys[k].y - yS[i].y < dMin:
let d = dist(yS[i], yS[k])
if d < result.minDist:
result = (d, (yS[i], yS[k]))
inc k
 
#---------------------------------------------------------------------------------------------------
 
func closestPair*(points: openArray[Point]): Result =
 
let xP = points.sortedByIt(it.x)
let yP = points.sortedByIt(it.y)
doAssert(points.len >= 2, "At least two points required.")
 
result = closestPair(xP, yP)
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
import random, times, strformat
 
randomize()
 
const N = 50_000
const Max = 10_000.0
var points: array[N, Point]
for pt in points.mitems: pt = (rand(Max), rand(Max))
 
echo "Sample contains ", N, " random points."
echo ""
 
let t0 = getTime()
echo "Brute force algorithm:"
echo points.bruteForceClosestPair()
let t1 = getTime()
echo "Optimized algorithm:"
echo points.closestPair()
let t2 = getTime()
 
echo ""
echo fmt"Execution time for brute force algorithm: {(t1 - t0).inMilliseconds:>4} ms"
echo fmt"Execution time for optimized algorithm: {(t2 - t1).inMilliseconds:>4} ms"</syntaxhighlight>
 
{{out}}
<pre>Sample contains 50000 random points.
 
Brute force algorithm:
(minDist: 0.1177082437919083, minPoints: (p1: (x: 3686.601318778875, y: 2187.261792916939), p2: (x: 3686.483703931143, y: 2187.257104820359)))
Optimized algorithm:
(minDist: 0.1177082437919083, minPoints: (p1: (x: 3686.483703931143, y: 2187.257104820359), p2: (x: 3686.601318778875, y: 2187.261792916939)))
 
Execution time for brute force algorithm: 2656 ms
Execution time for optimized algorithm: 63 ms</pre>
=={{header|Objective-C}}==
See [[Closest-pair problem/Objective-C]]
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">
 
type point = { x : float; y : float }
Line 1,932 ⟶ 3,008:
Printf.printf "(%f, %f) (%f, %f) Dist %f\n" a.x a.y b.x b.y (dist c)
 
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
Translation of pseudocode:
<langsyntaxhighlight lang="oz">declare
fun {Distance X1#Y1 X2#Y2}
{Sqrt {Pow X2-X1 2.0} + {Pow Y2-Y1 2.0}}
Line 2,034 ⟶ 3,109:
{ForAll Points RandomPoint}
{Show Points}
{Show {ClosestPair Points}}</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
Naive quadratic solution.
<langsyntaxhighlight lang="parigp">closestPair(v)={
my(r=norml2(v[1]-v[2]),at=[1,2]);
for(a=1,#v-1,
Line 2,049 ⟶ 3,123:
);
[v[at[1]],v[at[2]]]
};</langsyntaxhighlight>
=={{header|Pascal}}==
Brute force only calc square of distance, like AWK etc...
As fast as [[Closest-pair_problem#Faster_Brute-force_Version | D ]] .
<syntaxhighlight lang="pascal">program closestPoints;
{$IFDEF FPC}
{$MODE Delphi}
{$ENDIF}
const
PointCnt = 10000;//31623;
type
TdblPoint = Record
ptX,
ptY : double;
end;
tPtLst = array of TdblPoint;
 
tMinDIstIdx = record
md1,
md2 : NativeInt;
end;
 
function ClosPointBruteForce(var ptl :tPtLst):tMinDIstIdx;
Var
i,j,k : NativeInt;
mindst2,dst2: double; //square of distance, no need to sqrt
p0,p1 : ^TdblPoint; //using pointer, since calc of ptl[?] takes much time
Begin
i := Low(ptl);
j := High(ptl);
result.md1 := i;result.md2 := j;
mindst2 := sqr(ptl[i].ptX-ptl[j].ptX)+sqr(ptl[i].ptY-ptl[j].ptY);
repeat
p0 := @ptl[i];
p1 := p0; inc(p1);
For k := i+1 to j do
Begin
dst2:= sqr(p0^.ptX-p1^.ptX)+sqr(p0^.ptY-p1^.ptY);
IF mindst2 > dst2 then
Begin
mindst2 := dst2;
result.md1 := i;
result.md2 := k;
end;
inc(p1);
end;
inc(i);
until i = j;
end;
 
var
PointLst :tPtLst;
cloPt : tMinDIstIdx;
i : NativeInt;
Begin
randomize;
setlength(PointLst,PointCnt);
For i := 0 to PointCnt-1 do
with PointLst[i] do
Begin
ptX := random;
ptY := random;
end;
cloPt:= ClosPointBruteForce(PointLst) ;
i := cloPt.md1;
Writeln('P[',i:4,']= x: ',PointLst[i].ptX:0:8,
' y: ',PointLst[i].ptY:0:8);
i := cloPt.md2;
Writeln('P[',i:4,']= x: ',PointLst[i].ptX:0:8,
' y: ',PointLst[i].ptY:0:8);
end.</syntaxhighlight>{{Out}}<pre>PointCnt = 10000
//without randomize always same results
//32-Bit
P[ 324]= x: 0.26211815 y: 0.45851455
P[3391]= x: 0.26217852 y: 0.45849116
real 0m0.114s //fpc 3.1.1 32 Bit -O4 -MDelphi..cpu i4330 3.5 Ghz
//64-Bit doubles the speed comp switch -O2 ..-O4 same timings
P[ 324]= x: 0.26211815 y: 0.45851455
P[3391]= x: 0.26217852 y: 0.45849116
real 0m0.059s //fpc 3.1.1 64 Bit -O4 -MDelphi..cpu i4330 3.5 Ghz
 
//with randomize
P[ 47]= x: 0.12408823 y: 0.04501338
P[9429]= x: 0.12399629 y: 0.04496700
//32-Bit
PointCnt = { 10000*sqrt(10) } 31623;-> real 0m1.112s 10x times runtime</pre>
=={{header|Perl}}==
The divide & conquer technique is about 100x faster than the brute-force algorithm.
<lang perl>#! /usr/bin/perl
<syntaxhighlight lang="perl">use strict;
use warnings;
use POSIX qw(ceil);
 
sub dist {
my ($a, $b) = @_;
{
return my sqrt(( $a,->[0] - $b->[0])**2 = @_;+
return sqrt( ($a->[01] - $b->[01])**2 +)
($a->[1] - $b->[1])**2 );
}
 
sub closest_pair_simple {
my @points = @{ shift @_ };
{
my ($a, $b, $d) = ( $points[0], $points[1], dist($points[0], $points[1]) );
my $ra = shift;
mywhile( @arrpoints =) @$ra;{
my $infp = 1e600pop @points;
return $inf if scalar for my $l (@arrpoints) < 2;{
my ( $a, $b, $d ) = ( my $arr[0],t $arr[1],= dist($arr[0]p, $arr[1])l);
($a, $b, $d) = ($p, $l, $t) if $t < $d;
while( @arr ) {
my $p = pop @arr; }
foreach my $l (@arr) {
my $t = dist($p, $l);
($a, $b, $d) = ($p, $l, $t) if $t < $d;
}
}
return ($a, $b, $d);
}
 
sub closest_pair {
my @r = @{ shift @_ };
{
closest_pair_real( [sort { $a->[0] <=> $b->[0] } @r], [sort { $a->[1] <=> $b->[1] } @r] )
my $r = shift;
my @ax = sort { $a->[0] <=> $b->[0] } @$r;
my @ay = sort { $a->[1] <=> $b->[1] } @$r;
return closest_pair_real(\@ax, \@ay);
}
 
sub closest_pair_real {
{
my ($rx, $ry) = @_;
myreturn @xPclosest_pair_simple($rx) =if scalar(@$rx) <= 3;
my @yP = @$ry;
my $N = @xP;
return closest_pair_simple($rx) if scalar(@xP) <= 3;
 
my(@yR, $inf@yL, = 1e600@yS);
my $N = @$rx;
my $midx = ceil($N/2)-1;
my @PL = @$rx[ 0 .. $midx];
 
my @PLPR = @xP$rx[0$midx+1 .. $midxN-1];
my @PR$xm = @xP$$rx[$midx+1 .. $N]-1>[0];
$_->[0] <= $xm ? push @yR, $_ : push @yL, $_ for @$ry;
 
my $xm = ${$xP[$midx]}[0];
 
my @yR = ();
my @yL = ();
foreach my $p (@yP) {
if ( ${$p}[0] <= $xm ) {
push @yR, $p;
} else {
push @yL, $p;
}
}
 
my ($al, $bl, $dL) = closest_pair_real(\@PL, \@yR);
my ($ar, $br, $dR) = closest_pair_real(\@PR, \@yL);
my ($w1, $w2, $closest) = $dR > $dL ? ($al, $bl, $dL) : ($ar, $br, $dR);
abs($xm - $_->[0]) < $closest and push @yS, $_ for @$ry;
 
for my ($m1, $m2, $dmin) =i ($al,0 $bl,.. $dL@yS-1); {
($m1, $m2, $dmin) = ($ar,my $br,k $dR) if= $dRi <+ $dL1;
while ( $k <= $#yS and ($yS[$k]->[1] - $yS[$i]->[1]) < $closest ) {
 
my @yS$d = dist($yS[$k], $yS[$i]);
($w1, $w2, $closest) = ($yS[$k], $yS[$i], $d) if $d < $closest;
foreach my $p (@yP) {
push @yS, $p if abs($xm - ${$p}[0]) < $dmink++;
}
 
if ( @yS ) {
my ( $w1, $w2, $closest ) = ($m1, $m2, $dmin);
foreach my $i (0 .. ($#yS - 1)) {
 
my $k = $i + 1;
while ( ($k <= $#yS) && ( (${$yS[$k]}[1] - ${$yS[$i]}[1]) < $dmin) ) {
my $d = dist($yS[$k], $yS[$i]);
($w1, $w2, $closest) = ($yS[$k], $yS[$i], $d) if $d < $closest;
$k++;
}
 
}
return ($w1, $w2, $closest);
 
} else {
return ($m1, $m2, $dmin);
}
}
 
 
 
my @points = ();
my $N = 5000;
 
foreach my $i (1..$N) {
push @points, [rand(20)-10.0, rand(20)-10.0];
}
 
 
my ($a, $b, $d) = closest_pair_simple(\@points);
print "$d\n";
 
my ($a1, $b1, $d1) = closest_pair(\@points);
#print "$d1\n";</lang>
 
<tt>Time</tt> for the brute-force algorithm gave 40.63user 0.12system 0:41.06elapsed, while the divide&amp;conqueer algorithm gave 0.37user 0.00system 0:00.38elapsed with 5000 points.
 
=={{header|Perl 6}}==
 
{{trans|Perl 5}}
 
We avoid taking square roots in the slow method because the squares are just as comparable.
(This doesn't always work in the fast method because of distance assumptions in the algorithm.)
<lang perl6>sub MAIN ($N = 5000) {
my @points = (^$N).map: { [rand * 20 - 10, rand * 20 - 10] }
 
my ($af, $bf, $df) = closest_pair(@points);
say "fast $df at [$af], [$bf]";
 
my ($as, $bs, $ds) = closest_pair_simple(@points);
say "slow $ds at [$as], [$bs]";
}
 
sub dist-squared($a,$b) {
($a[0] - $b[0]) ** 2 +
($a[1] - $b[1]) ** 2;
}
 
sub closest_pair_simple(@arr is copy) {
return Inf if @arr < 2;
my ($a, $b, $d) = @arr[0,1], dist-squared(|@arr[0,1]);
while @arr {
my $p = pop @arr;
for @arr -> $l {
my $t = dist-squared($p, $l);
($a, $b, $d) = $p, $l, $t if $t < $d;
}
}
return $aw1, $bw2, sqrt $d;closest
}
sub closest_pair(@r) {
my @ax = @r.sort: { .[0] }
my @ay = @r.sort: { .[1] }
return closest_pair_real(@ax, @ay);
}
sub closest_pair_real(@rx, @ry) {
return closest_pair_simple(@rx) if @rx <= 3;
 
my @xP = @rx;
my @yP = @ry;
my $N = @xP;
my $midx = ceiling($N/2)-1;
my @PL = @xP[0 .. $midx];
my @PR = @xP[$midx+1 ..^ $N];
my $xm = @xP[$midx][0];
my @yR;
my @yL;
push ($_[0] <= $xm ?? @yR !! @yL), $_ for @yP;
my ($al, $bl, $dL) = closest_pair_real(@PL, @yR);
my ($ar, $br, $dR) = closest_pair_real(@PR, @yL);
my ($m1, $m2, $dmin) = $dR < $dL
?? ($ar, $br, $dR)
!! ($al, $bl, $dL);
my @yS = @yP.grep: { abs($xm - .[0]) < $dmin }
if @yS {
my ($w1, $w2, $closest) = $m1, $m2, $dmin;
for 0 ..^ @yS.end -> $i {
for $i+1 ..^ @yS -> $k {
last unless @yS[$k][1] - @yS[$i][1] < $dmin;
my $d = sqrt dist-squared(@yS[$k], @yS[$i]);
($w1, $w2, $closest) = @yS[$k], @yS[$i], $d if $d < $closest;
}
}
return $w1, $w2, $closest;
} else {
return $m1, $m2, $dmin;
}
}</lang>
 
my @points;
push @points, [rand(20)-10, rand(20)-10] for 1..5000;
printf "%.8f between (%.5f, %.5f), (%.5f, %.5f)\n", $_->[2], @{$$_[0]}, @{$$_[1]}
for [closest_pair_simple(\@points)], [closest_pair(\@points)];</syntaxhighlight>
{{out}}
<pre>0.00259322 between (-1.95541, -4.29695), (-1.95351, -4.29871)
0.00259322 between (-1.95541, -4.29695), (-1.95351, -4.29871)</pre>
=={{header|Phix}}==
Brute force and divide and conquer (translated from pseudocode) approaches compared
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">bruteForceClosestPair</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">mind</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dx</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">dy</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dy</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">minp</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">x2</span>
<span style="color: #000000;">dx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dx</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dx</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">dx</span><span style="color: #0000FF;"><</span><span style="color: #000000;">mind</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">dy</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">y2</span>
<span style="color: #000000;">dx</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">dy</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dy</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">dx</span><span style="color: #0000FF;"><</span><span style="color: #000000;">mind</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">mind</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dx</span>
<span style="color: #000000;">minp</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mind</span><span style="color: #0000FF;">),</span><span style="color: #000000;">minp</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">testset</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_rnd</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">({</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">},</span><span style="color: #000000;">10000</span><span style="color: #0000FF;">))</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">bruteForceClosestPair</span><span style="color: #0000FF;">(</span><span style="color: #000000;">testset</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- (Sorting the final point pair makes brute/dc more likely to tally. Note however
-- when &gt;1 equidistant pairs exist, brute and dc may well return different pairs;
-- it is only a problem if they decide to return different minimum distances.)</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">}}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Closest pair: {%f,%f} {%f,%f}, distance=%f (%3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">X</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Y</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">xP</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">testset</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">byY</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">compare</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">],</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">yP</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">routine_id</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"byY"</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">testset</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">distsq</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p2</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p1</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p2</span>
<span style="color: #000000;">x1</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">x2</span>
<span style="color: #000000;">y1</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">y2</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">x1</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">y1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">closestPair</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">xP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">yP</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- where xP is P(1) .. P(N) sorted by x coordinate, and
-- yP is P(1) .. P(N) sorted by y coordinate (ascending order)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">N</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xP</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">midN</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">N</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">assert</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yP</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">N</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">N</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">3</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">bruteForceClosestPair</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xP</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">xL</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">midN</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">xR</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">midN</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">N</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">yL</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span>
<span style="color: #000000;">yR</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">xm</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">midN</span><span style="color: #0000FF;">][</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">N</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">yP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]<=</span><span style="color: #000000;">xm</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">yL</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yL</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">else</span>
<span style="color: #000000;">yR</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yR</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">dL</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">pairL</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">closestPair</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">yL</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">dR</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">pairR</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">closestPair</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xR</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">yR</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">dmin</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">pairMin</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">({</span><span style="color: #000000;">dL</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pairL</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">dR</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pairR</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">yS</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yP</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xm</span><span style="color: #0000FF;">-</span><span style="color: #000000;">yP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">X</span><span style="color: #0000FF;">])<</span><span style="color: #000000;">dmin</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">yS</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yS</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yP</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nS</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yS</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">closest</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">cPair</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">dmin</span><span style="color: #0000FF;">*</span><span style="color: #000000;">dmin</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pairMin</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">nS</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">+</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">k</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">nS</span> <span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">yS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">][</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">yS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">])<</span><span style="color: #000000;">dmin</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">distsq</span><span style="color: #0000FF;">(</span><span style="color: #000000;">yS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span><span style="color: #000000;">yS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">d</span><span style="color: #0000FF;"><</span><span style="color: #000000;">closest</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">closest</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cPair</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">yS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">yS</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]}}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #7060A8;">sqrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">closest</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">cPair</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #000000;">points</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">closestPair</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xP</span><span style="color: #0000FF;">,</span><span style="color: #000000;">yP</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">{{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">},{</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">}}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">points</span><span style="color: #0000FF;">))</span> <span style="color: #000080;font-style:italic;">-- (see note above)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Closest pair: {%f,%f} {%f,%f}, distance=%f (%3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">d</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Closest pair: {0.0328051,0.0966250} {0.0328850,0.0966250}, distance=0.000120143 (2.37s)
Closest pair: {0.0328051,0.0966250} {0.0328850,0.0966250}, distance=0.000120143 (0.14s)
</pre>
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de closestPairBF (Lst)
(let Min T
(use (Pt1 Pt2)
Line 2,260 ⟶ 3,394:
Min )
(setq Min N Pt1 P Pt2 Q) ) ) )
(list Pt1 Pt2 (sqrt Min)) ) ) )</langsyntaxhighlight>
Test:
<pre>: (scl 6)
Line 2,278 ⟶ 3,412:
(0.839186 . 0.728260) ) )
-> ((891663 . 888594) (925092 . 818220) 77910)</pre>
 
=={{header|PL/I}}==
<syntaxhighlight lang="text">
/* Closest Pair Problem */
closest: procedure options (main);
Line 2,313 ⟶ 3,446:
end;
end closest;
</syntaxhighlight>
</lang>
=={{header|Prolog}}==
'''Brute force version, works with SWI-Prolog, tested on version 7.2.3.
<syntaxhighlight lang="prolog">
% main predicate, find and print closest point
do_find_closest_points(Points) :-
points_closest(Points, points(point(X1,Y1),point(X2,Y2),Dist)),
format('Point 1 : (~p, ~p)~n', [X1,Y1]),
format('Point 1 : (~p, ~p)~n', [X2,Y2]),
format('Distance: ~p~n', [Dist]).
 
% Find the distance between two points
distance(point(X1,Y1), point(X2,Y2), points(point(X1,Y1),point(X2,Y2),Dist)) :-
Dx is X2 - X1,
Dy is Y2 - Y1,
Dist is sqrt(Dx * Dx + Dy * Dy).
 
% find the closest point that relatest to another point
point_closest(Points, Point, Closest) :-
select(Point, Points, Remaining),
maplist(distance(Point), Remaining, PointList),
foldl(closest, PointList, 0, Closest).
 
% find the closest point/dist pair for all points
points_closest(Points, Closest) :-
maplist(point_closest(Points), Points, ClosestPerPoint),
foldl(closest, ClosestPerPoint, 0, Closest).
 
% used by foldl to get the lowest point/distance combination
closest(points(P1,P2,Dist), 0, points(P1,P2,Dist)).
closest(points(_,_,Dist), points(P1,P2,Dist2), points(P1,P2,Dist2)) :-
Dist2 < Dist.
closest(points(P1,P2,Dist), points(_,_,Dist2), points(P1,P2,Dist)) :-
Dist =< Dist2.
</syntaxhighlight>
To test, pass in a list of points.
<syntaxhighlight lang="prolog">do_find_closest_points([
point(0.654682, 0.925557),
point(0.409382, 0.619391),
point(0.891663, 0.888594),
point(0.716629, 0.996200),
point(0.477721, 0.946355),
point(0.925092, 0.818220),
point(0.624291, 0.142924),
point(0.211332, 0.221507),
point(0.293786, 0.691701),
point(0.839186, 0.728260)
]).
</syntaxhighlight>
{{out}}
<pre>
Point 1 : (0.925092, 0.81822)
Point 1 : (0.891663, 0.888594)
Distance: 0.07791019135517516
true ;
false.
</pre>
=={{header|PureBasic}}==
'''Brute force version
<langsyntaxhighlight PureBasiclang="purebasic">Procedure.d bruteForceClosestPair(Array P.coordinate(1))
Protected N=ArraySize(P()), i, j
Protected mindistance.f=Infinity(), t.d
Line 2,336 ⟶ 3,524:
ProcedureReturn mindistance
EndProcedure
</syntaxhighlight>
</lang>
 
Implementation can be as
<langsyntaxhighlight PureBasiclang="purebasic">Structure coordinate
x.d
y.d
Line 2,367 ⟶ 3,555:
Data.d 0.716629, 0.996200, 0.477721, 0.946355, 0.925092, 0.818220
Data.d 0.624291, 0.142924, 0.211332, 0.221507, 0.293786, 0.691701, 0.839186, 0.72826
EndDataSection</langsyntaxhighlight>
{{out}}
Output
<pre>Mindistance= 0.077910
Point 1= 0.891663: 0.888594
Line 2,374 ⟶ 3,562:
 
Press ENTER to quit</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">"""
Compute nearest pair of points using two algorithms
Line 2,462 ⟶ 3,649:
times()
times()
times()</langsyntaxhighlight>
 
Sample output{{out}} followed by timing comparisons<br>
(Note how the two algorithms agree on the minimum distance, but may return a different pair of points if more than one pair of points share that minimum separation):
<div style="height:30ex;overflow:scroll"><pre>[(5+9j), (9+3j), (2+0j), (8+4j), (7+4j), (9+10j), (1+9j), (8+2j), 10j, (9+6j)]
Line 2,518 ⟶ 3,705:
Time for closestPair 0.119326618327
>>> </pre></div>
 
=={{header|R}}==
{{works with|R|2.8.1+}}
Brute force solution as per wikipedia pseudo-code
<langsyntaxhighlight Rlang="r">closest_pair_brute <-function(x,y,plotxy=F) {
xy = cbind(x,y)
cp = bruteforce(xy)
Line 2,551 ⟶ 3,737:
else bruteforce(pmatrix,n+1,pd)
}
}</langsyntaxhighlight>
 
Quicker brute force solution for R that makes use of the apply function native to R for dealing with matrices. It expects x and y to take the form of separate vectors.
<langsyntaxhighlight Rlang="r">closestPair<-function(x,y)
{
distancev <- function(pointsv)
Line 2,573 ⟶ 3,759:
"\n\tDistance: ",minrow[3],"\n",sep="")
c(distance=minrow[3],x1.x=x[minrow[1]],y1.y=y[minrow[1]],x2.x=x[minrow[2]],y2.y=y[minrow[2]])
}</langsyntaxhighlight>
 
 
This is the quickest version, that makes use of the 'dist' function of R. It takes a two-column object of x,y-values as input, or creates such an object from seperate x and y-vectors.
 
<langsyntaxhighlight Rlang="r">closest.pairs <- function(x, y=NULL, ...){
# takes two-column object(x,y-values), or creates such an object from x and y values
if(!is.null(y)) x <- cbind(x, y)
Line 2,595 ⟶ 3,781:
x2=x[point.pair[2],1],y2=x[point.pair[2],2],
distance=min.dist)
}</langsyntaxhighlight>
 
Example<langsyntaxhighlight Rlang="r">x = (sample(-1000.00:1000.00,100))
y = (sample(-1000.00:1000.00,length(x)))
cp = closest.pairs(x,y)
Line 2,634 ⟶ 3,820:
0.17 0.00 0.19
 
</syntaxhighlight>
</lang>
 
Using dist function for brute force, but divide and conquer (as per pseudocode) for speed:
<langsyntaxhighlight Rlang="r">closest.pairs.bruteforce <- function(x, y=NULL)
{
if (!is.null(y))
Line 2,725 ⟶ 3,911:
print(closest.pairs.bruteforce(x,y))
cat(sprintf("That took %.2f seconds.\n",proc.time()[3] - tstart))
</syntaxhighlight>
</lang>
{{out}}
Sample output
<pre>
How many points?
Line 2,759 ⟶ 3,945:
That took 6.38 seconds.
</pre>
 
=={{header|Racket}}==
The brute force solution using complex numbers
to represent pairs.
<langsyntaxhighlight lang="racket">
#lang racket
(define (dist z0 z1) (magnitude (- z1 z0)))
Line 2,779 ⟶ 3,964:
(displayln (~a "Closest points: " result))
(displayln (~a "Distance: " (dist* result)))
</syntaxhighlight>
</lang>
 
Output:
The divide and conquer algorithm using a struct to represent points
<lang racket>
<syntaxhighlight lang="racket">
#lang racket
(struct point (x y) #:transparent)
 
(define (closest-pair ps)
(check-type ps)
(cond [(vector? ps) (if (> (vector-length ps) 1)
(closest-pair/sorted (vector-sort ps left?)
(vector-sort ps below?))
(error 'closest-pair "2 or more points are needed" ps))]
[(sequence? ps) (closest-pair (for/vector ([x (in-sequences ps)]) x))]
[else (error 'closest-pair "closest pair only supports sequence types (excluding hash)")]))
 
;; accept any sequence type except hash
;; any other exclusions needed?
(define (check-type ps)
(cond [(hash? ps) (error 'closest-pair "Hash tables are not supported")]
[(sequence? ps) #t]
[else (error 'closest-pair "Only sequence types are supported")]))
 
;; vector -> vector -> list
(define (closest-pair/sorted Px Py)
(define L (vector-length Px))
(cond [(= L 2) (vector->list Px)]
[(= L 3) (apply min-pair (combinations (vector->list Px) 2))]
[else (let*-values ([(Qx Rx) (vector-split-at Px (floor (/ L 2)))]
; Rx-min is the left most point in Rx
[(Rx-min) (vector-ref Rx 0)]
; instead of sorting Qx, Rx by y
; - Qy are members of Py to left of Rx-min
; - Ry are the remaining members of Py
[(Qy Ry) (vector-partition Py (curryr left? Rx-min))]
[(pair1) (closest-pair/sorted Qx Qy)]
[(pair2) (closest-pair/sorted Rx Ry)]
[(delta) (min (distance^2 pair1) (distance^2 pair2))]
[(pair3) (closest-split-pair Px Py delta)])
; pair3 is null when there are no split pairs closer than delta
(min-pair pair1 pair2 pair3))]))
 
(define (closest-split-pair Px Py delta)
(define Lp (vector-length Px))
(define x-mid (point-x (vector-ref Px (floor (/ Lp 2)))))
(define Sy (for/vector ([p (in-vector Py)]
#:when (< (abs (- (point-x p) x-mid)) delta))
p))
(define Ls (vector-length Sy))
(define-values (_ best-pair)
(for*/fold ([new-best delta]
[new-best-pair null])
([i (in-range (sub1 Ls))]
[j (in-range (+ i 1) (min (+ i 7) Ls))]
[Sij (in-value (list (vector-ref Sy i)
(vector-ref Sy j)))]
[dij (in-value (distance^2 Sij))]
#:when (< dij new-best))
(values dij Sij)))
best-pair)
 
;; helper procedures
 
;; same as partition except for vectors
;; it's critical to maintain the relative order of elements
(define (vector-partition Py pred)
(define-values (left right)
(for/fold ([Qy null]
[Ry null])
([p (in-vector Py)])
(if (pred p)
(values (cons p Qy) Ry)
(values Qy (cons p Ry)))))
(values (list->vector (reverse left))
(list->vector (reverse right))))
 
; is p1 (strictly) left of p2
(define (left? p1 p2) (< (point-x p1) (point-x p2)))
 
; is p1 (strictly) below of p2
(define (below? p1 p2) (< (point-y p1) (point-y p2)))
 
;; return the pair with minimum distance
(define (min-pair . pairs)
(argmin distance^2 pairs))
 
;; pairs are passed around as a list of 2 points
;; distance is only for comparison so no need to use sqrt
(define (distance^2 pair)
(cond [(null? pair) +inf.0]
[else (define a (first pair))
(define b (second pair))
(+ (sqr (- (point-x b) (point-x a)))
(sqr (- (point-y b) (point-y a))))]))
 
; points on a quadratic curve, shuffled
(define points
(shuffle
(for/list ([ i (in-range 1000)]) (point i (* i i)))))
(match-define (list (point p1x p1y) (point p2x p2y)) (closest-pair points))
(printf "Closest points on a quadratic curve (~a,~a) (~a,~a)\n" p1x p1y p2x p2y)
</syntaxhighlight>
 
{{out}}
<syntaxhighlight lang="racket">
Closest points: (0+1i 1+2i)
Distance: 1.4142135623730951
</lang>
 
Closest points on a quadratic curve (0,0) (1,1)
=={{header|REXX}}==
</syntaxhighlight>
(This version of the REXX program is modeled after the psuedo-code.)
=={{header|Raku}}==
<lang rexx>/*REXX program to solve the closest pair problem. */
(formerly Perl 6)
parse arg N low high seed .; if n=='' then n=100
if seed\=='' then call random ,,seed /*use seed, makes rand repeatable*/
if low=='' | low==',' then low=0
if high=='' | high==',' then high=20000
w=length(high); w=w + (w//2==0)
do j=1 for N /*gen random points*/
@.j.xx=random(low,high)
@.j.yy=random(low,high)
end /*j*/
nearA=1
nearB=2
minDD=(@.nearA.xx-@.nearB.xx)**2 + (@.nearA.yy-@.nearB.yy)**2
 
{{trans|Perl 5}}
do j=1 for N-1
do k=j+1 to N
dd=(@.j.xx-@.k.xx)**2 + (@.j.yy-@.k.yy)**2
if dd\=0 then if dd<minDD then do; minDD=dd
nearA=j
nearB=k
end
end /*k*/
end /*j*/
 
Using concurrency, the 'simple' routine beats the (supposedly) more efficient one for all but the smallest sets of input.
say 'For' N "points:"; say
<syntaxhighlight lang="raku" line>sub MAIN ($N = 5000) {
say ' 'center('x',w,"═")' ' center('y',w,"═")
my @points = (^$N).map: { [rand × 20 - 10, rand × 20 - 10] }
say 'The points ['right(@.nearA.xx,w)"," right(@.nearA.yy,w)"]" ' and'
say ' ['right(@.nearB.xx,w)"," right(@.nearB.yy,w)"]"; say
say 'the minimum distance between them is: ' sqrt(abs(minDD))
exit /*stick a fork in it, we're done.*/
/*───────────────────────────────────sqrt subroutine────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0;d=digits();numeric digits 11
g=.sqrtG(); do j=0 while p>9; m.j=p; p=p%2+1; end
do k=j+5 to 0 by -1; if m.k>11 then numeric digits m.k; g=.5*(g+x/g); end
numeric digits d; return g/1
.sqrtG: numeric form; m.=11; p=d+d%4+2
parse value format(x,2,1,,0) 'E0' with g 'E' _ .; return g*.5'E'_%2</lang>
'''output''' when using the input of: <tt> 200 </tt>
<pre style="overflow:scroll">
For 100 points:
 
my @candidates = @points.sort(*.[0]).rotor( 10 => -2, :partial).race.map: { closest-pair-simple(@$_) }
══x══ ══y══
say 'simple ' ~ (@candidates.sort: *.[2]).head(1).gist;
The points [11341, 19534] and
@candidates = @points.sort(*.[0]).rotor( 10 => -2, :partial).race.map: { closest-pair(@$_) }
[11136, 19498]
say 'real ' ~ (@candidates.sort: *.[2]).head(1).gist;
}
 
sub dist-squared(@a, @b) { (@a[0] - @b[0])² + (@a[1] - @b[1])² }
the minimum distance between them is: 208.136974
 
sub closest-pair-simple(@points is copy) {
return ∞ if @points < 2;
my ($a, $b, $d) = |@points[0,1], dist-squared(|@points[0,1]);
while @points {
my \p = pop @points;
for @points -> \l {
($a, $b, $d) = p, l, $_ if $_ < $d given dist-squared(p, l);
}
}
$a, $b, $d.sqrt
}
 
sub closest-pair(@r) {
closest-pair-real (@r.sort: *.[0]), (@r.sort: *.[1])
}
 
sub closest-pair-real(@rx, @ry) {
return closest-pair-simple(@rx) if @rx ≤ 3;
 
my \N = @rx;
my \midx = ceiling(N/2) - 1;
my @PL := @rx[ 0 .. midx];
my @PR := @rx[midx+1 ..^ N ];
my \xm = @rx[midx;0];
(.[0] ≤ xm ?? my @yR !! my @yL).push: @$_ for @ry;
my (\al, \bl, \dL) = closest-pair-real(@PL, @yR);
my (\ar, \br, \dR) = closest-pair-real(@PR, @yL);
my ($w1, $w2, $closest) = dR < dL ?? (ar, br, dR) !! (al, bl, dL);
my @yS = @ry.grep: { (xm - .[0]).abs < $closest }
 
for 0 ..^ @yS -> \i {
for i+1 ..^ @yS -> \k {
next unless @yS[k;1] - @yS[i;1] < $closest;
($w1, $w2, $closest) = |@yS[k, i], $_ if $_ < $closest given dist-squared(|@yS[k, i]).sqrt;
}
}
$w1, $w2, $closest
}</syntaxhighlight>
{{out}}
<pre>simple (([-1.1560800527301716 -9.214015073077793] [-1.1570263876019649 -9.213340680530798] 0.0011620477602117762))
real (([-1.1570263876019649 -9.213340680530798] [-1.1560800527301716 -9.214015073077793] 0.0011620477602117762))</pre>
=={{header|REXX}}==
Programming note: &nbsp; this REXX version allows two (or more) points to be identical, and will
<br>manifest itself as a minimum distance of zero &nbsp; (the variable &nbsp; <big> <tt> '''dd''' </tt> </big> &nbsp; on line 17).
<syntaxhighlight lang="rexx">/*REXX program solves the closest pair of points problem (in two dimensions). */
parse arg N LO HI seed . /*obtain optional arguments from the CL*/
if N=='' | N=="," then N= 100 /*Not specified? Then use the default.*/
if LO=='' | LO=="," then LO= 0 /* " " " " " " */
if HI=='' | HI=="," then HI= 20000 /* " " " " " " */
if datatype(seed, 'W') then call random ,,seed /*seed for RANDOM (BIF) repeatability.*/
w= length(HI); w= w + (w//2==0) /*W: for aligning the output columns.*/
 
/*╔══════════════════════╗*/ do j=1 for N /*generate N random points*/
/*║ generate N points. ║*/ @x.j= random(LO, HI) /* " a " X */
/*╚══════════════════════╝*/ @y.j= random(LO, HI) /* " a " Y */
end /*j*/ /*X & Y make the point.*/
A= 1; B= 2 /* [↓] MIND is actually the squared */
minD= (@x.A - @x.B)**2 + (@y.A - @y.B)**2 /* distance between the 1st two points.*/
/* [↓] use of XJ & YJ speed things up.*/
do j=1 for N-1; xj= @x.j; yj= @y.j /*find min distance between a point ···*/
do k=j+1 for N-j-1 /* ··· and all other (higher) points. */
sd= (xj - @x.k)**2 + (yj - @y.k)**2 /*compute squared distance from points.*/
if sd<minD then parse value sd j k with minD A B
end /*k*/ /* [↑] needn't take SQRT of SD (yet).*/
end /*j*/ /* [↑] when done, A & B are the points*/
$= 'For ' N " points, the minimum distance between the two points: "
say $ center("x", w, '═')" " center('y', w, "═") ' is: ' sqrt( abs(minD)) / 1
say left('', length($) - 1) "["right(@x.A, w)',' right(@y.A, w)"]"
say left('', length($) - 1) "["right(@x.B, w)',' right(@y.B, w)"]"
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); m.=9; numeric form; h=d+6
numeric digits; parse value format(x,2,1,,0) 'E0' with g 'E' _ .; g= g *.5'e'_ % 2
do j=0 while h>9; m.j= h; h= h % 2 + 1; end /*j*/
do k=j+5 to 0 by -1; numeric digits m.k; g= (g+x/g)*.5; end /*k*/; return g</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input of: &nbsp; &nbsp; <tt> 100 </tt>}}
<pre>
For 100 points, the minimum distance between the two points: ══x══ ══y══ is: 219.228192
[ 7277, 1625]
[ 7483, 1700]
</pre>
{{out|output|text=&nbsp; when using the input of: &nbsp; &nbsp; <tt> 200 </tt>}}
<pre>
For 200 points, the minimum distance between the two points: ══x══ ══y══ is: 39.408121
[17604, 19166]
[17627, 19198]
</pre>
{{out|output|text=&nbsp; when using the input of: &nbsp; &nbsp; <tt> 1000 </tt>
}}
<pre>
For 1000 points, the minimum distance between the two points: ══x══ ══y══ is: 5.09901951
[ 6264, 19103]
[ 6263, 19108]
</pre>
=={{header|Ring}}==
<syntaxhighlight lang="ring">
decimals(10)
x = list(10)
y = list(10)
x[1] = 0.654682
y[1] = 0.925557
x[2] = 0.409382
y[2] = 0.619391
x[3] = 0.891663
y[3] = 0.888594
x[4] = 0.716629
y[4] = 0.996200
x[5] = 0.477721
y[5] = 0.946355
x[6] = 0.925092
y[6] = 0.818220
x[7] = 0.624291
y[7] = 0.142924
x[8] = 0.211332
y[8] = 0.221507
x[9] = 0.293786
y[9] = 0.691701
x[10] = 0.839186
y[10] = 0.728260
min = 10000
for i = 1 to 9
for j = i+1 to 10
dsq = pow((x[i] - x[j]),2) + pow((y[i] - y[j]),2)
if dsq < min min = dsq mini = i minj = j ok
next
next
see "closest pair is : " + mini + " and " + minj + " at distance " + sqrt(min)
</syntaxhighlight>
Output:
<pre>
closest pair is : 3 and 6 at distance 0.0779101914
</pre>
=={{header|RPL}}==
Brute-force approach, because it's unlikely that anyone would use a RPL calculator to process a large set of points.
« → points
« 0 0 0
1 points SIZE 1 - '''FOR''' j
j 1 + points SIZE '''FOR''' k
points j GET points k GET - ABS
'''IF''' DUP2 < '''THEN''' 4 ROLLD 3 DROPN j k ROT '''ELSE''' DROP '''END'''
'''NEXT NEXT''' ROT ROT
points SWAP GET points ROT GET
'''IF''' DUP2 RE SWAP RE < '''THEN''' SWAP '''END''' <span style="color:grey">@ sort by ascending x</span>
2 →LIST
» » '<span style="color:blue">CLOSEPR</span>' STO
 
{ (0,0) (1,0) (1,2) (3,4) (5,5) (7,5) (3,5) } <span style="color:blue">CLOSEPR</span>
{{out}}
<pre>
2: 8.60232526704
1: { (0,0) (7,5) }
</pre>
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby">Point = Struct.new(:x, :y)
 
def distance(p1, p2)
Line 2,845 ⟶ 4,254:
def closest_bruteforce(points)
mindist, minpts = Float::MAX, []
points.length.timescombination(2) do |ipi,pj|
dist = distance(pi, pj)
(i+1).upto(points.length - 1) do |j|
if dist = distance(points[i],< points[j])mindist
ifmindist = dist < mindist
minpts = mindist =[pi, distpj]
minpts = [points[i], points[j]]
end
end
end
Line 2,858 ⟶ 4,265:
 
def closest_recursive(points)
return closest_bruteforce(points) if points.length <= 3
xP = points.sort_by(&:x)
return closest_bruteforce(points)
mid = points.length / 2
end
xPxm = points.sort_by {|p| pxP[mid].x}
dL, pairL = closest_recursive(xP[0,mid])
mid = (points.length / 2.0).ceil
pLdR, pairR = closest_recursive(xP[0,mid..-1])
dmin, dpair = dL<dR ? [dL, pairL] : [dR, pairR]
pR = xP[mid..-1]
yP = xP.find_all {|p| (xm - p.x).abs < dmin}.sort_by(&:y)
dL, pairL = closest_recursive(pL)
closest, closestPair = dmin, dpair
dR, pairR = closest_recursive(pR)
if dL < dR
dmin, dpair = dL, pairL
else
dmin, dpair = dR, pairR
end
yP = xP.find_all {|p| (pL[-1].x - p.x).abs < dmin}.sort_by {|p| p.y}
closest = Float::MAX
closestPair = []
0.upto(yP.length - 2) do |i|
(i+1).upto(yP.length - 1) do |k|
Line 2,885 ⟶ 4,284:
end
end
if [closest, < dminclosestPair]
[closest, closestPair]
else
[dmin, dpair]
end
end
 
 
points = Array.new(100) {Point.new(rand, rand)}
Line 2,904 ⟶ 4,298:
x.report("bruteforce") {ans1 = closest_bruteforce(points)}
x.report("recursive") {ans2 = closest_recursive(points)}
end</langsyntaxhighlight>
'''Sample output'''
<pre style='width:full; overflow:scroll'>[0.00522229060545241, [#<struct Point x=0.43887011964135, y=0.00656904813877568>, #<struct Point x=0.433711197400243, y=0.00575797448120408>]]
<pre>
[0.00522229060545241, [#<struct Point x=0.433711197400243, y=0.00575797448120408>, #<struct Point x=0.43887011964135, y=0.00656904813877568>]]
[0.005299616045889868, [#<struct Point x=0.24805908871087445, y=0.8413503128160198>, #<struct Point x=0.24355227214243136, y=0.8385620275629906>]]
user system total real
[0.005299616045889868, [#<struct Point x=0.24355227214243136, y=0.8385620275629906>, #<struct Point x=0.24805908871087445, y=0.8413503128160198>]]
bruteforce 133.437000 0.000000 133.437000 (134.633000)
user system total real
recursive 0.516000 0.000000 0.516000 ( 0.559000)</pre>
bruteforce 43.446000 0.000000 43.446000 ( 43.530062)
recursive 0.187000 0.000000 0.187000 ( 0.190000)
</pre>
 
=={{header|Run BASIC}}==
Courtesy http://dkokenge.com/rbp
<langsyntaxhighlight lang="runbasic">n =10 ' 10 data points input
dim x(n)
dim y(n)
Line 2,953 ⟶ 4,350:
data 0.211332, 0.221507
data 0.293786, 0.691701
data 0.839186, 0.72826</langsyntaxhighlight>
=={{header|Rust}}==
<syntaxhighlight lang="rust">
//! We interpret complex numbers as points in the Cartesian plane, here. We also use the
//! [sweepline/plane sweep closest pairs algorithm][algorithm] instead of the divide-and-conquer
//! algorithm, since it's (arguably) easier to implement, and an efficient implementation does not
//! require use of unsafe.
//!
//! [algorithm]: http://www.cs.mcgill.ca/~cs251/ClosestPair/ClosestPairPS.html
extern crate num;
 
use num::complex::Complex;
use std::cmp::{Ordering, PartialOrd};
use std::collections::BTreeSet;
type Point = Complex<f32>;
 
/// Wrapper around `Point` (i.e. `Complex<f32>`) so that we can use a `TreeSet`
#[derive(PartialEq)]
struct YSortedPoint {
point: Point,
}
 
impl PartialOrd for YSortedPoint {
fn partial_cmp(&self, other: &YSortedPoint) -> Option<Ordering> {
(self.point.im, self.point.re).partial_cmp(&(other.point.im, other.point.re))
}
}
 
impl Ord for YSortedPoint {
fn cmp(&self, other: &YSortedPoint) -> Ordering {
self.partial_cmp(other).unwrap()
}
}
 
impl Eq for YSortedPoint {}
 
fn closest_pair(points: &mut [Point]) -> Option<(Point, Point)> {
if points.len() < 2 {
return None;
}
 
points.sort_by(|a, b| (a.re, a.im).partial_cmp(&(b.re, b.im)).unwrap());
 
let mut closest_pair = (points[0], points[1]);
let mut closest_distance_sqr = (points[0] - points[1]).norm_sqr();
let mut closest_distance = closest_distance_sqr.sqrt();
 
// the strip that we inspect for closest pairs as we sweep right
let mut strip: BTreeSet<YSortedPoint> = BTreeSet::new();
strip.insert(YSortedPoint { point: points[0] });
strip.insert(YSortedPoint { point: points[1] });
 
// index of the leftmost point on the strip (on points)
let mut leftmost_idx = 0;
 
// Start the sweep!
for (idx, point) in points.iter().enumerate().skip(2) {
// Remove all points farther than `closest_distance` away from `point`
// along the x-axis
while leftmost_idx < idx {
let leftmost_point = &points[leftmost_idx];
if (leftmost_point.re - point.re).powi(2) < closest_distance_sqr {
break;
}
strip.remove(&YSortedPoint {
point: *leftmost_point,
});
leftmost_idx += 1;
}
 
// Compare to points in bounding box
{
let low_bound = YSortedPoint {
point: Point {
re: ::std::f32::INFINITY,
im: point.im - closest_distance,
},
};
let mut strip_iter = strip.iter().skip_while(|&p| p < &low_bound);
loop {
let point2 = match strip_iter.next() {
None => break,
Some(p) => p.point,
};
if point2.im - point.im >= closest_distance {
// we've reached the end of the box
break;
}
let dist_sqr = (*point - point2).norm_sqr();
if dist_sqr < closest_distance_sqr {
closest_pair = (point2, *point);
closest_distance_sqr = dist_sqr;
closest_distance = dist_sqr.sqrt();
}
}
}
 
// Insert point into strip
strip.insert(YSortedPoint { point: *point });
}
 
Some(closest_pair)
}
 
pub fn main() {
let mut test_data = [
Complex::new(0.654682, 0.925557),
Complex::new(0.409382, 0.619391),
Complex::new(0.891663, 0.888594),
Complex::new(0.716629, 0.996200),
Complex::new(0.477721, 0.946355),
Complex::new(0.925092, 0.818220),
Complex::new(0.624291, 0.142924),
Complex::new(0.211332, 0.221507),
Complex::new(0.293786, 0.691701),
Complex::new(0.839186, 0.728260),
];
let (p1, p2) = closest_pair(&mut test_data[..]).unwrap();
println!("Closest pair: {} and {}", p1, p2);
println!("Distance: {}", (p1 - p2).norm_sqr().sqrt());
}
</syntaxhighlight>
{{out}}
<pre>
Closest pair: 0.891663+0.888594i and 0.925092+0.81822i
Distance: 0.07791013
</pre>
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">import scala.utilcollection.mutable._ListBuffer
import scala.util.Random
 
object ClosestPair {
case class Point(x: Double, y: Double) extends Pair(x,y){
def distance(p: Point) = math.hypot(_1x-p._1x, _2y-p._2y)
}
 
override def toString = "(" + x + ", " + y + ")"
def closestPairBF(a:Array[Point])={
}
var minDist=a(0) distance a(1)
var minPoints=(a(0), a(1))
 
case class Pair(point1: Point, point2: Point) {
for(p1<-a; p2<-a if p1.ne(p2); dist=p1 distance p2 if(dist<minDist)){
val distance: Double = point1 distance point2
minDist=dist;
 
minPoints=(p1, p2)
override def toString = {
point1 + "-" + point2 + " : " + distance
}
}
 
def sortByX(points: List[Point]) = {
points.sortBy(point => point.x)
}
 
def sortByY(points: List[Point]) = {
points.sortBy(point => point.y)
}
 
def divideAndConquer(points: List[Point]): Pair = {
val pointsSortedByX = sortByX(points)
val pointsSortedByY = sortByY(points)
 
divideAndConquer(pointsSortedByX, pointsSortedByY)
}
 
def bruteForce(points: List[Point]): Pair = {
val numPoints = points.size
if (numPoints < 2)
return null
var pair = Pair(points(0), points(1))
if (numPoints > 2) {
for (i <- 0 until numPoints - 1) {
val point1 = points(i)
for (j <- i + 1 until numPoints) {
val point2 = points(j)
val distance = point1 distance point2
if (distance < pair.distance)
pair = Pair(point1, point2)
}
}
}
(minPoints, minDist)
return pair
}
}
 
def main(args: Array[String]): Unit = {
val a=Array.fill(1000)(new Point(Random.nextDouble, Random.nextDouble))
val (points, dist)=closestPairBF(a)
println("min: "+points._1+" - "+points._2+" ->"+dist)
}
}</lang>
 
private def divideAndConquer(pointsSortedByX: List[Point], pointsSortedByY: List[Point]): Pair = {
val numPoints = pointsSortedByX.size
if(numPoints <= 3) {
return bruteForce(pointsSortedByX)
}
 
val dividingIndex = numPoints >>> 1
val leftOfCenter = pointsSortedByX.slice(0, dividingIndex)
val rightOfCenter = pointsSortedByX.slice(dividingIndex, numPoints)
 
var tempList = leftOfCenter.map(x => x)
//println(tempList)
tempList = sortByY(tempList)
var closestPair = divideAndConquer(leftOfCenter, tempList)
 
tempList = rightOfCenter.map(x => x)
tempList = sortByY(tempList)
 
val closestPairRight = divideAndConquer(rightOfCenter, tempList)
 
if (closestPairRight.distance < closestPair.distance)
closestPair = closestPairRight
 
tempList = List[Point]()
val shortestDistance = closestPair.distance
val centerX = rightOfCenter(0).x
 
for (point <- pointsSortedByY) {
if (Math.abs(centerX - point.x) < shortestDistance)
tempList = tempList :+ point
}
 
closestPair = shortestDistanceF(tempList, shortestDistance, closestPair)
closestPair
}
 
private def shortestDistanceF(tempList: List[Point], shortestDistance: Double, closestPair: Pair ): Pair = {
var shortest = shortestDistance
var bestResult = closestPair
for (i <- 0 until tempList.size) {
val point1 = tempList(i)
for (j <- i + 1 until tempList.size) {
val point2 = tempList(j)
if ((point2.y - point1.y) >= shortestDistance)
return closestPair
val distance = point1 distance point2
if (distance < closestPair.distance)
{
bestResult = Pair(point1, point2)
shortest = distance
}
}
}
 
closestPair
}
 
def main(args: Array[String]) {
val numPoints = if(args.length == 0) 1000 else args(0).toInt
 
val points = ListBuffer[Point]()
val r = new Random()
for (i <- 0 until numPoints) {
points.+=:(new Point(r.nextDouble(), r.nextDouble()))
}
println("Generated " + numPoints + " random points")
 
var startTime = System.currentTimeMillis()
val bruteForceClosestPair = bruteForce(points.toList)
var elapsedTime = System.currentTimeMillis() - startTime
println("Brute force (" + elapsedTime + " ms): " + bruteForceClosestPair)
 
startTime = System.currentTimeMillis()
val dqClosestPair = divideAndConquer(points.toList)
elapsedTime = System.currentTimeMillis() - startTime
println("Divide and conquer (" + elapsedTime + " ms): " + dqClosestPair)
if (bruteForceClosestPair.distance != dqClosestPair.distance)
println("MISMATCH")
}
}
</syntaxhighlight>
 
{{out}}
<pre>scala ClosestPair 1000
Generated 1000 random points
Brute force (981 ms): (0.41984960343173994, 0.4499078600557793)-(0.4198255166110827, 0.45044969701435) : 5.423720721077961E-4
Divide and conquer (52 ms): (0.4198255166110827, 0.45044969701435)-(0.41984960343173994, 0.4499078600557793) : 5.423720721077961E-4
</pre>
=={{header|Seed7}}==
This is the brute force algorithm:
 
<langsyntaxhighlight lang="seed7">const type: point is new struct
var float: x is 0.0;
var float: y is 0.0;
Line 3,016 ⟶ 4,654:
result := [] (points[savei], points[savej]);
end if;
end func;</langsyntaxhighlight>
=={{header|Sidef}}==
{{trans|Raku}}
<syntaxhighlight lang="ruby">func dist_squared(a, b) {
sqr(a[0] - b[0]) + sqr(a[1] - b[1])
}
 
func closest_pair_simple(arr) {
arr.len < 2 && return Inf
var (a, b, d) = (arr[0, 1], dist_squared(arr[0,1]))
arr.clone!
while (arr) {
var p = arr.pop
for l in arr {
var t = dist_squared(p, l)
if (t < d) {
(a, b, d) = (p, l, t)
}
}
}
return(a, b, d.sqrt)
}
 
func closest_pair_real(rx, ry) {
rx.len <= 3 && return closest_pair_simple(rx)
 
var N = rx.len
var midx = (ceil(N/2)-1)
var (PL, PR) = rx.part(midx)
 
var xm = rx[midx][0]
 
var yR = []
var yL = []
 
for item in ry {
(item[0] <= xm ? yR : yL) << item
}
 
var (al, bl, dL) = closest_pair_real(PL, yR)
var (ar, br, dR) = closest_pair_real(PR, yL)
 
al == Inf && return (ar, br, dR)
ar == Inf && return (al, bl, dL)
 
var (m1, m2, dmin) = (dR < dL ? [ar, br, dR]...
: [al, bl, dL]...)
 
var yS = ry.grep { |a| abs(xm - a[0]) < dmin }
 
var (w1, w2, closest) = (m1, m2, dmin)
for i in (0 ..^ yS.end) {
for k in (i+1 .. yS.end) {
yS[k][1] - yS[i][1] < dmin || break
var d = dist_squared(yS[k], yS[i]).sqrt
if (d < closest) {
(w1, w2, closest) = (yS[k], yS[i], d)
}
}
}
 
return (w1, w2, closest)
}
 
func closest_pair(r) {
var ax = r.sort_by { |a| a[0] }
var ay = r.sort_by { |a| a[1] }
return closest_pair_real(ax, ay);
}
 
var N = 5000
var points = N.of { [1.rand*20 - 10, 1.rand*20 - 10] }
var (af, bf, df) = closest_pair(points)
say "#{df} at (#{af.join(' ')}), (#{bf.join(' ')})"</syntaxhighlight>
=={{header|Smalltalk}}==
See [[Closest-pair problem/Smalltalk]]
=={{header|Swift}}==
 
<syntaxhighlight lang="swift">import Foundation
 
struct Point {
var x: Double
var y: Double
 
func distance(to p: Point) -> Double {
let x = pow(p.x - self.x, 2)
let y = pow(p.y - self.y, 2)
return (x + y).squareRoot()
}
}
 
extension Collection where Element == Point {
func closestPair() -> (Point, Point)? {
let (xP, xY) = (sorted(by: { $0.x < $1.x }), sorted(by: { $0.y < $1.y }))
return Self.closestPair(xP, xY)?.1
}
static func closestPair(_ xP: [Element], _ yP: [Element]) -> (Double, (Point, Point))? {
guard xP.count > 3 else { return xP.closestPairBruteForce() }
let half = xP.count / 2
let xl = Array(xP[..<half])
let xr = Array(xP[half...])
let xm = xl.last!.x
let (yl, yr) = yP.reduce(into: ([Element](), [Element]()), {cur, el in
if el.x > xm {
cur.1.append(el)
} else {
cur.0.append(el)
}
})
guard let (distanceL, pairL) = closestPair(xl, yl) else { return nil }
guard let (distanceR, pairR) = closestPair(xr, yr) else { return nil }
let (dMin, pairMin) = distanceL > distanceR ? (distanceR, pairR) : (distanceL, pairL)
let ys = yP.filter({ abs(xm - $0.x) < dMin })
var (closest, pairClosest) = (dMin, pairMin)
for i in 0..<ys.count {
let p1 = ys[i]
for k in i+1..<ys.count {
let p2 = ys[k]
guard abs(p2.y - p1.y) < dMin else { break }
let distance = abs(p1.distance(to: p2))
if distance < closest {
(closest, pairClosest) = (distance, (p1, p2))
}
}
}
return (closest, pairClosest)
}
func closestPairBruteForce() -> (Double, (Point, Point))? {
guard count >= 2 else { return nil }
var closestPoints = (self.first!, self[index(after: startIndex)])
var minDistance = abs(closestPoints.0.distance(to: closestPoints.1))
guard count != 2 else { return (minDistance, closestPoints) }
for i in 0..<count {
for j in i+1..<count {
let (iIndex, jIndex) = (index(startIndex, offsetBy: i), index(startIndex, offsetBy: j))
let (p1, p2) = (self[iIndex], self[jIndex])
let distance = abs(p1.distance(to: p2))
if distance < minDistance {
minDistance = distance
closestPoints = (p1, p2)
}
}
}
return (minDistance, closestPoints)
}
}
 
var points = [Point]()
 
for _ in 0..<10_000 {
points.append(Point(
x: .random(in: -10.0...10.0),
y: .random(in: -10.0...10.0)
))
}
 
print(points.closestPair()!)</syntaxhighlight>
 
{{out}}
 
<pre>(Point(x: 5.279430517795172, y: 8.85108182685002), Point(x: 5.278427575530877, y: 8.851990433099456))</pre>
=={{header|Tcl}}==
Each point is represented as a list of two floating-point numbers, the first being the ''x'' coordinate, and the second being the ''y''.
<langsyntaxhighlight Tcllang="tcl">package require Tcl 8.5
 
# retrieve the x-coordinate
Line 3,112 ⟶ 4,927:
set time [time {set ::dist($method) [closest_$method $points]} 1]
puts [format "%-10s %9d %9d %s" $method $::comparisons [lindex $time 0] [lindex $::dist($method) 0]]
}</langsyntaxhighlight>
{{out}}
Example output
<pre>method compares time closest
bruteforce 49995000 512967207 0.0015652738546658382
recursive 14613 488094 0.0015652738546658382</pre>
Note that the <code>lindex</code> and <code>llength</code> commands are both O(1).
 
=={{header|Ursala}}==
The brute force algorithm is easy. Reading from left to right,
Reading from left to right, clop is defined as a function that forms the Cartesian product
that forms the Cartesian product of its argument,
of its argument, and then extracts the member whose left side
and then extracts the member whose left side is a minimum
is a minimum with respect to the floating point comparison relation
with respect to the floating point comparison relation
after deleting equal pairs and attaching to the left of
each remaining pair the sum of the squares of the differences
between corresponding coordinates.
<langsyntaxhighlight Ursalalang="ursala">#import flo
 
clop = @iiK0 fleq$-&l+ *EZF ^\~& plus+ sqr~~+ minus~~bbI</langsyntaxhighlight>
The divide and conquer algorithm following the specification given
given above is a little more hairy but not much longer.
The <code>eudist</code> library function
is used to compute the distance between points.
<langsyntaxhighlight Ursalalang="ursala">#import std
#import flo
 
Line 3,141 ⟶ 4,956:
^(fleq-<&l,fleq-<&r); @blrNCCS ~&lrbhthPX2X+ ~&a^& fleq$-&l+ leql/8?al\^(eudist,~&)*altK33htDSL -+
^C/~&rr ^(eudist,~&)*tK33htDSL+ @rlrlPXPlX ~| fleq^\~&lr abs+ minus@llPrhPX,
^/~&ar @farlK30K31XPGbrlrjX3J ^/~&arlhh @W lesser fleq@bl+-</langsyntaxhighlight>
test program:
<langsyntaxhighlight Ursalalang="ursala">test_data =
 
<
Line 3,165 ⟶ 4,980:
#cast %eeWWA
 
example = clop test_data</langsyntaxhighlight>
{{out}}
The output shows the minimum distance and the two points separated
by that distance. (If the brute force algorithm were used, it would
Line 3,173 ⟶ 4,989:
(-2.132372e+00,2.358850e+00),
(-1.745694e+00,3.276434e+00))
</pre>
=={{header|VBA}}==
<syntaxhighlight lang="vb">Option Explicit
 
Private Type MyPoint
X As Single
Y As Single
End Type
 
Private Type MyPair
p1 As MyPoint
p2 As MyPoint
End Type
 
Sub Main()
Dim points() As MyPoint, i As Long, BF As MyPair, d As Single, Nb As Long
Dim T#
Randomize Timer
Nb = 10
Do
ReDim points(1 To Nb)
For i = 1 To Nb
points(i).X = Rnd * Nb
points(i).Y = Rnd * Nb
Next
d = 1000000000000#
T = Timer
BF = BruteForce(points, d)
Debug.Print "For " & Nb & " points, runtime : " & Timer - T & " sec."
Debug.Print "point 1 : X:" & BF.p1.X & " Y:" & BF.p1.Y
Debug.Print "point 2 : X:" & BF.p2.X & " Y:" & BF.p2.Y
Debug.Print "dist : " & d
Debug.Print "--------------------------------------------------"
Nb = Nb * 10
Loop While Nb <= 10000
End Sub
 
Private Function BruteForce(p() As MyPoint, mindist As Single) As MyPair
Dim i As Long, j As Long, d As Single, ClosestPair As MyPair
For i = 1 To UBound(p) - 1
For j = i + 1 To UBound(p)
d = Dist(p(i), p(j))
If d < mindist Then
mindist = d
ClosestPair.p1 = p(i)
ClosestPair.p2 = p(j)
End If
Next
Next
BruteForce = ClosestPair
End Function
 
Private Function Dist(p1 As MyPoint, p2 As MyPoint) As Single
Dist = Sqr((p1.X - p2.X) ^ 2 + (p1.Y - p2.Y) ^ 2)
End Function
</syntaxhighlight>
{{out}}
<pre>For 10 points, runtime : 0 sec.
point 1 : X:7,199265 Y:7,690955
point 2 : X:7,16863 Y:7,681544
dist : 3,204883E-02
--------------------------------------------------
For 100 points, runtime : 0 sec.
point 1 : X:48,97898 Y:96,54872
point 2 : X:48,78981 Y:96,95755
dist : 0,4504737
--------------------------------------------------
For 1000 points, runtime : 0,44921875 sec.
point 1 : X:576,9511 Y:398,5834
point 2 : X:577,364 Y:398,3212
dist : 0,4891393
--------------------------------------------------
For 10000 points, runtime : 47,46875 sec.
point 1 : X:8982,698 Y:1154,133
point 2 : X:8984,763 Y:1152,822
dist : 2,445694
--------------------------------------------------</pre>
=={{header|Visual FoxPro}}==
<syntaxhighlight lang="vfp">
CLOSE DATABASES ALL
CREATE CURSOR pairs(id I, xcoord B(6), ycoord B(6))
INSERT INTO pairs VALUES (1, 0.654682, 0.925557)
INSERT INTO pairs VALUES (2, 0.409382, 0.619391)
INSERT INTO pairs VALUES (3, 0.891663, 0.888594)
INSERT INTO pairs VALUES (4, 0.716629, 0.996200)
INSERT INTO pairs VALUES (5, 0.477721, 0.946355)
INSERT INTO pairs VALUES (6, 0.925092, 0.818220)
INSERT INTO pairs VALUES (7, 0.624291, 0.142924)
INSERT INTO pairs VALUES (8, 0.211332, 0.221507)
INSERT INTO pairs VALUES (9, 0.293786, 0.691701)
INSERT INTO pairs VALUES (10, 0.839186, 0.728260)
 
SELECT p1.id As id1, p2.id As id2, ;
(p1.xcoord-p2.xcoord)^2 + (p1.ycoord-p2.ycoord)^2 As dist2 ;
FROM pairs p1 JOIN pairs p2 ON p1.id < p2.id ORDER BY 3 INTO CURSOR tmp
 
GO TOP
? "Closest pair is " + TRANSFORM(id1) + " and " + TRANSFORM(id2) + "."
? "Distance is " + TRANSFORM(SQRT(dist2))
</syntaxhighlight>
{{out}}
<pre>
Visual FoxPro uses 1 based indexing,
 
Closest pair is 3 and 6.
Distance is 0.077910.
</pre>
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-math}}
{{libheader|Wren-sort}}
<syntaxhighlight lang="wren">import "./math" for Math
import "./sort" for Sort
 
var distance = Fn.new { |p1, p2| Math.hypot(p1[0] - p2[0], p1[1] - p2[1]) }
 
var bruteForceClosestPair = Fn.new { |p|
var n = p.count
if (n < 2) Fiber.abort("There must be at least two points.")
var minPoints = [p[0], p[1]]
var minDistance = distance.call(p[0], p[1])
for (i in 0...n-1) {
for (j in i+1...n) {
var dist = distance.call(p[i], p[j])
if (dist < minDistance) {
minDistance = dist
minPoints = [p[i], p[j]]
}
}
}
return [minDistance, minPoints]
}
 
var optimizedClosestPair // recursive so pre-declare
optimizedClosestPair = Fn.new { |xP, yP|
var n = xP.count
if (n <= 3) return bruteForceClosestPair.call(xP)
var hn = (n/2).floor
var xL = xP.take(hn).toList
var xR = xP.skip(hn).toList
var xm = xP[hn-1][0]
var yL = yP.where { |p| p[0] <= xm }.toList
var yR = yP.where { |p| p[0] > xm }.toList
var ll = optimizedClosestPair.call(xL, yL)
var dL = ll[0]
var pairL = ll[1]
var rr = optimizedClosestPair.call(xR, yR)
var dR = rr[0]
var pairR = rr[1]
var dmin = dR
var pairMin = pairR
if (dL < dR) {
dmin = dL
pairMin = pairL
}
var yS = yP.where { |p| (xm - p[0]).abs < dmin }.toList
var nS = yS.count
var closest = dmin
var closestPair = pairMin
for (i in 0...nS-1) {
var k = i + 1
while (k < nS && (yS[k][1] - yS[i][1] < dmin)) {
var dist = distance.call(yS[k], yS[i])
if (dist < closest) {
closest = dist
closestPair = [yS[k], yS[i]]
}
k = k + 1
}
}
return [closest, closestPair]
}
 
var points = [
[ [5, 9], [9, 3], [2, 0], [8, 4], [7, 4], [9, 10], [1, 9], [8, 2], [0, 10], [9, 6] ],
 
[
[0.654682, 0.925557], [0.409382, 0.619391], [0.891663, 0.888594],
[0.716629, 0.996200], [0.477721, 0.946355], [0.925092, 0.818220],
[0.624291, 0.142924], [0.211332, 0.221507], [0.293786, 0.691701],
[0.839186, 0.728260]
]
]
 
for (p in points) {
var dp = bruteForceClosestPair.call(p)
var dist = dp[0]
var pair = dp[1]
System.print("Closest pair (brute force) is %(pair[0]) and %(pair[1]), distance %(dist)")
var xP = Sort.merge(p) { |x, y| (x[0] - y[0]).sign }
var yP = Sort.merge(p) { |x, y| (x[1] - y[1]).sign }
dp = optimizedClosestPair.call(xP, yP)
dist = dp[0]
pair = dp[1]
System.print("Closest pair (optimized) is %(pair[0]) and %(pair[1]), distance %(dist)\n")
}</syntaxhighlight>
 
{{out}}
<pre>
Closest pair (brute force) is [8, 4] and [7, 4], distance 1
Closest pair (optimized) is [7, 4] and [8, 4], distance 1
 
Closest pair (brute force) is [0.891663, 0.888594] and [0.925092, 0.81822], distance 0.077910191355175
Closest pair (optimized) is [0.891663, 0.888594] and [0.925092, 0.81822], distance 0.077910191355175
</pre>
 
=={{header|XPL0}}==
The brute force method is simpler than the recursive solution and is
and is perfectly adequate, even for a thousand points.
 
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
proc ClosestPair(P, N); \Show closest pair of points in array P
Line 3,215 ⟶ 5,235:
[0.839186, 0.728260]]; \9
ClosestPair(Data, 10);
]</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
2 -- 5
0.891663,0.888594 -- 0.925092,0.818220
</pre>
=={{header|Yabasic}}==
'''Versión de fuerza bruta:
<syntaxhighlight lang="yabasic">
minDist = 1^30
dim x(9), y(9)
x(0) = 0.654682 : y(0) = 0.925557
x(1) = 0.409382 : y(1) = 0.619391
x(2) = 0.891663 : y(2) = 0.888594
x(3) = 0.716629 : y(3) = 0.996200
x(4) = 0.477721 : y(4) = 0.946355
x(5) = 0.925092 : y(5) = 0.818220
x(6) = 0.624291 : y(6) = 0.142924
x(7) = 0.211332 : y(7) = 0.221507
x(8) = 0.293786 : y(8) = 0.691701
x(9) = 0.839186 : y(9) = 0.728260
 
for i = 0 to 8
for j = i+1 to 9
dist = (x(i) - x(j))^2 + (y(i) - y(j))^2
if dist < minDist then
minDist = dist
mini = i
minj = j
end if
next j
next i
print "El par mas cercano es ", mini, " y ", minj, " a una distancia de ", sqr(minDist)
end
</syntaxhighlight>
{{out}}
<pre>
El par mas cercano es 2 y 5 a una distancia de 3.68449e-05
</pre>
=={{header|zkl}}==
An ugly solution in both time and space.
<langsyntaxhighlight lang="zkl">class Point{
fcn init(_x,_y){ var[const] x=_x, y=_y; }
fcn distance(p){ (p.x-x).hypot(p.y-y) }
fcn toString { String("Point(",x,",",y,")") }
}
 
Line 3,235 ⟶ 5,287:
fcn closestPoints(points){
pairs:=Utils.Helpers.pickNFrom(2,points);
triples:=pairs.apply(fcn([(p1,p2)]){ T(p1,p2,p1.distance(p2)) });
triples.reduce(fcn([(_,_,d1)]p1,[(_,_,d2)]p2){
if(d1 < d2) p1 else p2});
});
}</lang>
}</syntaxhighlight>
<lang zkl>points:=T( 5.0, 9.0, 9.0, 3.0,
<syntaxhighlight lang="zkl">points:=T( 5.0, 9.0, 9.0, 3.0,
2.0, 0.0, 8.0, 4.0,
7.0, 4.0, 9.0, 10.0,
1.0, 9.0, 8.0, 2.0,
0.0, 10.0, 9.0, 6.0 ).pump(List,T.fp(Void.Read,1),Point);
 
closestPoints(points).println(); //-->L(Point(8,4),Point(7,4),1)
Line 3,252 ⟶ 5,305:
0.624291, 0.142924, 0.211332, 0.221507,
0.293786, 0.691701, 0.839186, 0.72826)
.pump(List,T.fp(Void.Read,1),Point);
closestPoints(points).println();</syntaxhighlight>
{{out}}
//-->L(Point(0.891663,0.888594),Point(0.925092,0.81822),0.0779102)</lang>
<pre>
L(Point(8,4),Point(7,4),1)
L(Point(0.925092,0.81822),Point(0.891663,0.888594),0.0779102)
</pre>
=={{header|ZX Spectrum Basic}}==
{{trans|BBC_BASIC}}
<syntaxhighlight lang="zxbasic">10 DIM x(10): DIM y(10)
20 FOR i=1 TO 10
30 READ x(i),y(i)
40 NEXT i
50 LET min=1e30
60 FOR i=1 TO 9
70 FOR j=i+1 TO 10
80 LET p1=x(i)-x(j): LET p2=y(i)-y(j): LET dsq=p1*p1+p2*p2
90 IF dsq<min THEN LET min=dsq: LET mini=i: LET minj=j
100 NEXT j
110 NEXT i
120 PRINT "Closest pair is ";mini;" and ";minj;" at distance ";SQR min
130 STOP
140 DATA 0.654682,0.925557
150 DATA 0.409382,0.619391
160 DATA 0.891663,0.888594
170 DATA 0.716629,0.996200
180 DATA 0.477721,0.946355
190 DATA 0.925092,0.818220
200 DATA 0.624291,0.142924
210 DATA 0.211332,0.221507
220 DATA 0.293786,0.691701
230 DATA 0.839186,0.728260</syntaxhighlight>
9,482

edits