Add tasks for all the new languages

This commit is contained in:
Tina Müller 2016-12-05 23:44:36 +01:00
parent 9dc3c2bb62
commit bba7bfd280
13208 changed files with 134745 additions and 0 deletions

View file

@ -0,0 +1,104 @@
function bruteForceClosestPair(sequence s)
atom {x1,y1} = s[1], {x2,y2} = s[2], dx = x1-x2, dy = y1-y2, mind = dx*dx+dy*dy
sequence minp = s[1..2]
for i=1 to length(s)-1 do
{x1,y1} = s[i]
for j=i+1 to length(s) do
{x2,y2} = s[j]
dx = x1-x2
dx = dx*dx
if dx<mind then
dy = y1-y2
dx += dy*dy
if dx<mind then
mind = dx
minp = {s[i],s[j]}
end if
end if
end for
end for
return {sqrt(mind),minp}
end function
sequence testset = sq_rnd(repeat({1,1},10000))
atom t0 = time()
sequence points
atom d
{d,points} = bruteForceClosestPair(testset)
-- (Sorting the final point pair makes brute/dc more likely to tally. Note however
-- when >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.)
atom {{x1,y1},{x2,y2}} = sort(points)
printf(1,"Closest pair: {%f,%f} {%f,%f}, distance=%f (%3.2fs)\n",{x1,y2,x2,y2,d,time()-t0})
t0 = time()
constant X = 1, Y = 2
sequence xP = sort(testset)
function byY(sequence p1, p2)
return compare(p1[Y],p2[Y])
end function
sequence yP = custom_sort(routine_id("byY"),testset)
function distsq(sequence p1,p2)
atom {x1,y1} = p1, {x2,y2} = p2
x1 -= x2
y1 -= y2
return x1*x1 + y1*y1
end function
function closestPair(sequence xP, yP)
-- where xP is P(1) .. P(N) sorted by x coordinate, and
-- yP is P(1) .. P(N) sorted by y coordinate (ascending order)
integer N, midN, k, nS
sequence xL, xR, yL, yR, pairL, pairR, pairMin, yS, cPair
atom xm, dL, dR, dmin, closest
N = length(xP)
if length(yP)!=N then ?9/0 end if -- (sanity check)
if N<=3 then
return bruteForceClosestPair(xP)
end if
midN = floor(N/2)
xL = xP[1..midN]
xR = xP[midN+1..N]
xm = xP[midN][X]
yL = {}
yR = {}
for i=1 to N do
if yP[i][X]<=xm then
yL = append(yL,yP[i])
else
yR = append(yR,yP[i])
end if
end for
{dL, pairL} = closestPair(xL, yL)
{dR, pairR} = closestPair(xR, yR)
{dmin, pairMin} = {dR, pairR}
if dL<dR then
{dmin, pairMin} = {dL, pairL}
end if
yS = {}
for i=1 to length(yP) do
if abs(xm-yP[i][X])<dmin then
yS = append(yS,yP[i])
end if
end for
nS = length(yS)
{closest, cPair} = {dmin*dmin, pairMin}
for i=1 to nS-1 do
k = i + 1
while k<=nS and (yS[k][Y]-yS[i][Y])<dmin do
d = distsq(yS[k],yS[i])
if d<closest then
{closest, cPair} = {d, {yS[k], yS[i]}}
end if
k += 1
end while
end for
return {sqrt(closest), cPair}
end function
{d,points} = closestPair(xP,yP)
{{x1,y1},{x2,y2}} = sort(points) -- (see note above)
printf(1,"Closest pair: {%f,%f} {%f,%f}, distance=%f (%3.2fs)\n",{x1,y2,x2,y2,d,time()-t0})

View file

@ -0,0 +1,32 @@
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)

View file

@ -0,0 +1,71 @@
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(' ')})"

View file

@ -0,0 +1,20 @@
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))

View file

@ -0,0 +1,10 @@
# 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;

View file

@ -0,0 +1,53 @@
# 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])) ;

View file

@ -0,0 +1,13 @@
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