RosettaCodeData/Task/Heronian-triangles/Ruby/heronian-triangles.rb

47 lines
1.1 KiB
Ruby

class Triangle
def self.valid?(a,b,c) # class method
short, middle, long = [a, b, c].sort
short + middle > long
end
attr_reader :sides, :perimeter, :area
def initialize(a,b,c)
@sides = [a, b, c].sort
@perimeter = a + b + c
s = @perimeter / 2.0
@area = Math.sqrt(s * (s - a) * (s - b) * (s - c))
end
def heronian?
area == area.to_i
end
def <=>(other)
[area, perimeter, sides] <=> [other.area, other.perimeter, other.sides]
end
def to_s
"%-11s%6d%8.1f" % [sides.join('x'), perimeter, area]
end
end
max, area = 200, 210
prim_triangles = []
1.upto(max) do |a|
a.upto(max) do |b|
b.upto(max) do |c|
next if a.gcd(b).gcd(c) > 1
prim_triangles << Triangle.new(a, b, c) if Triangle.valid?(a, b, c)
end
end
end
sorted = prim_triangles.select(&:heronian?).sort
puts "Primitive heronian triangles with sides upto #{max}: #{sorted.size}"
puts "\nsides perim. area"
puts sorted.first(10).map(&:to_s)
puts "\nTriangles with an area of: #{area}"
sorted.each{|tr| puts tr if tr.area == area}