diff --git a/2025/ruby/day_09.rb b/2025/ruby/day_09.rb
new file mode 100644
index 0000000..8aabde3
--- /dev/null
+++ b/2025/ruby/day_09.rb
@@ -0,0 +1,30 @@
+tiles = DATA.read.lines.map { it.split(?,).map(&:to_i) }
+
+def area(a, b)
+ a.zip(b).map { (_1 - _2).abs + 1 }.inject(:*)
+end
+
+# part one
+sorted = tiles.combination(2).sort_by { -area(_1, _2) }
+pp area(*sorted.first)
+
+# part two
+edges = (tiles + [tiles.first]).each_cons(2)
+hedges, vedges = edges.partition { _1[0] == _2[0] }
+hedges = hedges.map {|(ay,ax),(_,bx)| [ay, Range.new(*[ax, bx].sort)] }
+vedges = vedges.map {|(ay,ax),(by,_)| [Range.new(*[ay, by].sort), ax] }
+
+pair = sorted.find {|pair|
+ ys, xs = pair.transpose.map(&:sort)
+ ys = (ys[0]+1..ys[-1]-1)
+ xs = (xs[0]+1..xs[-1]-1)
+
+ hedges.lazy.none? {|hy, hxs|
+ ys.cover?(hy) && xs.any? {|x| hxs.cover?(x) }
+ } && vedges.lazy.none? {|vys, vx|
+ xs.cover?(vx) && ys.any? {|y| vys.cover?(y) }
+ }
+}
+pp area(*pair)
+
+__END__