new tasks
This commit is contained in:
parent
2a4d27cea0
commit
80737d5a6a
1194 changed files with 15353 additions and 1 deletions
68
Task/Closest-pair_problem/Ruby/closest_pair_problem.rb
Normal file
68
Task/Closest-pair_problem/Ruby/closest_pair_problem.rb
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
Point = Struct.new(:x, :y)
|
||||
|
||||
def distance(p1, p2)
|
||||
Math.hypot(p1.x - p2.x, p1.y - p2.y)
|
||||
end
|
||||
|
||||
def closest_bruteforce(points)
|
||||
mindist, minpts = Float::MAX, []
|
||||
points.length.times do |i|
|
||||
(i+1).upto(points.length - 1) do |j|
|
||||
dist = distance(points[i], points[j])
|
||||
if dist < mindist
|
||||
mindist = dist
|
||||
minpts = [points[i], points[j]]
|
||||
end
|
||||
end
|
||||
end
|
||||
[mindist, minpts]
|
||||
end
|
||||
|
||||
def closest_recursive(points)
|
||||
if points.length <= 3
|
||||
return closest_bruteforce(points)
|
||||
end
|
||||
xP = points.sort_by {|p| p.x}
|
||||
mid = (points.length / 2.0).ceil
|
||||
pL = xP[0,mid]
|
||||
pR = xP[mid..-1]
|
||||
dL, pairL = closest_recursive(pL)
|
||||
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|
|
||||
break if (yP[k].y - yP[i].y) >= dmin
|
||||
dist = distance(yP[i], yP[k])
|
||||
if dist < closest
|
||||
closest = dist
|
||||
closestPair = [yP[i], yP[k]]
|
||||
end
|
||||
end
|
||||
end
|
||||
if closest < dmin
|
||||
[closest, closestPair]
|
||||
else
|
||||
[dmin, dpair]
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
points = Array.new(100) {Point.new(rand, rand)}
|
||||
p ans1 = closest_bruteforce(points)
|
||||
p ans2 = closest_recursive(points)
|
||||
fail "bogus!" if ans1[0] != ans2[0]
|
||||
|
||||
require 'benchmark'
|
||||
|
||||
points = Array.new(10000) {Point.new(rand, rand)}
|
||||
Benchmark.bm(12) do |x|
|
||||
x.report("bruteforce") {ans1 = closest_bruteforce(points)}
|
||||
x.report("recursive") {ans2 = closest_recursive(points)}
|
||||
end
|
||||
Loading…
Add table
Add a link
Reference in a new issue