2016-02-19 80 views
1

我想做一個沒有利用明顯的數學攻擊的篩子。我想強暴它。我的算法是基於這樣一個概念,即篩選器對很多不是素數的檢查進行了很多檢查,只是返回操作的結果來檢查這些數據,而不是找出素數。我認爲一些卡邁克爾數字證明它對於非常大的東西是無效的。我可能是錯的。我繼續檢查範圍內的數字,並遵循從Wikipedia給出的基本算法。Eratosthenes變體的篩選

def primes(n) 
    nums = (2..n) 
    not_prime = [] 
    primes = [] 
    nums.to_a.each_with_index do |it, idx| 
     primes << it unless not_prime.include?(it) 
     p primes.last 
     p nums.step(primes.last).to_a 
     nums.step(primes.last).each_with_index do |num, idx| 
     next if idx == 0 
     not_prime << num 
     end 
    end 

    primes 
end 

當我的範圍不會將一行:

nums.step(primes.last).each_with_index 

比第一個(2)等數字,我得到關閉的情況-X錯誤(配合名單,我相信上)。例如,找到所有非素數兩個倍數,但是對於三的倍數,範圍上的步驟返回2,5,811等,它們都是1。

我想弄清楚使用Range對象或轉換爲Array的解決方案,但我喜歡我的(錯誤的)解決方案的簡潔性。有人認爲他們可以幫我解決這個問題嗎?

編輯:

我修好了!該解決方案創建了一個全新的範圍來迭代,而不是採用原始範圍。見下文。向JörgW Mittag大聲呼喊,鼓勵創建一個新的範圍,而不是試圖擺弄我正在嘗試做的原始不變對象。有時候圓孔中的方形釘聽起來好多了。

def primes(n) 
    nums = (2..n) 
    not_prime = [] 
    primes = [] 
    nums.to_a.each_with_index do |it, idx| 
     next if not_prime.include?(it) 
     primes << it 
     ((primes.last)..n).step(primes.last).each_with_index do |num, idx| 
     next if idx == 0 || num == primes.last 
     not_prime << num 
     end 
    end 

    primes 
end 
+0

另一個解決方案是隻創建自己的自定義數據結構的房子我的Range對象並執行操作,但我喜歡用stdlib的項目和原語的人工挑戰...... – noname

+1

您遍歷範圍'2..n'在步驟'3'中,除了'2,5,8,...'之外還有什麼可能*? –

+0

我明白這是錯的。我該如何解決這個錯誤? – noname

回答

0
def primes(n) 
    nums = (2..n) 
    not_prime = [] 
    primes = [] 
    nums.to_a.each_with_index do |it, idx| 
     next if not_prime.include?(it) 
     primes << it 
     ((primes.last)..n).step(primes.last).each_with_index do |num, idx| 
     next if idx == 0 || num == primes.last 
     not_prime << num 
     end 
    end 

    primes 
end