Понимание методов и сравнения - Найти простые числа - PullRequest
0 голосов
/ 08 ноября 2019

Я хотел бы задать несколько вопросов о поиске простых чисел. Следующий код прошел все тесты. Спасибо!

Решение: 1 - Вопрос: Несмотря на то, что он прошел все тесты, я повторяю «Это не простое число» дважды. Как я должен рефакторинг, чтобы включить num <= 1 внутри цикла while, чтобы мне не нужно было повторять: «Это не простое число? </strong>

def is_it_prime(num)
    return "This is not a prime number" if num <= 1
    n = 2
    while n < num
      return "This is not a prime number" if num % n == 0
      n += 1
    end
    return "This is a prime number"
end
  • check is_it_prime определено.
  • проверка количества аргументов
  • говорят, что 7 - это простое число
  • говорят, что 100 - это не простое число
  • говорят, что отрицательное число не является простымчисло
  • говорят, что 0 не является простым числом
  • говорят, что 1 не является простым числом
  • говорят, что 97 является простым числом

Решение -2: Для этого кода я хотел бы знать, почему num-1?

def is_it_prime(num)
    return "This is not a prime number" if num <= 1
    (2..(num - 1)).each {|n|return "This is not a prime number" if num % n == 0 }
end

Для этого кода я получаю ошибку для следующих двух значений:

puts is_it_prime(7) => 2..6
puts is_it_prime(97) => 2..96

Решение -3: Какой из них более эффективен? Как мне проверить? 2. .Math.sqrt (num) против 2 .. (num-1).

def is_it_prime(num)
    return "This is not a prime number" if num <= 1
    (2..Math.sqrt(num)).none? { |i| num % i == 0 }
    return "This is a prime number."
end
def is_it_prime(num)
    return "This is not a prime number" if num <= 1
    (2...(num -1)).all?{|m| num % m != 0 }
    return "This is a prime number."
end

Для этих двух наборов кодов я получаю одинаковую ошибку. Почему это дает этот результат

puts is_it_prime(100) => This is a prime number.

1 Ответ

2 голосов
/ 08 ноября 2019

Ваш второй код завершается ошибкой, потому что Ruby вернет значение последнего вычисленного выражения, если оно достигнет конца метода без обработки оператора return. Последнее выражение было (2..(num - 1)).each { ... }, а each возвращает объект, для которого он был вызван. Убедитесь, что вы возвращаете что-либо во время или после each.

Af для своего третьего кода, между all? { |a| a == b } и none? { a != b } нет никакой разницы в эффективности. Они полностью эквивалентны. Как поясняется в комментариях, тестирование до квадратного корня достаточно, а тестирование до n-1 является излишним. Но ошибка в том, что вы оцениваете, является ли что-то простым или нет, а затем отбрасываете эту информацию и печатаете "This is a prime number." независимо.

Чтобы не повторяться, вы можете сделать несколькоразные вещи. Отделите тест от печати:

def is_it_prime(num)
  return true if num <= 1
  n = 2
  limit = Math.sqrt(num)
  while n <= limit
    return false if num % n == 0
    n += 1
  end
  return true
end

def is_it_prime(num)
  if is_it_prime_for_real(num)
    return "This is a prime number"
  else
    return "This is not a prime number" 
  end
end

Выполните составной тест:

def is_it_prime(num)
  if num <= 1 or (2..Math.sqrt(num)).all? { |m| num % m != 0 }
    "This is not a prime number" 
  else
    "This is a prime number"
  end
end

Используйте константы, чтобы избежать дублирования литералов:

IS_PRIME = "This is a prime number"
IS_NOT_PRIME = "This is not a prime number"
def is_it_prime(num)
  return IS_NOT_PRIME if num <= 1
  return IS_PRIME if (2..Math.sqrt(num)).none? { |m| (num % m).zero? }
  IS_NOT_PRIME
end

...

...