2011-10-04 87 views
1

我是Ruby的新手。經過一番重構之後,我回到了這個位置。有沒有更好的方法來寫這個?在Ruby中寫這個更好的方法是什麼?

51 def tri_num?(n) 
52  i = 1 
53  while i < n 
54  return i if i * (i + 1)/2 == n 
55  i += 1 
56  end 
57  raise InvalidTree 
58 end 
+0

define'better'?你的意思是視覺上還是速度?因爲如果你關心的是後者,那麼while循環可能是最快的。我同意這不是太具有吸引力。查看Fixnum#次:'n.times {| i |返回我如果我*(i + 1)/ 2 == n'例如 –

回答

5

什麼直接解決了嗎?

def tri_num? n 

    i = (0.5*(-1.0 + Math.sqrt(1.0 + 8.0*n))).to_i 

    if i*(i+1)/2 == n 
    return i 
    else 
    raise InvalidTree 
    end 

end 

雖然我不知道tri_num?是不是一個好名字。通常以一個以?結尾的函數應該返回truefalse

+0

我不知道這個公式,任何參考? – CamelCamelCamel

+0

我只是做了一個小代數,並解決[二次方程](http://en.wikipedia.org/wiki/Quadratic_equation)我^ 2 +我 - 2 * n = 0。 – dantswain

+0

我希望我有數學技能。好的解決方案 – CamelCamelCamel

3

是的。

def tri_num?(n) 
    1.upto(n-1) do |i| 
    return i if i * (i + 1)/2 == n 
    end 
    raise InvalidTree 
end 
+0

+1 :)你打我幾秒 – Tilo

+2

這不是浪費週期嗎?說n是11,這不是一個三角形數字:這是直到第10個三角形數字是55,高於n。 – CamelCamelCamel

+0

我的算法與您最初在問題中發佈的算法基本相同,但它只是寫得更簡潔。您的算法具有相同的低效率。我注意到它,但沒有去改善它。在適當的時候發出「break」聲明會使該算法在引發異常的情況下更有效。 –

0
def tri_num?(n) 
    (1...n).each do |i| 
    return i if i * (i + 1)/2 == n 
    end 
    rails InvalidTree # not defined..            
end 
+0

是的..他想要做的是n-1 - 這就是'...'語法的作用,它不包括最終值。例如3個點,而不是2個 – Tilo

+0

嗯..這是一個錯字!感謝指出這一點..我打算當然鍵入「1」:-P – Tilo

2

我認爲一樣dantswain,基本上反轉公式:

=> i * (i + 1)/2 = n 
=> i * (i + 1) = 2*n 
=> i^2 + i = 2*n 
=> i^2 + i -2*n = 0 

而對於上述的解決方案是:

i = (-1 +- sqrt(1+8n))/2 

在這裏我不考慮-的解決方案,因爲它會給n大於0的任何值賦予負數,最後的代碼是:

def tri_num?(n) 
    i = (-1 + Math.sqrt(1 + 8*n))/2.0 
    return i.to_i if i == i.to_i 
    raise InvalidTree 
end 
相關問題