我一直在研究Ruby Koans,并将其发送到about_triangle_project.rb,在其中您需要编写方法三角形的代码.
这些项目的代码可在此处找到:
https://github.com/edgecase/ruby_koans/blob/master/koans/about_triangle_project.rb
https://github.com/edgecase/ruby_koans/blob/master/koans/triangle.rb
在triangle.rb中,我创建了以下方法:
def triangle(a, b, c)
if ((a == b) && (a == c) && (b == c))
return :equilateral
elsif ((a == b) || (a == c) || (b == c))
return :isosceles
else
return :scalene
end
end
Run Code Online (Sandbox Code Playgroud)
我从阅读克里斯·派恩的"学会计划"中了解到,总有不止一种方法可以做.虽然上面的代码有效,但我不禁想到有一种更优雅的方式.是否有人愿意提出他们如何使这种方法更有效和紧凑的想法?
我很好奇的另一件事是,为了确定等边三角形,我无法创造(a == b == c)的条件.它是等边三角形的证明,但Ruby讨厌语法.有一个简单的解释,为什么这是?
Chu*_*uck 55
有一个简单的解释为什么:
==
在Ruby中是一个执行特定功能的运算符.操作员有规则来确定他们应用的顺序 - 例如,a + 2 == 3
在等式检查之前评估添加.但是一次只评估一个操作员.将两个相等性检查彼此相邻是没有意义的,因为相等性检查的计算结果为true
或false
.有些语言允许这样做,但它仍然不工作的权利,因为那时你会评估true == c
,如果a
和b
是相等的,这显然是不正确的,即使一个== b ==下,在数学术语.
至于更优雅的解决方案:
case [a,b,c].uniq.size
when 1 then :equilateral
when 2 then :isosceles
else :scalene
end
Run Code Online (Sandbox Code Playgroud)
或者,甚至更简洁(但不太可读):
[:equilateral, :isosceles, :scalene].fetch([a,b,c].uniq.size - 1)
Run Code Online (Sandbox Code Playgroud)
小智 11
另一种方法:
def triangle(a, b, c)
a, b, c = [a, b, c].sort
raise TriangleError if a <= 0 or a + b <= c
return :equilateral if a == c
return :isosceles if a == b or b == c
return :scalene
end
Run Code Online (Sandbox Code Playgroud)
def triangle(a, b, c)
if a == b && a == c # transitivity => only 2 checks are necessary
:equilateral
elsif a == b || a == c || b == c # == operator has the highest priority
:isosceles
else
:scalene # no need for return keyword
end
end
Run Code Online (Sandbox Code Playgroud)
我借用了Chuck的酷炫uniq.size技术并将其用于oo解决方案.最初我只想提取参数验证作为保护条款以维护单一责任原则,但由于两种方法都在相同的数据上运行,我认为它们属于一个对象.
# for compatibility with the tests
def triangle(a, b, c)
t = Triangle.new(a, b, c)
return t.type
end
class Triangle
def initialize(a, b, c)
@sides = [a, b, c].sort
guard_against_invalid_lengths
end
def type
case @sides.uniq.size
when 1 then :equilateral
when 2 then :isosceles
else :scalene
end
end
private
def guard_against_invalid_lengths
if @sides.any? { |x| x <= 0 }
raise TriangleError, "Sides must be greater than 0"
end
if @sides[0] + @sides[1] <= @sides[2]
raise TriangleError, "Not valid triangle lengths"
end
end
end
Run Code Online (Sandbox Code Playgroud)
小智 5
class TriangleError < StandardError
end
def triangle(a, b, c)
sides = [a,b,c].sort
raise TriangleError if sides.first <= 0 || sides[2] >= sides[1] + sides[0]
return :equilateral if sides.uniq.length == 1
return :isosceles if sides.uniq.length == 2
:scalene
end
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9279 次 |
最近记录: |