views:

1283

answers:

5

Assume the availability of a function is_prime. Assume a variable n has been associated with a positive integer. Write the statements needed to compute the sum of the first n prime numbers. The sum should be associated with the variable total.

Note: is_prime takes an integer as a parameter and returns True if and only if that integer is prime. Well, I wrote is_prime function like this:

def is_prime(n):
    n = abs(n)
    i = 2
    while i < n:
        if n % i == 0:
            return False
        i += 1
    return True

but it works except for n==0. How can I fix it to make it work for every integer? I'm trying to find out answers for both how to write function to get the sum of first n prime numbers and how to modify my is_prime function, which should work for all possible input, not only positive numbers.

A: 

Why not just hardcode an answer for i = 0 or 1?

n = abs(n)
i = 2
if(n == 0 || n == 1)
   return true //Or whatever you feel 0 or 1 should return.
while i < n:
    if n % i == 0:
        return False
    i += 1
return True

And you could further improve the speed of your algorithm by omitting some numbers. This script only checks up to the square root of n as no composite number has factors greater than its square root if a number has one or more factors, one will be encountered before the square root of that number. When testing large numbers, this makes a pretty big difference.

n = abs(n)
i = 2
if(n == 0 || n == 1)
   return true //Or whatever you feel 0 or 1 should return.
while i <= sqrt(n):
    if n % i == 0:
        return False
    i += 1
return True
Sam152
One is technically not a prime. Zero is in no way a prime.
paxdiablo
Not true to say that "no composite number has factors greater than its square root" What about 123456 = 643 * 192 ? One factor is smaller, and the other greater than the square root (351.363..)
pavium
I made a clarification.
Sam152
So there is no need to analyze for factors bigger than the square root because there is also a factor smaller than the square root, and that will be found first to prove that the number is composite.
Jonathan Leffler
Make sure that you do "i <= sqrt(n)" instead of making it a strict comparison, otherwise your funciton fails for perfect squares like n=4. Also, 0 and 1 are not primes so return false.
David Grayson
It's often faster to change "while i <= sqrt(n)" into "while i*i <= n" since multiplication is usually faster than a square root.
paxdiablo
Of course you'd rather compute the sqrt(n) only once per n and store it in a variable and neither recompute it nor square i at each loop
ptor
@ptor, good catch, that *is* a better solution. One calculation in total, probably less effort than i*i every time through the loop, even though the individual operation is more expensive.
paxdiablo
A: 

Well, what happens when n is 0 or 1?

You have

i = 2
while i < n: #is 2 less than 0 (or 1?)
     ...
return True

If you want n of 0 or 1 to return False, then doesn't this suggest that you need to modify your conditional (or function itself) to account for these cases?

matt b
+2  A: 

In your problem statement it says that n is a positive integer. So assert(n>0) and ensure that your program outer-loop will never is_prime() with a negative value nor zero.

Your algorithm - trial division of every successive odd number (the 'odd' would be a major speed-up for you) - works, but is going to be very slow. Look at the prime sieve for inspiration.

Will
A: 

try this:

 if(n==0)
    return true
 else
    n = abs(n)
    i = 2
    while i < n:
        if n % i == 0:
            return False
        i += 1
    return True
Ngu Soon Hui
+3  A: 

Your assignment is as follows.

Assume the availability of a function is_prime. Assume a variable n has been associated with a positive integer. Write the statements needed to compute the sum of the first n prime numbers. The sum should be associated with the variable total.

As NVRAM rightly points out in the comments (and nobody else appears to have picked up on), the question states "assume the availability of a function is_prime".

You don't have to write that function. What you do have to do is "write the statements needed to compute the sum of the first n prime numbers".

The pseudocode for that would be something like:

primes_left = n
curr_num = 2
curr_sum = 0
while primes_left > 0:
    if is_prime(curr_num):
        curr_sum = curr_sum + curr_num
        primes_left = primes_left - 1
    curr_num = curr_num + 1
print "Sum of first " + n + " primes is " + curr_sum

I think you'll find that, if you just implement that pseudocode in your language of choice, that'll be all you have to do.

If you are looking for an implementation of is_prime to test your assignment with, it doesn't really matter how efficient it is, since you'll only be testing a few small values anyway. You also don't have to worry about numbers less than two, given the constraints of the code that will be using it. Something like this is perfectly acceptable:

def is_prime(num):
    if num < 2:
        return false
    if num == 2:
        return true
    divisor = 2
    while divisor * divisor <= num:
        if num % divisor == 0:
            return false
        divisor = divisor + 1
    return true
paxdiablo