Skip to content

Commit 697375e

Browse files
authored
Add Convex Hull in Ruby (#5937)
1 parent dbe8842 commit 697375e

1 file changed

Lines changed: 53 additions & 0 deletions

File tree

archive/r/ruby/convex-hull.rb

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# frozen_string_literal: true
2+
3+
USAGE = 'Usage: please provide at least 3 x and y coordinates as separate lists (e.g. "100, 440, 210")'
4+
5+
def usage!
6+
warn USAGE
7+
exit 1
8+
end
9+
10+
def parse_list(str)
11+
str.split(",").map { Integer(it.strip) }
12+
rescue ArgumentError, NoMethodError
13+
usage!
14+
end
15+
16+
def cross(o, a, b)
17+
(a[0] - o[0]) * (b[1] - o[1]) -
18+
(a[1] - o[1]) * (b[0] - o[0])
19+
end
20+
21+
def build_hull(points)
22+
hull = []
23+
24+
points.each do |p|
25+
hull.pop while hull.size >= 2 && cross(hull[-2], hull[-1], p) <= 0
26+
hull << p
27+
end
28+
29+
hull
30+
end
31+
32+
def convex_hull(points)
33+
points = points.sort
34+
35+
lower = build_hull(points)
36+
upper = build_hull(points.reverse)
37+
38+
lower + upper[1..-2]
39+
end
40+
41+
x_str, y_str = ARGV
42+
usage! if x_str.nil? || y_str.nil?
43+
44+
x = parse_list(x_str)
45+
y = parse_list(y_str)
46+
47+
usage! if x.size != y.size || x.size < 3
48+
49+
points = x.zip(y)
50+
51+
convex_hull(points).each do |x, y|
52+
puts "(#{x}, #{y})"
53+
end

0 commit comments

Comments
 (0)