题目要求很简单,写一个 triangle(a,b,c) 函数,判断是等边,等腰,或一般三角形,并且能在有一边小于等于零或两边之和小于第三边的情况下 raise 一个 error 普通 Ruby 程序员:
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
if a == b && b == c # && a == c
:equilateral
elsif a == b || b == c || c == a
:isosceles
else
:scalene
end
end
高端 Ruby 程序员:
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
再次验证了 Ruby 是一门优雅的语言啊。
triangle(A,B,C) ->
[X,Y,Z] = lists:sort([A,B,C]),
true = ((X+Y) > Z) and (X>0),
case [X,Y,Z] of
[X,X,X] -> equilateral;
[X,X,Z] -> isosceles;
[X,Y,Y] -> isosceles;
[X,Y,Z] -> scalene
end.
@zj0713001 你的意思是这样?
def triangle(a, b, c)
x, y, z = [a,b,c].sort
raise TriangleError if [x,y,z].min <= 0 || x + y <= z
[:equilateral,:isosceles,:scalene].fetch([a,b,c].uniq.size - 1)
end
就 3 个数比较,用?可读性还能接受的吧
def triangle(a, b, c)
x, y, z = [a,b,c].sort
raise TriangleError if x + y <= z || x <= 0
x == z ? :equilateral : (x == y || y == z ? :isosceles : :scalene)
end
普通的写成这样也不过多了一行而已,还好读好跑
def triangle(a, b, c)
raise TriangleError if a == 0 || b == 0 || c == 0
raise TriangleError if (a + b < c) || (a + c < b) || (b + c < a)
return :equilateral if a == b && b == c
return :isosceles if a == b || b == c || c == a
:scalene
end
高端的那个,创建了 4 个 array,min、sort、uniq 这些操作全都要遍历 array。 才 3 个元素可以不计较,但要是把这个当优雅,大的结构也这样用,那 vm 跑得再快也敌不过各种 O(n^x) x >= 2 的算法啊
In elixir,
triangle = fn [x,y,z] ->
case Enum.sort [x,y,z] do
[x,y,z] when (x+y<=z) or (x<0) -> raise "triangle error"
[x,x,x] -> :equilateral
[x,x,z] -> :isosceles
[x,y,y] -> :isosceles
[x,y,z] -> :scalene
end
end
IO.puts triangle.([3,4,5])
IO.puts triangle.([1,1,9]) # => error
refs bhuztez
数体教... 三角形的三个不等式其实已经蕴含了三条边都大于 0 的结论.(假设我们有 a + b > c
和 a + c > b
, 两式子相加,2a + b + c > b + c
, 约简就有 a > 0
).
另外 x == y
是可以重用的量哦。
def triangle a, b, c
raise TriangleError if a + b <= c or a + c <= b or b + c <= a
x, y, z = [a==b, b==c, c==a]
return :equilateral if x and y
return :isosceles if x or y or z
:scalene
end
cmp = [a==b, b==c, c==a]
return :e if cmp.inject :&
return :i if cmp.inject :|
return :s
补充:算法有错,旧帖保留是为了留着示众......
简洁并且容易理解的方式应该是这样吧
triangle(X,Y,Z) ->
case lists:usort([X,Y,Z]) of
[0|_] -> error;
[_A,_B] -> isosceles;
[_A] -> equilateral;
[A,B,C] when C >= A+B -> error;
_ -> scalene
end.
测试:
9> c(a).
{ok,a}
10> a:test().
1 2 3 error
1 3 3 isosceles
3 2 3 isosceles
3 3 3 equilateral
0 2 3 error
ok
#42 楼 @bhuztez 你说的对,我的算法思路有问题,应该在你的基础上改一下就行了
triangle(A,B,C) ->
[X,Y,Z] = lists:sort([A,B,C]),
true = ((X+Y) > Z) and (X>0),
case lists:usort([X,Y,Z]) of
[X] -> equilateral;
[_A,_B] -> isosceles;
_ -> scalene
end.
测试用例补充
12> a:test().
1 2 3 error
1 3 3 isosceles
1 1 3 error
3 2 3 isosceles
3 3 3 equilateral
0 2 3 error
ok
确实看了自叹不如加醍醐灌顶啊
而且这句:[:equilateral,:isosceles,:scalene].fetch([a,b,c].uniq.size - 1)
我很惭愧的没有看懂
def triangle(a, b, c): arr = [a,b,c] a, b, c = arr.sort() if a < 0 or a+b < c: raise Exception return ['equilateral','isosceles','scalene'][set(arr).size-1]
这样改代码,会不会太难看?
def triangle(a, b, c)
raise error if [a,b,c].min <= 0 or (a + b + c) <= 2 * [a,b,c].max
[:equilateral,:isosceles,:scalene].fetch([a,b,c].uniq.size - 1)
end