I\'m going through the ruby koans, I\'m on 151 and I just hit a brick wall.
Here is the koan:
# You need to write the triangle method in the file \'trian
Ended up doing this:
def triangle(a, b, c)
a, b, c = [a, b, c].sort
raise TriangleError if a <= 0 || a + b <= c
[nil, :equilateral, :isosceles, :scalene][[a, b, c].uniq.size]
end
Thanks to commenters here :)
def triangle(a, b, c)
[a, b, c].permutation do |sides|
raise TriangleError unless sides[0] + sides[1] > sides[2]
end
case [a,b,c].uniq.size
when 3; :scalene
when 2; :isosceles
when 1; :equilateral
end
end
You shouldn't need to change the TriangleError code, AFAICS. Looks like your syntax is just a little wacky. Try changing
raise new.TriangleError
to
raise TriangleError, "why the exception happened"
Also, you should be testing the values (and throwing exceptions) before you do anything with them. Move the exception stuff to the beginning of the function.
This is what I ended up with. It is sort of a combination of a few of the above examples with my own unique take on the triangle inequality exception (it considers the degenerate case as well). Seems to work.
def triangle(a, b, c)
raise TriangleError if [a,b,c].min <= 0
raise TriangleError if [a,b,c].sort.reverse.reduce(:-) >= 0
return :equilateral if a == b && b == c
return :isosceles if a == b || a == c || b == c
return :scalene
end
Leon wins on fancy elegance, Benji for his knowledge the Array API. Here's my brute elegant answer:
def triangle(a, b, c)
[a, b, c].each { | side | raise TriangleError, "Sides must be positive" unless side > 0 }
raise TriangleError, "Two sides can never be less than or equal to third side" if ((a + b) <= c) | ((a + c) <= b) | ((b + c) <= a)
return :equilateral if (a == b) && (b == c)
return :isosceles if (a == b) || (b == c) || (a == c)
return :scalene
end
def triangle(a, b, c)
sides = a, b, c # Assigns variable signs (array) to all arguments.
begin
raise TriangleError if sides.inject(:+) <= 0 # Raise an error if all sides added together are less than or equal to 0. (the triangle would be invalid).
raise TriangleError if sides.any?(&:negative?) #Raise an error if there are any negative sides.
sides.each {|side| (side < (sides.inject(:+) - side) ? nil : (raise TriangleError))} # For the final check, Raise an error if any single side is greater than the other two sides added together. It can be broken down like this if side is less than (remaining sides - side we're comparing) raise an error, else, nil.
return :equilateral if sides.uniq.length == 1
return :isosceles if sides.uniq.length == 2
return :scalene if sides.uniq.length == 3
resuce TriangleError
end
end