我正在浏览红宝石公案,我在151岁,我只是碰到了一堵砖墙。
这是公案:
# You need to write the triangle method in the file 'triangle.rb'
require 'triangle.rb'
class AboutTriangleProject2 < EdgeCase::Koan
# The first assignment did not talk about how to handle errors.
# Let's handle that part now.
def test_illegal_triangles_throw_exceptions
assert_raise(TriangleError) do triangle(0, 0, 0) end
assert_raise(TriangleError) do triangle(3, 4, -5) end
assert_raise(TriangleError) do triangle(1, 1, 3) end
assert_raise(TriangleError) do triangle(2, 4, 2) end
end
end
然后在triangle.rb中我们有:
def triangle(a, b, c)
# WRITE THIS CODE
if a==b && a==c
return :equilateral
end
if (a==b && a!=c) || (a==c && a!=b) || (b==c && b!=a)
return :isosceles
end
if a!=b && a!=c && b!=c
return :scalene
end
if a==0 && b==0 && c==0
raise new.TriangleError
end
end
# Error class used in part 2. No need to change this code.
class TriangleError < StandardError
end
我感到困惑 - 任何帮助都会非常感激!
编辑:要完成这个公案,我需要在TriangleError类中添加一些东西 - 但我不知道是什么更新:这是koan karma所说的:
<TriangleError> exception expected but none was thrown.
答案 0 :(得分:48)
您不需要更改TriangleError代码AFAICS。看起来你的语法有点古怪。尝试更改
raise new.TriangleError
到
raise TriangleError, "why the exception happened"
此外,您应该在对它们执行任何操作之前测试值(并抛出异常)。将异常内容移动到函数的开头。
答案 1 :(得分:30)
你忘了a,b或c是否定的情况:
def triangle(a, b, c)
raise TriangleError if [a,b,c].min <= 0
x, y, z = [a,b,c].sort
raise TriangleError if x + y <= z
[:equilateral,:isosceles,:scalene].fetch([a,b,c].uniq.size - 1)
end
答案 2 :(得分:11)
结束这样做:
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
感谢评论者:)
答案 3 :(得分:9)
我喜欢Cory的回答。但是我想知道,如果你有两个测试,有什么理由可以获得任何理由或什么:
raise TriangleError, "Sides must by numbers greater than zero" if (a <= 0) || (b <= 0) || (c <= 0)
raise TriangleError, "No two sides can add to be less than or equal to the other side" if (a+b <= c) || (a+c <= b) || (b+c <= a)
答案 4 :(得分:7)
您无需修改例外。这样的事情应该有效;
def triangle(*args)
args.sort!
raise TriangleError if args[0] + args[1] <= args[2] || args[0] <= 0
[nil, :equilateral, :isosceles, :scalene][args.uniq.length]
end
答案 5 :(得分:6)
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
答案 6 :(得分:4)
在尝试了解我必须用koan 151做什么之后,我在第一篇文章中得到了它,并且检查每个人的解决方案得到很多乐趣:) ...这是我的:
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是学习Ruby的一种非常有趣的方式
答案 7 :(得分:3)
你绝对不会更新Triangle Error类 - 我自己被困在152。我想我需要在这里使用pythag定理。
def triangle(a, b, c)
# WRITE THIS CODE
if a == 0 || b == 0 || c == 0
raise TriangleError
end
# The sum of two sides should be less than the other side
if((a+b < c) || (a+c < b) || (b+c < a))
raise TriangleError
end
if a==b && b==c
return :equilateral
end
if (a==b && a!=c) || (a==c && a!=b) || (b==c && b!=a)
return :isosceles
end
if(a!=b && a!=c && b!=c)
return :scalene
end
end
# Error class used in part 2. No need to change this code.
class TriangleError < StandardError
end
答案 8 :(得分:3)
我不认为我在这里看到这个。
我相信所有非法的三角形条件都意味着最长的一面不能超过总数的一半。即:
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
答案 9 :(得分:3)
我想要一个有效解析所有参数的方法,而不是依赖于测试断言中给出的顺序。
def triangle(a, b, c)
# WRITE THIS CODE
[a,b,c].permutation { |p|
if p[0] + p[1] <= p[2]
raise TriangleError, "Two sides of a triangle must be greater than the remaining side."
elsif p.count { |x| x <= 0} > 0
raise TriangleError, "A triangle cannot have sides of zero or less length."
end
}
if [a,b,c].uniq.count == 1
return :equilateral
elsif [a,b,c].uniq.count == 2
return :isosceles
elsif [a,b,c].uniq.count == 3
return :scalene
end
end
希望这有助于其他人意识到有一种方法可以给猫皮肤。
答案 10 :(得分:2)
您还可以尝试使用以下命令来实例:
raise TriangleError.new("All sides must be greater than 0") if a * b * c <= 0
答案 11 :(得分:2)
我最终得到了这段代码:
def triangle(a, b, c)
raise TriangleError, "impossible triangle" if [a,b,c].min <= 0
x, y, z = [a,b,c].sort
raise TriangleError, "no two sides can be < than the third" if x + y <= z
if a == b && b == c # && a == c # XXX: last check implied by previous 2
:equilateral
elsif a == b || b == c || c == a
:isosceles
else
:scalene
end
end
我不喜欢第二个条件/加注,但我不确定如何进一步改善它。
答案 12 :(得分:2)
实际上在以下代码中,条件a&lt; = 0是多余的。如果a&lt; a + b将始终小于c。 0,我们知道b&lt; ç
raise TriangleError if a <= 0 || a + b <= c
答案 13 :(得分:1)
这是我写的内容,一切正常。
def triangle(a, b, c)
# WRITE THIS CODE
raise TriangleError, "Sides have to be greater than zero" if (a == 0) | (b == 0) | (c == 0)
raise TriangleError, "Sides have to be a postive number" if (a < 0) | (b < 0) | (c < 0)
raise TriangleError, "Two sides can never be less than the sum of one side" if ((a + b) < c) | ((a + c) < b) | ((b + c) < a)
raise TriangleError, "Two sides can never be equal one side" if ((a + b) == c) | ((a + c) == b) | ((b + c) == a)
return :equilateral if (a == b) & (a == c) & (b == 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
答案 14 :(得分:1)
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
答案 15 :(得分:1)
不是这个问题需要另一个答案;但是,我认为这是最简单,最易读的解决方案。感谢我之前的所有人。
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
答案 16 :(得分:1)
#(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
答案 17 :(得分:1)
您必须检查新创建的三角形是否不会破坏“三角形不等式”。你可以通过这个小公式确保这一点。
if !((a-b).abs < c && c < a + b)
raise TriangleError
end
当您收到错误:
<TriangleError> exception expected but none was thrown.
在此文件中创建常规三角形时,您的代码可能会抛出异常。 about_triangle_project.rb
答案 18 :(得分:1)
这是我优雅的答案,在上面的评论中提供了很多帮助
def triangle(a, b, c)
test_tri = [a,b,c]
if test_tri.min <=0
raise TriangleError
end
test_tri.sort!
if test_tri[0]+ test_tri[1] <= test_tri[2]
raise TriangleError
end
if a == b and b == c
:equilateral
elsif a != b and b != c and a != c
:scalene
else
:isosceles
end
end
答案 19 :(得分:1)
对于Koan about_triangle_project_2.rb,无需更改TriangleError类。在三角形算法之前插入此代码以传递所有测试:
if ((a<=0 || b<=0 || c<=0))
raise TriangleError
end
if ((a+b<=c) || (b+c<=a) || (a+c<=b))
raise TriangleError
end
答案 20 :(得分:1)
这是我的版本......: - )
def triangle(a, b, c)
if a <= 0 || b <= 0 || c <= 0
raise TriangleError
end
if a + b <= c || a + c <= b || b + c <= a
raise TriangleError
end
return :equilateral if a == b && b == c
return :isosceles if a == b || a == c || b == c
return :scalene if a != b && a != c && b != c
end
答案 21 :(得分:1)
这个确实占用了一些大脑时间。但这是我的解决方案
def triangle(a, b, c)
# WRITE THIS CODE
raise TriangleError, "All sides must be positive number" if a <= 0 || b <= 0 || c <= 0
raise TriangleError, "Impossible triangle" if ( a + b + c - ( 2 * [a,b,c].max ) <= 0 )
if(a == b && a == c)
:equilateral
elsif (a == b || b == c || a == c)
:isosceles
else
:scalene
end
end
答案 22 :(得分:1)
这就是我最终的结果。它有点是上面几个例子的组合,我对三角不等式异常有独特的看法(它也考虑了退化情况)。似乎工作。
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
答案 23 :(得分:0)
最简单的解决方案!
def triangle(a, b, c)
#This would check for if the numbers are negative or 0.
if a <= 0 || b <= 0 || c <= 0
raise TriangleError
end
#This would check if the two sides of a triangle are greater than the remaining side.
if a + b <= c || a + c <= b || b + c <= a
raise TriangleError
end
if a == b && b = c
:equilateral
elsif a == b || a == c || b == c
:isosceles
else
:scalene
end
end
感谢所有美丽的人的回答,我已经检查了他们,我会说不需要更改 TriangleError 代码。我们需要检查无效的三角形,如果三角形不是,则引发错误。
答案 24 :(得分:0)
StackOverflow上有一些非常出色的人......我每次访问时都会想到这一点:D 只是为了对话,这是我提出的解决方案:
def triangle(a, b, c)
raise TriangleError if [a,b,c].min <= 0
x,y,z = [a,b,c].sort
raise TriangleError if x + y <= z
equal_sides = 0
equal_sides +=1 if a == b
equal_sides +=1 if a == c
equal_sides +=1 if b == c
# Note that equal_sides will never be 2. If it hits 2
# of the conditions, it will have to hit all 3 by the law
# of associativity
return [:scalene, :isosceles, nil, :equilateral][equal_sides]
end
答案 25 :(得分:0)
我的解决方案,我认为这是更易读的解决方案之一:
def triangle(a, b, c)
a, b, c = [a, b, c].sort
if a <= 0 or c >= a + b
raise TriangleError
end
case [a, b, c].uniq.length
when 1
:equilateral
when 2
:isosceles
when 3
:scalene
end
end
答案 26 :(得分:0)
您可以使用此公式并验证所有案例:
你的代码如下:
def triangle(a, b, c)
# Validate the triangle
raise TriangleError, "The triangle is not valid" unless (a + b) > c && (a + c) > b && (b + c) > a
if a === b && b === c
:equilateral
elsif a === b || a === c || b === c
:isosceles
else
:scalene
end
end
答案 27 :(得分:0)
这是我的解决方案: -
def triangle(a, b, c)
if a <= 0 || b <= 0 || c <= 0 || a + b <= c || a + c <= b || b + c <= a
raise TriangleError
elsif (a == b) &&( a==c) && (b==c)
return :equilateral
elsif (a==b) || (b==c) || (a==c)
return :isosceles
else
return :scalene
end
end
希望它有所帮助。
答案 28 :(得分:0)
错误检查试图达到三角形的标准:
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
有更优雅和简洁的方法来执行此错误检查,但我认为应该明确如何检查4个主要标准。 我实际上将2个标准卷入了一个检查。例如。没有边可能是负面的,没有边可能是0。
使用splat运算符作为参数是一种很好的方法来确保你有一个数组而没有明确地形成一个,但我不喜欢它,因为这意味着你还应该添加一个检查以确保有3个参数,这是隐含的。
答案 29 :(得分:0)
我能提出的最小解决方案。
这将通过测试,但是,如果阵列比它应该更长,它将不会抱怨。容易测试但似乎并不完全需要。
def(sides*)
splat(将输入转换为数组)raise TriangleError if ... or ...
如果两者都为真,则提出错误sides.sort!
对列表进行排序。这很重要,因为两个语句依赖于正在排序的列表,这意味着它只执行一次。sides.sort![0] <=0
获取最小元素,如果大于0,则所有其他元素都将为。sides.reverse.reduce(:-) >=0
最大元素减去较小的两个,如果超过0那么最大的一方比另外两个大。sides.uniq.size-1
获取唯一边数(减1) [:e,:i,:s].fetch(sides.uniq.size-1)
从数组中获取相应的元素(并返回)。
def triangle(*sides)
raise TriangleError if sides.sort![0] <=0 or sides.reverse.reduce(:-) >=0
[:equilateral, :isosceles, :scalene].fetch(sides.uniq.size - 1)
end
答案 30 :(得分:0)
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
答案 31 :(得分:0)
无需编写TriangleError方法。它说'不需要改变这个代码',所以我根本不会改变它。像我一样顽固。
4行拍摄它,很好干净。 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
答案 32 :(得分:0)
规则:
尺寸必须> 0
任何2个方面的总数,必须大于第3个
代码:
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)
答案 33 :(得分:0)
这是我的解决方案......老实说,我想不出更简洁,更易读的一个!
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
答案 34 :(得分:0)
Leon以优雅的姿态赢得了胜利,Benji凭借他对Array API的了解而获胜。这是我粗野的优雅答案:
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
答案 35 :(得分:0)
class TriangleError < StandardError
end
def triangle(x,y,z)
if(x>=y+z||y>=x+z||z>=x+y)
raise TriangleError,"impossible triangle"
elsif(x==0&&y==0&&z==0)||(x<0||y<0||z<0)
raise TriangleError,"length cannot be zero or negative"
elsif(x==y&&x==z)
:equilateral
elsif(x==y||y==z||x==z)
:isosceles
else
:scalene
end
end
答案 36 :(得分:0)
无需更改任何挑战的TriangleError代码。您只需检查无效三角形,如果三角形不是,则引发错误。
def triangle(a, b, c)
if a==0 && b==0 && c==0
raise TriangleError, "This isn't a triangle"
end
if a <0 or b < 0 or c <0
raise TriangleError, "Negative length - thats not right"
end
if a + b <= c or a + c <= b or b + c <= a
raise TriangleError, "One length can't be more (or the same as) than the other two added together. If it was the same, the whole thing would be a line. If more, it wouldn't reach. "
end
# WRITE THIS CODE
if a == b and b == c
return :equilateral
end
if (a==b or b == c or a == c)
return :isosceles
end
:scalene
end