Posts: 0
Threads: 0
Joined: Sep 2017
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
Not that this question needed another answer; however, I think this is the simplest and most readable solution. Thanks to all those before me.
def triangle(a, b, c)
a, b, c = [a, b, c].sort
raise TriangleError, "all sides must > 0" unless [a, b, c].min > 0
raise TriangleError, "2 smaller sides together must the > 3rd side" unless a + b > c
return :equilateral if a == b && a == c
return :isosceles if a == b || a == c || b == c
return :scalene
end
# Error class used in part 2. No need to change this code.
class TriangleError < StandardError
end
|
Posts: 0
Threads: 0
Joined: Aug 2018
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
The error checking is trying to get at the criteria for a triangle:
if (a <= 0 || b <= 0 || c <= 0)
raise TriangleError,"All lengths must be positive"
end
args=[a,b,c].sort #this lets us get at the longest side of the triangle
unless ( args[0]+args[1] > args[2] )
raise TriangleError,"Longest length may not be greater than the sum of the other lengths"
end
if (args[0]-args[1] > args[2])
raise TriangleError,"Longest length must be greater than the difference of the other two lengths"
end
There are more elegant and concise ways to do this error checking but I think it should make clear how to check for the 4 major criteria are.
I actually rolled 2 criteria into a single check. E.g. no sides may be negative and no sides may be 0.
Using a splat operator for the arguments is a nice way to make sure you have an array without explicitly forming one, but I dislike it here because it means you should also add a check to make sure that there are exactly 3 arguments, which is implicit right now.
|
Posts: 0
Threads: 0
Joined: Apr 2021
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
Smallest solution I could come up with.
This will pass the tests, however, it will not complain if the array is longer than it should be. Easy to test for but didn't seem entirely needed.
0. `def(sides*)` splat (turn the input into an array)
0. `raise TriangleError if ... or ...` Raise the error if either are true
1. `sides.sort!` sort the list in place. This is important as two statements rely on the list being sorted and this means it is only done once.
2. `sides.sort![0] <=0` get the smallest element, if this is greater than 0 all the others will be.
2. `sides.reverse.reduce(:-) >=0` biggest element minus the smaller two, if this is over 0 then the largest side was bigger than the other two.
4. `sides.uniq.size-1` get the number of unique sides (minus one)
5. `[:e,:i,:s].fetch(sides.uniq.size-1)` get the appropriate element from the array (and return).
def triangle(*sides)
raise TriangleError if sides.sort![0] <=0 or sides.reverse.reduce(:-) >=0
[:equilateral, :isosceles, :scalene].fetch(sides.uniq.size - 1)
end
|
Posts: 0
Threads: 0
Joined: Nov 2022
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
def triangle(a, b, c)
raise TriangleError if [a, b, c].min <= 0
raise TriangleError if [a, b, c].max * 2 >= [a, b, c].reduce(:+)
if a == b && b == c
:equilateral
elsif a == b || b == c || c == a
:isosceles
else
:scalene
end
end
|
Posts: 0
Threads: 0
Joined: Feb 2022
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
No need to write the TriangleError method. It says 'No need to change this code', so I won't change it at all. Stubborn as I am.
4lines shot it, nice nd clean.
def triangle(a, b, c)
if(a * b * c <= 0) || (( (a + c)<=b) || ((a + b)<=c)||((b + c)<=a) )
raise TriangleError else
return ((a == b && b == c && a == c)? :equilateral:(((a == b)||(b == c)||(a == c))? :isosceles: :scalene))
end
end
# Error class used in part 2. No need to change this code.
class TriangleError < StandardError
end
|
Posts: 0
Threads: 0
Joined: Oct 2018
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
#(1)Any zero or -ve values
if [a,b,c].any? { |side_length| side_length <= 0 }
raise TriangleError
end
#(2)Any side of a triangle must be less than the sum of the other two sides
# a < b+c, b < a+c and c < a+b a valid triangle
# a >= b+c, b >= a+c and c >= a+b an invalid triangle
total_of_side_lengths = [a,b,c].inject {|total,x| total += x}
if [a,b,c].any? { |side_length| side_length >= (total_of_side_lengths - side_length)}
raise TriangleError
end
|
Posts: 0
Threads: 0
Joined: Oct 2022
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
Rules:
1. size must be > 0
2. Total of any 2 sides, must be bigger that the 3rd
Code:
raise TriangleError if ( [a,b,c].any? {|x| (x <= 0)} ) or ( ((a+b)<=c) or ((b+c)<=a) or ((a+c)<=b))
[:equilateral, :isosceles, :scalene].fetch([a,b,c].uniq.size - 1)
|
Posts: 0
Threads: 0
Joined: Sep 2020
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
Here's my solution... honestly I can't think of a more concise and readable one!
def triangle(a, b, c)
raise TriangleError unless a > 0 && b > 0 && c > 0
raise TriangleError if a == b && a + b <= c
raise TriangleError if a == c && a + c <= b
return :equilateral if a == b && b == c
return :isosceles if a == b || b == c || c == a
:scalene
end
|
Posts: 0
Threads: 0
Joined: Aug 2018
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
I don't think I see this one here, yet.
I believe all the illegal triangle conditions imply that the longest side can't be more than half the total. i.e:
def triangle(a, b, c)
fail TriangleError, "Illegal triangle: [#{a}, #{b}, #{c}]" if
[a, b, c].max >= (a + b + c) / 2.0
return :equilateral if a == b and b == c
return :isosceles if a == b or b == c or a == c
return :scalene
end
|
Posts: 0
Threads: 0
Joined: May 2020
Reputation:
0
Level: inf []
Total Points: inf
Rank nan / 1
100% to upload Level
Activity inf / 1
99% to upload your Rank
Experience nan
100% to upload Experience
Points: 50
|
After try to understand what I must to do with koan 151, I got it with the first posts, and get lot fun to check everyone solution :) ... here is the mine:
def triangle(a, b, c)
array = [a, b, c].sort
raise TriangleError if array.min <= 0 || array[0]+array[1] <= array[2]
array.uniq!
array.length == 1 ? :equilateral: array.length == 2 ? :isosceles : :scalene
end
Koan is a very interesting way to learn Ruby
|
|