From 2384c5947440b9a49ecb5482e783d94d171830d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C8=98tefan-Iulian=20Alecu?= <165364995+pascalecu@users.noreply.github.com> Date: Wed, 13 May 2026 22:38:09 +0300 Subject: [PATCH] Add Convex Hull in Ruby --- archive/r/ruby/convex-hull.rb | 53 +++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 archive/r/ruby/convex-hull.rb diff --git a/archive/r/ruby/convex-hull.rb b/archive/r/ruby/convex-hull.rb new file mode 100644 index 000000000..13bc260aa --- /dev/null +++ b/archive/r/ruby/convex-hull.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +USAGE = 'Usage: please provide at least 3 x and y coordinates as separate lists (e.g. "100, 440, 210")' + +def usage! + warn USAGE + exit 1 +end + +def parse_list(str) + str.split(",").map { Integer(it.strip) } +rescue ArgumentError, NoMethodError + usage! +end + +def cross(o, a, b) + (a[0] - o[0]) * (b[1] - o[1]) - + (a[1] - o[1]) * (b[0] - o[0]) +end + +def build_hull(points) + hull = [] + + points.each do |p| + hull.pop while hull.size >= 2 && cross(hull[-2], hull[-1], p) <= 0 + hull << p + end + + hull +end + +def convex_hull(points) + points = points.sort + + lower = build_hull(points) + upper = build_hull(points.reverse) + + lower + upper[1..-2] +end + +x_str, y_str = ARGV +usage! if x_str.nil? || y_str.nil? + +x = parse_list(x_str) +y = parse_list(y_str) + +usage! if x.size != y.size || x.size < 3 + +points = x.zip(y) + +convex_hull(points).each do |x, y| + puts "(#{x}, #{y})" +end