Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

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