Another update from ingydotnet^djgoku

This commit is contained in:
Ingy döt Net 2015-11-18 06:14:39 +00:00
parent 91df62d461
commit 948b86eafa
7604 changed files with 108452 additions and 22726 deletions

View file

@ -0,0 +1,24 @@
defmodule Closest_pair do
def bruteForce([p0,p1|_] = points) do
pnts = List.to_tuple(points)
minDist = distance(p0, p1)
n = tuple_size(pnts)
{minDistance, minPoints} = Enum.reduce(0..n-2, {minDist, [0,1]}, fn i,{mD,mP} ->
Enum.reduce(i+1..n-1, {mD,mP}, fn j,{md,mp} ->
dist = distance(elem(pnts,i), elem(pnts,j))
if dist < md, do: {dist, [i,j]}, else: {md,mp}
end)
end)
{:math.sqrt(minDistance), minPoints}
end
defp distance({p0x,p0y}, {p1x,p1y}) do
(p1x - p0x) * (p1x - p0x) + (p1y - p0y) * (p1y - p0y)
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)

View file

@ -0,0 +1,137 @@
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}]}

View file

@ -15,7 +15,7 @@ sub dist-squared($a,$b) {
sub closest_pair_simple(@arr is copy) {
return Inf if @arr < 2;
my ($a, $b, $d) = @arr[0,1], dist-squared(|@arr[0,1]);
my ($a, $b, $d) = flat @arr[0,1], dist-squared(|@arr[0,1]);
while @arr {
my $p = pop @arr;
for @arr -> $l {

View file

@ -1,32 +1,33 @@
/*REXX program solves the closest pair of points problem in 2 dimensions*/
parse arg N low high seed . /*get optional arguments from CL.*/
if N=='' | N==',' then N=100 /*N not specified? Use default.*/
if low=='' | low==',' then low=0
if high=='' | high==',' then high=20000
if seed\==''& seed\==',' then call random ,,seed /*seed for repeatable.*/
/*REXX program solves the closest pair of points problem in two dimensions.*/
parse arg N low high seed . /*obtain optional arguments from the CL*/
if N=='' | N==',' then N=100 /*Not specified? Then use the default.*/
if low=='' | low==',' then low=0 /* " " " " " " */
if high=='' |high==',' then high=20000 /* " " " " " " */
if datatype(seed,'W') then call random ,,seed /*seed for RANDOM repeatable.*/
w=length(high); w=w + (w//2==0)
/*╔══════════════════════╗*/ do j=1 for N /*gen N random pts.*/
/*║ generate N points. ║*/ @x.j=random(low,high) /*random X.*/
/*╚══════════════════════╝*/ @y.j=random(low,high) /* " Y.*/
/*╔══════════════════════╗*/ do j=1 for N /*generate N random points. */
/*║ generate N points. ║*/ @x.j=random(low,high) /*a random X. */
/*╚══════════════════════╝*/ @y.j=random(low,high) /*" " Y. */
end /*j*/
A=1; B=2
minDD=(@x.A-@x.B)**2 + (@y.A-@y.B)**2 /*distance between 1st two points*/
minDD=(@x.A-@x.B)**2 + (@y.A-@y.B)**2 /*distance between first two points. */
do j=1 for N-1 /*find min distance between a ···*/
do k=j+1 to N /*point and all the other points.*/
do j=1 for N-1 /*find minimum distance between a ··· */
do k=j+1 to N /* ··· point and all the other points.*/
dd=(@x.j - @x.k)**2 + (@y.j - @y.k)**2
if dd\=0 then if dd<minDD then do; minDD=dd; A=j; B=k; end
end /*k*/
end /*j*/ /* [↑] when done, A & B are it*/
end /*j*/ /* [↑] when done, A & B are the ones*/
_= 'For ' N " points, the minimum distance between the two points: "
say _ center("x",w,'')" " center('y',w,"") ' is: ' sqrt(abs(minDD))
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 /*stick a fork in it, we're done.*/
/*──────────────────────────────────SQRT subroutine───────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); numeric form
numeric digits 11;p=d+d%4+2;parse value format(x,2,1,,0) 'E0' with g 'E' _ .
g=g*.5'E'_%2; m.=11; 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
_= 'For ' N " points, the minimum distance between the two points: "
say _ center("x",w,'')" " center('y',w,"") ' is: ' sqrt(abs(minDD))
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 /*stick a fork in it, we're all done. */
/*────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0 then return 0; d=digits(); i=; m.=9
numeric digits 9; numeric form; h=d+6; if x<0 then do; x=-x; i='i'; end
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*/
numeric digits d; return (g/1)i /*make complex if X < 0.*/