0
\$\begingroup\$

This challenge I am working on involves checking the sides of a triangle and returning the type of triangle as a symbol.

For example, :equilateral if all sides are equal, :scalene if the sides are all different, and :isoseles if two sides are the same.

Here is my thought process: I want to make something that doesn't involve a bunch of if/else or case statements. To achieve this, I thought that using math would help. Now, my math isn't that great, so I had to research cosine and make an algorithm to return angles A,B, and C.

First, I know this isn't required. I don't need the angles, but I thought it would help me avoid too many statements. However, I couldn't figure out what to do after this step.

Below is my code. It works, but I feel like it's kind of tacky. I know I could do better, but I'm facing a wall here. Any input?

def triangle(one, two, three)
  is_valid_triangle?(one,two,three)
end

def is_valid_triangle?(one,two,three)
  sides = [one,two,three].sort
  if (sides[0] + sides[1] <= sides[2]) || (sides[0] == 0)
    return "invalid!"
  else
    which_triangle?(one,two,three)
  end
end

def which_triangle?(one,two,three)
  triangles = {equilateral: [60,60,60], isosceles: [0], scalene: [0]}
  angle_a = (Math.acos((two**2+three**2-one**2)/(2*two*three).to_f)*180/Math::PI).round(2)
  angle_b = (Math.acos((three**2+one**2-two**2)/(2*three*one).to_f)*180/Math::PI).round(2)
  angle_c = (Math.acos((one**2+two**2-three**2)/(2*one*two).to_f)*180/Math::PI).round(2)
  if angle_a && angle_b == 60
    return :equilateral, triangles[:equilateral]
  elsif angle_a != angle_b && angle_b != angle_c
    triangles[:scalene] = [angle_a, angle_b, angle_c]
    return :scalene, triangles[:scalene]
  else
    triangles[:isosceles] = [angle_a, angle_b, angle_c]
    return :isosceles, triangles[:isosceles]
  end
end

p triangle(30,23,10)
p triangle(3,3,3)
p triangle(1.5,3,3)
p triangle(3,4,5)
p triangle(0,3,3)
p triangle(3,1,1)
\$\endgroup\$
5
  • 2
    \$\begingroup\$ You seriously think this looks simpler than checking lengths of three sides? It probably takes two lines of code to do it. \$\endgroup\$ Commented Oct 28, 2017 at 5:09
  • 2
    \$\begingroup\$ If a==b and b==c: return type1 elif a==b or b==c or a==c: return type2 return type3 \$\endgroup\$ Commented Oct 28, 2017 at 5:13
  • \$\begingroup\$ @Stackcrashed I understand that my way isn't simpler, I'm just trying to figure out a better way to do it without using if, elif statements. Unless there isn't any better way to do it. \$\endgroup\$
    – Nathan
    Commented Oct 29, 2017 at 1:20
  • \$\begingroup\$ Please see What to do when someone answers. I have rolled back Rev 3 → 2. \$\endgroup\$ Commented Oct 29, 2017 at 2:55
  • 2
    \$\begingroup\$ Note that @Stackcrashed's method works without elif since you are doing an early return. \$\endgroup\$
    – user1149
    Commented Oct 29, 2017 at 16:56

1 Answer 1

2
\$\begingroup\$

For triangle(3, 2, 3), the resulting classification is wrong:

[:scalene, [70.53, 38.94, 70.53]]

When you take into consideration all of the different pairs of angles you have to test, you are no better off comparing angles than comparing side lengths. In fact, this approach is worse, with extra computation and loss of precision due to rounding.

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.