2015-02-21 2 views
0

Я делаю программу в рубине, чтобы найти все основные факторы заданного числа. Я знаю, что Ruby имеет класс .Prime, но я бы хотел сделать это, не используя его.Использование modulo в диапазоне чисел в Ruby

Все работает хорошо, за исключением одного улова: я не могу найти способ запускать modulo в диапазоне чисел. Я попытался найти ответ в Интернете, в документации Ruby и более старых сообщениях здесь. До сих пор я ничего не нашел, что помогло.

Вот код:

def prime(n) 
    r = Range.new(2, n-1) 
    r.each { |x| puts x if n % x == 0 && x % (2..x-1) != 0} 
end 

print "Please enter a number: " 
prime(gets.chomp.to_i) 

EDIT: К сожалению, я, возможно, был расплывчатым. Этот бит кода:

x % (2..x-1) != 0 

Kicks обратно это:

euler2.rb:3:in `%': Enumerator can't be coerced into Fixnum (TypeError) 
     from euler2.rb:3:in `block in divisible' 
     from euler2.rb:3:in `each' 
     from euler2.rb:3:in `divisible' 
     from euler2.rb:7:in `<main>' 

Я гугле эту ошибку, но не повезло. Если я изменю код на не-диапазон, он будет работать.

+0

«Запустите modulo на ряд чисел», что вы имеете в виду? Кажется, вы уже это делаете. Каков ожидаемый результат? – jcm

+0

Думаю, я понял это сейчас. – jcm

+0

Просто подсказка, вам нужно только проверить sqrt (n), а не n. – Lesleh

ответ

2

Ваша логика неверна. Вы пытаетесь что-то гораздо проще, как:

def prime(n) 
    !(2..n-1).detect{|x| n%x == 0} 
end 

Здесь detect возвращает первое значение x что соответствует условию n%x == 0. Если не возвращается nil. Поэтому в случае простого номера (2..n-1).detect{|x| n%x == 0} вернется nil и ! сделает это true. Для составных чисел их младший делитель будет возвращен и ! сделает это false.

Что не так с кодом?

Вы делаете x % (2..x-1). Здесь (2..x-1) - это диапазон. Вы не можете делать по модулю Fixnum с Range. Таким образом, вы получите:

TypeError: Range can't be coerced into Fixnum 

Вы можете улучшить x % (2..x-1) использовать что-то вроде (2..x-1).each{|n| x%n} или любой другой Enumerator вместо each. Однако я по-прежнему считаю, что ваша логика слишком сложна или простая проблема.

0

Как насчет any??

def prime(n) 
    range = Range.new(2, n-1) 
    composite = range.any? { |i| n%i == 0 } 

    !composite 
end 

Конечно, это будет медленно для больших чисел.

Смежные вопросы