2012-05-18 33 views
1

所面臨的挑戰是找到的最小整數foo,其中:Ruby:枚舉器不能被強制轉換爲Fixnum;與項目歐拉#奮力5

foo % 1..20 == 0 

我現在的嘗試是蠻力

until foo % 1.upto(20) == 0 do 
    foo++ 
end 

此輸出錯誤unexpected keyword end。但是,如果我不將end關鍵字放入irb中,代碼永遠不會運行,因爲該塊未關閉。

我做了一個空的測試案例,看看我的錯誤奠定

until foo % 1.upto(20) == 0 do 
end 

這將引發新的錯誤:enumerator can't be coerced to a fixnum。我想這意味着你不能直接在一個範圍上執行模數,並期望整個範圍的整數布爾結果。但我不知道該從哪裏出發。

我第一次嘗試的東西更高效/優雅/到了點forewent贊成嘗試蠻力如下:

foo = 1 
1.upto(20) {|bar| foo *= bar unless foo % i == 0} 

給出了錯誤的答案。我不明白爲什麼,但我也有興趣爲什麼

foo = 1 
20.downto(1) {|bar| foo *= bar unless foo % i == 0} 

輸出一個不同的答案。

編輯:我會用於循環(我用腳本編寫了ActionScript腳本)但他們不工作我期望在紅寶石。

+3

foo ++不能像Ruby中預期的那樣工作。你需要寫foo + = 1 – OzBandit

+0

@David:這是我最不喜歡的語言功能... – sarnold

+0

@sarnold最不喜歡的是你希望它是在Ruby中,還是你不喜歡它在其他語言?它在Ruby中並不真正有意義(或者一般來說也可能是OO),因爲數字不可變,因此'++'會涉及隱藏的賦值。 –

回答

0

如果這是我,我會定義一個函數來測試條件:

def mod_test(num) 
    test = (1..20).map {|i| num % i == 0} 
    test.all? # all are true 
end 

,然後一個循環來嘗試不同的值:

foo = 20 
until mod_test(foo) do 
    foo += 20 
end 

(感謝Dylan+= 20加速。)

我敢肯定,有一個聰明的方法來使用foo % 10 == 0的知識也暗示foo % 5 == 0一個d foo % 2 == 0,並且只對120之間的素數執行測試,甚至可能使用該信息直接構建數字 - 但我的代碼運行得足夠快。

+0

您實際上可以只是測試11..20。如果20有效,那麼10;如果18工作,那麼9;等等。 –

+0

@Dylan:將運行時間減半的優秀點。 (函數調用將阻止它完全是一半。)很好。 :) – sarnold

+0

@迪蘭你有有趣的優化。我的工作讓我瞭解每個人的意見。 – ac7v

2

試試這個:

until 1.upto(20).reject{|i| foo % i == 0 }.empty? do 
    foo += 1 
end 
+1

由於它必須可以被20整除,所以你可以從'foo = 20'開始,每次加20而不是1 –

+0

好主意,因爲我放棄了'foo = 17740946'。 :) – sarnold

+0

我沒有試圖改進解決ProjectEuler問題的答案 - 我只是提供了一個正確的語法嘗試解決方案 – PinnyM

3

你的第一個解決方案是錯誤的,因爲1.upto(20)枚舉,也就是說,基本上在值1到20的迭代器,它不能被用作一個數模或與另一個數字比較,因爲它本身不是一個數字。

你真的需要兩個「環」在這裏:

foo = 1 
foo += 1 until (1..20).all? { |i| foo % i == 0 } 

第一循環是until,然後all?是各種各樣的另一環,因爲它確保了塊({ |i| foo % i == 0 })是真調用範圍內的每個元素((1..20))。請注意,我使用了一個線「向後」語法(這也適用於ifunlesswhile,...)以上-the等同於:

foo = 1 
until (1..20).all? { |i| foo % i == 0 } do 
    foo += 1 
end 
# foo => 232792560 

此外,這是令人難以置信的效率低下,項目歐拉通常涉及到比編程更多的數學,非暴力解決方案可能涉及更多數學,但速度更快。

+0

儘管我想爲這些「優雅」問題提供解決方案,但至今我只能管理「雜亂」。發佈這個問題後,我想出了一個不同的方法,我試圖將一些代碼片段打成形。這至少是一個高於蠻力的步驟,我認爲它會起作用,但我需要所有的幫助,才能理解錯誤的地方。有趣的部分是這花了幾個小時後,這傷害了我的頭,增加了我的基本能力。啓發性部分是在閱讀其他人的(更好的)解決方案。感謝您爲此提供的幫助。 – ac7v

2

我知道這不是直接的OP的問題,但是這是比較容易的方式實現與剛:

puts (1..20).reduce(:lcm) 

它是如此簡單,它好像是不公平的解決是這樣,但是這正是爲什麼Ruby是我歐拉項目的首選語言。

另請參見this question

相關問題