2013-12-23 3 views
0
def isPrime?(num) 

    i = 2 

    @isFalse = 0 

    while i < num 
     divisible = ((num % i) == 0) 
     if divisible 
      @isFalse += 1 
      return false 
     end 
     i += 1 
    end 
    true 
end 

def primes(max) 
    startTime = Time.now 
     (2..max).each do |p| 
      puts "#{p} #{isPrime?(p)}" 
     end 
    endTime = Time.now 

    puts "--------------------------------------------------" 
    puts " FALSE values in range from (2 thru #{max}): #{@isFalse} \n TRUE values in range from (2 thru #{max}): #{[email protected]}" 
    puts "\nTotal time to calculate is #{endTime - startTime} seconds!" 
end 

primes(10) 

isPrime? проверяет, является ли данное число простым числом. primes загружает ряд чисел и проверяет, является ли каждое из них простым.Ошибка синтаксиса? Ошибка Ruby? Ошибка с приращением экземпляра с + = 1?

Я хочу знать, сколько чисел является простым в пределах диапазона и сколько их нет.

Я добавил @isFalse += 1 мышление Я могу увеличивать каждый раз при возврате false, чтобы я мог определить, сколько чисел в диапазоне ложных, и использовать это для вычитания из max, чтобы узнать, сколько чисел истинно.

Весь код работает правильно, за исключением того, что @isFalse неправильно увеличивается. Почему это? Спасибо за помощь.

--UPDATE--
Мой выход: добавлены puts "About to increment @isFalse" до того @isFalse += 1

2 true 
3 true 
About to increment @isFalse 
4 false 
5 true 
About to increment @isFalse 
6 false 
7 true 
About to increment @isFalse 
8 false 
About to increment @isFalse 
9 false 
About to increment @isFalse 
10 false 
-------------------------------------------------- 
    FALSE values in range from (2 thru 10): 1 
    TRUE values in range from (2 thru 10): 8 
+0

Быстрая проверка отладки: напечатайте что-то перед линией '@isFalse + = 1' (например,' puts "About increment @isFalse" '). Это должно помочь определить проблему. – Alec

+0

Следующее ваше предложение действительно выводит строку 5 раз 'puts 'About to increment @isFalse'' – fyz

+0

@alecbenzer любое другое предложение? Я здесь. – fyz

ответ

0

@isFalse = 0 есть внутри ваш isPrime? способ. Вытащите это оттуда!

+0

Как вы предлагаете инициализировать его? Если это не так, я получаю неопределенную ошибку. Пожалуйста, объясни. – fyz

+0

Буквально вне метода (и пока вы на нем, переименуйте его в 'non_prime_count' или somesuch). – steenslag

+0

Отлично. Теперь я вижу свою ошибку. Кстати, именование происходит потому, что у меня были '@ isFalse' и' @ isTrue' - я решил, что это было излишним, поэтому я изменил только для '@ isFalse'. Короче говоря, я собирался изменить название на что-то более четкое, как вы предложили. Я вижу свою ошибку. Наличие '@ isFalse' в методе было проблемой, хотя и не в' while', потому что метод 'prime' вызывал его с каждым последующим числом. Вот почему я бы получил только одно ложное, которое применялось к последнему вызову метода 'prime'. Спасибо, ваш единственный лайнер был именно тем, что доктор заказал! :) Спасибо! – fyz

1

кажется, что вы пытаетесь выяснить количество простых чисел в этом диапазоне с помощью @isFalse. Если это так, вы должны использовать следующую модификацию своего кода (хотя я не рекомендую проверять простые числа таким образом, а код действительно неэффективен):

В принципе, я удалил переменную экземпляра @isFalse в целом, и проверил, является ли число простым или нет во втором методе. Этот код намного чище, и действительно делает то, что вы намерены ему делать.

Проблема с кодом, что @isFalse это сбрасывается в 0 каждый раз ваш первый метод isPrime? был называться, и, следовательно, не отражает количество простых чисел в заданном диапазоне.

def isPrime?(num) 
    i = 2 
    while i < num 
     divisible = ((num % i) == 0) 
     return false if divisible 
     i += 1 
    end 
    true 
end 

def primes(max) 
    startTime = Time.now 
     is_prime = 0 
     (2..max).each do |p| 
      if isPrime?(p) 
       is_prime += 1 
       puts p 
     end 
    endTime = Time.now 

    puts "--------------------------------------------------" 
    puts " FALSE values in range from (2 thru #{max}): #{is_prime} \n TRUE values in range from (2 thru #{max}): #{max-1-is_prime}" 
    puts "\nTotal time to calculate is #{endTime - startTime} seconds!" 
end 

primes(10) 
2

Каждый раз, когда вызывается isPrime?, @isFalse сбрасывается в 0. Таким образом, результат @isFalse равно 1 от последнего времени isPrime? был назван (с num равным 10, увеличивающимся @isFalse до 1).

1

Как ваш вопрос был дан ответ, я хотел бы предложить более рубин, как решение:

Вы хотите метод is_prime? не делать ничего другого, кроме определения, если num простое:

def is_prime?(num) 
    (2...num).each {|i| return false if num % i == 0} 
    true 
end 

Сделайте свой подсчет простых чисел по методу nbr_primes.

def nbr_primes(max) 
    return false if max < 2 
    (2..max).reduce(0) {|tot, i| tot + (is_prime?(i) ? 1 : 0)} 
end 

p nbr_primes(20) # => 8 

Несколько моментов:

  • я удалил ссылки на время и выход форматирования, поскольку они не являются центральными к этому вопросу.
  • Это конвенция Ruby, чтобы назвать методы с строчными буквами и символами подчеркивания.
  • (2...num), поскольку он имеет три точки, представляет собой последовательность от 2 до (и включая) num - 1. Вместо этого мы могли бы написать (2..num-1) (две точки), которым пользуются некоторые.
  • (2..max).reduce(0) {|tot, i|...} Итерации свыше i от 2 до 0 включительно max. tot, который является аккумулятором reduce, увеличивается на 1 для каждого номера от 2 до max, что считается простым. Выражение возвращает значение tot, которое, в свою очередь, возвращается методом nbr_primes. inject является синонимом для reduce.
  • При проверке, является ли число n простым, вам нужно только проверить, делится ли его номерами по номерам до Math.sqrt(n).to_i.
  • С require 'prime' вам не нужно изобретать велосипед. Например, Prime.prime?(7) #=> true и Prime.take_while {|p| p <= 10}.size #=> [2, 3, 5, 7].size + 1 # => 4.
+0

Спасибо, что нашли время ответить. Я считаю эту информацию очень полезной. Я ценю ваши знания. Спасибо. – fyz

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