Skip to content

Instantly share code, notes, and snippets.

@danneu
Created August 4, 2011 22:09
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danneu/1126423 to your computer and use it in GitHub Desktop.
Save danneu/1126423 to your computer and use it in GitHub Desktop.
Ruby Koans 151 triangle.rb solution
def triangle(a, b, c)
raise TriangleError if a<=0 or b<=0 or c<=0
raise TriangleError if a+b<=c or b+c<=a or a+c<=b
return :equilateral if a==b and a==c
return :isosceles if a==b or b==c or a==c
:scalene
end
@davidchambers
Copy link

I found it helpful to start with:

a, b, c = [a, b, c].sort

This simplifies matters quite a bit:

raise TriangleError unless a > 0
raise TriangleError unless a + b > c
return :equilateral if a == c
return :isosceles if a == b or b == c
:scalene

@danneu
Copy link
Author

danneu commented Oct 22, 2011

Nice, that's smart.

@ryan-miller
Copy link

I threw the arguments into an array to use the "uniq" method in helping find how many unique sides.

sides = []
sides << a << b << c
sorted_sides = sides.sort
unique_sides = sides.uniq.length
raise TriangleError unless sorted_sides.first > 0
raise TriangleError unless sorted_sides.first + sorted_sides.fetch(1) > sorted_sides.last
return :equilateral if unique_sides == 1
return :isosceles if unique_sides == 2
return :scalene

@danneu
Copy link
Author

danneu commented Apr 11, 2012

Cool. My effort to condense your solution:

def triangle(a, b,c)
  (a, b, c), uniq_sides = [a, b, c].sort, [a, b, c].uniq.size
  raise TriangleError unless a > 0 and a + b > c
  return :equilateral if uniq_sides == 1
  return :isosceles if uniq_sides == 2
  :scalene
end

I didn't like repeating [a, b, c] and the only one-liner idea I had was:

a, b, c, uniq_sides = [a, b, c].sort.tap { |sides| sides << sides.uniq.size } 

:/

@davidchambers
Copy link

Even better:

def triangle(a, b, c)
  a, b, c = sides = [a, b, c].sort
  raise TriangleError unless a > 0 and a + b > c
  {1 => :equilateral, 2 => :isosceles, 3 => :scalene}[sides.uniq.size]
end

Or even:

def triangle(a, b, c)
  a, b, c = sides = [a, b, c].sort
  raise TriangleError unless a > 0 and a + b > c
  [nil, :equilateral, :isosceles, :scalene][sides.uniq.size]
end

We're really streamlining this little chunk of code. :)

@danneu
Copy link
Author

danneu commented Apr 11, 2012

Nice. I get hung up on a tree instead of seeing the forest of refactoring.

I got rid of the nil, but at this rate we might as well rename sides to x. 😔

def triangle(a, b, c)
  a, b, c = sides = [a, b, c].sort
  raise TriangleError unless a > 0 and a + b > c
  [:scalene, :isosceles, :equilateral][-sides.uniq.size]
end

Until next time, team fistbump. 👊

@davidchambers
Copy link

Using a negative index – clever!

@rolandobrown
Copy link

Dan & David,

Hi. I'm Rolando. I'm a student at Flatiron School in NYC, and this exchange was super helpful in helping me figure a solution out.

Just wanted to say thanks!

@asyraffff
Copy link

Thanks for all of you guys

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment