Ruby - Determine If a Number Is a Prime

Ruby - determine if a number is a prime

It's because = is of higher precedence than or. See Ruby's operator precedence table below (highest to lowest precedence):

[ ] [ ]=
**
! ~ + -
* / %
+ -
>> <<
&
^ |
<= < > >=
<=> == === != =~ !~
&&
||
.. ...
? :
= %= { /= -= += |= &= >>= <<= *= &&= ||= **=
defined?
not
or and
if unless while until
begin/end

The problematic line is being parsed as...

(foundDivider = ((n % d) == 0)) or foundDivider

...which is certainly not what you mean. There are two possible solutions:

Force the precedence to be what you really mean...

foundDivider = (((n % d) == 0) or foundDivider)

...or use the || operator instead, which has higher precedence than =:

foundDivider = ((n % d) == 0) || foundDivider

Ruby Prime number program

Let's calculate the square root of 7 (a prime number) and 8 (a composite number):

Math.sqrt(7) #=> 2.6457513110645907
Math.sqrt(8) #=> 2.8284271247461903

This doesn't really help, does it? Apparently, you can't determine if a number is a prime number by calculating its square root.

Instead, you have to check the number's divisors. From Wikipedia:

A prime number (or a prime) is a natural number greater than 1 that has no positive divisors other than 1 and itself.

Let's determine the divisors of 7: (using the modulo operator %)

7 % 1 #=> 0 <- 7 is divisible by 1
7 % 2 #=> 1
7 % 3 #=> 1
7 % 4 #=> 3
7 % 5 #=> 2
7 % 6 #=> 1
7 % 7 #=> 0 <- 7 is divisible by 7

This satisfies the above definition - 7 is a prime number.

Now, let's determine the divisors of 8:

8 % 1 #=> 0 <- 8 is divisible by 1
8 % 2 #=> 0 <- 8 is divisible by 2
8 % 3 #=> 2
8 % 4 #=> 0 <- 8 is divisible by 4
8 % 5 #=> 3
8 % 6 #=> 2
8 % 7 #=> 1
8 % 8 #=> 0 <- 8 is divisible by 8

8 has two additional divisors 2 and 4. Therefore, 8 is not a prime number.

In Ruby, you could use select to find the divisors:

(1..7).select { |d| 7 % d == 0 } #=> [1, 7]
(1..8).select { |d| 8 % d == 0 } #=> [1, 2, 4, 8]

Finally, here's a variant of your Ruby code that checks if a given number num has exactly two divisors, 1 and num itself:

prime_array = []

(1...100).each do |num|
if (1..num).select { |d| num % d == 0 } == [1, num]
prime_array.push(num)
end
end

prime_array
#=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

The above code can be optimized. I leave that to you.

Checking for prime number in ruby

The proximate issue you are facing is, this is not valid Ruby: (counter == Math.sqrt(num).ceil) ? "false"

?, as an operator, is a part of the trinary operator ... ? ... : ..., and always comes in pair with a :, as you write in your next line. Then again, overuse of trinary operator is also not good. You also have a problem with control flow: after evaluating "true", the loop will continue, counter won't change, and you got an infinite loop.

I suggest you work out what the algorithm should be. Write it in English, if necessary. Then make sure you convert it to Ruby correctly.

Also, Ruby methods should be in snake case (lowercase with underscores between words), so PrimeTime is not a good name. I suggest prime? (as question marks are also allowed in identifiers) if you will be returning a boolean value (true or false). If you are returning a string (as you seem to be trying to do), try check_for_primality or something similar (without the question mark).

Also... if remainder is zero, the number is not prime. I think you have your tests switched around.

If you are still stumped:


def prime?(num); (2..Math.sqrt(num)).each do |counter|; if (num % counter == 0); return false end end; true; end

EDIT On rewritten code: break & return false doesn't do what you want. They are both control statements; if you break, return won't happen. Even if it did, if the break wasn't there, it would have been better to write and, or at least &&, not & (binary and).

Your logic is still wrong though: PrimeTime(16) is true, for example, is not really what I'd expect from a primality testing function.

Ruby - method for generating prime numbers

Got a good idea for your implementation:

@primes = []
def prime_numbers(n)
i = 2
while @primes.size < n do
@primes << i if is_prime?(i)
i += 1
end
@primes
end

def is_prime?(n)
@primes.each { |prime| return false if n % prime == 0 }
true
end

This is based on the idea that non-prime numbers have prime factors :)

Why doesnt my ruby coding for finding prime numbers work?

You have a few problems. One was identified earlier: the location of the statement i = 2. Here is your code with that fixed.

def is_prime?(*nums)
nums.each do |num|
i = 2
while i < num
if num % i == 0
puts "#{num} is not a prime"
else
puts "#{num} is a prime"
end
i += 1
end
end
end

When num % i == 0 you've determined the number is not prime, and print a message to that effect, but then you continue checking to see if it is divisible all larger numbers less than num. Each time num % i == 0 you print out that it's not prime. The point is that you don't need to keep checking once you determine a number is not prime.

Another problem is whenever num % i != 0 you print that the number is prime. That's premature, however. You can't draw that conclusion until you determine that num % i != 0 for all integers less than num.

Let's see how to fix these problems. I think the easiest ways is to write a separate method that determines if a single number is prime. I've called that method is_prime? and renamed the main method is_each_prime?.

def is_each_prime?(*nums)
nums.each { |num|
puts "#{num} is #{ is_prime?(num) ? '' : "not " }a prime" }
end

def is_prime?(num)
(2...Math.sqrt(num)).all? { |i| num % i != 0 }
end

puts is_each_prime?(21, 23, 17)
#=> 21 is not a prime
# 23 is a prime
# 17 is a prime

One advantage of creating a separate method is_prime? is that you can test it separately, to make sure it is working properly.



Related Topics



Leave a reply



Submit