Project Euler Problem #7 in Python (10001st prime number)
up vote
9
down vote
favorite
I have managed to solve the 7th Project Euler problem, however I think it can be improved by a lot, I am by no means a professional programmer or even consider myself really good at it. Any improvements / suggestions would be really helpful.
Problem statement:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
This is my solution.
counter = 2
n = 10001
for i in range(3, 1000000, 2):
k = 1
while k < i:
k += 2
if i % k == 0:
break
if k + 2 == i:
counter += 1
if counter == n:
print(i)
raise ZeroDivisionError
The program does skip 2 and 3, in an attempt of mine to make it faster. At the end I raise an error in order to stop the program from looping.
python python-3.x programming-challenge primes
add a comment |
up vote
9
down vote
favorite
I have managed to solve the 7th Project Euler problem, however I think it can be improved by a lot, I am by no means a professional programmer or even consider myself really good at it. Any improvements / suggestions would be really helpful.
Problem statement:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
This is my solution.
counter = 2
n = 10001
for i in range(3, 1000000, 2):
k = 1
while k < i:
k += 2
if i % k == 0:
break
if k + 2 == i:
counter += 1
if counter == n:
print(i)
raise ZeroDivisionError
The program does skip 2 and 3, in an attempt of mine to make it faster. At the end I raise an error in order to stop the program from looping.
python python-3.x programming-challenge primes
add a comment |
up vote
9
down vote
favorite
up vote
9
down vote
favorite
I have managed to solve the 7th Project Euler problem, however I think it can be improved by a lot, I am by no means a professional programmer or even consider myself really good at it. Any improvements / suggestions would be really helpful.
Problem statement:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
This is my solution.
counter = 2
n = 10001
for i in range(3, 1000000, 2):
k = 1
while k < i:
k += 2
if i % k == 0:
break
if k + 2 == i:
counter += 1
if counter == n:
print(i)
raise ZeroDivisionError
The program does skip 2 and 3, in an attempt of mine to make it faster. At the end I raise an error in order to stop the program from looping.
python python-3.x programming-challenge primes
I have managed to solve the 7th Project Euler problem, however I think it can be improved by a lot, I am by no means a professional programmer or even consider myself really good at it. Any improvements / suggestions would be really helpful.
Problem statement:
By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13.
What is the 10 001st prime number?
This is my solution.
counter = 2
n = 10001
for i in range(3, 1000000, 2):
k = 1
while k < i:
k += 2
if i % k == 0:
break
if k + 2 == i:
counter += 1
if counter == n:
print(i)
raise ZeroDivisionError
The program does skip 2 and 3, in an attempt of mine to make it faster. At the end I raise an error in order to stop the program from looping.
python python-3.x programming-challenge primes
python python-3.x programming-challenge primes
edited Feb 21 at 21:38
200_success
128k15149412
128k15149412
asked Feb 21 at 19:17
Gentlebud
462
462
add a comment |
add a comment |
5 Answers
5
active
oldest
votes
up vote
3
down vote
I'm not going to pay attention to your algorithm, as Arnav is right there, but instead focus on style problems. It should be a giant red flag when you raise a ZeroDivisionError
when you aren't dividing by zero. The correct solution here is to put your code inside a function, which will let you return the correct result. While here, you might as well make the upper limit of your range n*n
instead of 1,000,000
, which will let it work for bigger values. Also, I know I said I wouldn't focus on the algorithm, but you can make the inner loop be while k*k<i
, as any prime factor of n
will be less than the n**.5
. This simple change makes your code take .1 second instead of 30.
def nth_prime(n):
counter = 2
for i in range(3, n**2, 2):
k = 1
while k*k < i:
k += 2
if i % k == 0:
break
else:
counter += 1
if counter == n:
return i
print(nth_prime(100001))
1
Nice. It's still pretty close to OP's code while not being too inefficient. You needprint(nth_prime(10001))
, though.
– Eric Duminil
Feb 22 at 10:31
add a comment |
up vote
3
down vote
Upper bound for p_n
There is a known upper bound for the n-th prime.
It means that you don't need to guess how large it could be. upper_bound_for_p_n(10001)
tells us in less than a micro-second that the desired number cannot be larger than 114320
.
You just need to apply the Sieve of Erathosthenes up to 114320 and you're done:
from math import log, ceil
def find_primes(limit):
nums = [True] * (limit + 1)
nums[0] = nums[1] = False
for (i, is_prime) in enumerate(nums):
if is_prime:
yield i
for n in range(i * i, limit + 1, i):
nums[n] = False
def upper_bound_for_p_n(n):
if n < 6:
return 100
return ceil(n * (log(n) + log(log(n))))
def find_n_prime(n):
primes = list(find_primes(upper_bound_for_p_n(n)))
return primes[n - 1]
It calculates the 10001th prime in 15ms on my computer, compared to 35s for your code.
Also,1.26*n*log(n)
is a tighter upper bound forn>17
– Oscar Smith
Feb 22 at 20:08
add a comment |
up vote
3
down vote
What I dislike about your solution is the unnecessarily large amount of complexity your code has, which takes a toll on its performance.
When I solved this problem myself, I used the Sieve of Eratosthenes to generate a list of prime numbers up to an arbitrary limit (I also picked one million, but you could use a formula to compute it) and indexed that list at 10,000 to get the 10,001st number.
Here is how I implemented the sieve:
def primes_upto(limit):
limitN = limit+1
not_prime = set()
primes = [2]
for i in range(3, limitN, 2):
if i in not_prime:
continue
for j in range(i*3, limitN, i*2):
not_prime.add(j)
primes.append(i)
return primes
As you can see, this approach reduces the complexity of your code. Also, this is approximately 28 seconds quicker than your approach.
add a comment |
up vote
0
down vote
One way to solve this problem and use memory efficiently is through generators, this way only one prime at the time is processed and you won't get out of memory
def is_prime(n):
if n == 2:
return True
if n % 2 == 0 or n < 2:
return False
limit = int(n ** 0.5) + 1
for i in range(3, limit, 2):
if n % i == 0:
return False
return True
def next_prime(count_limit):
yield 2
count = 1
n = 3
while True:
if is_prime(n):
yield n
count += 1
if count == count_limit:
return
n += 2
n = 10001
# Good
item = None
for item in next_prime(n):
pass
print(item)
# Better
from collections import deque
dd = deque(next_prime(n), maxlen=1)
print(dd.pop())
Aditionally, if you need to run it several times, memoizing is suggested:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def is_prime(n):
...
The first half of this isn't so much a review as an alternate method. You talk about reducing memory, but OP's algo was alreadyO(1)
– Oscar Smith
Feb 22 at 3:23
You could also useislice
to access the n-th element of your generator. You could also rename your functions. I wouldn't expectnext_prime
to return a generator of primes.
– Eric Duminil
Feb 22 at 10:32
add a comment |
up vote
0
down vote
I use generator also.
def prime():
import itertools
yield 2
for i in itertools.count(3, 2):
if i == 2:
yield 2
else:
e = int(i**.5) + 1
for j in range(2, e+1):
if i % j == 0:
break
elif j < e:
continue
else:
yield i
for i, n in enumerate(prime()):
if i < 10001:
pass
elif i == 10001:
print(n)
else:
break
New contributor
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188053%2fproject-euler-problem-7-in-python-10001st-prime-number%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
3
down vote
I'm not going to pay attention to your algorithm, as Arnav is right there, but instead focus on style problems. It should be a giant red flag when you raise a ZeroDivisionError
when you aren't dividing by zero. The correct solution here is to put your code inside a function, which will let you return the correct result. While here, you might as well make the upper limit of your range n*n
instead of 1,000,000
, which will let it work for bigger values. Also, I know I said I wouldn't focus on the algorithm, but you can make the inner loop be while k*k<i
, as any prime factor of n
will be less than the n**.5
. This simple change makes your code take .1 second instead of 30.
def nth_prime(n):
counter = 2
for i in range(3, n**2, 2):
k = 1
while k*k < i:
k += 2
if i % k == 0:
break
else:
counter += 1
if counter == n:
return i
print(nth_prime(100001))
1
Nice. It's still pretty close to OP's code while not being too inefficient. You needprint(nth_prime(10001))
, though.
– Eric Duminil
Feb 22 at 10:31
add a comment |
up vote
3
down vote
I'm not going to pay attention to your algorithm, as Arnav is right there, but instead focus on style problems. It should be a giant red flag when you raise a ZeroDivisionError
when you aren't dividing by zero. The correct solution here is to put your code inside a function, which will let you return the correct result. While here, you might as well make the upper limit of your range n*n
instead of 1,000,000
, which will let it work for bigger values. Also, I know I said I wouldn't focus on the algorithm, but you can make the inner loop be while k*k<i
, as any prime factor of n
will be less than the n**.5
. This simple change makes your code take .1 second instead of 30.
def nth_prime(n):
counter = 2
for i in range(3, n**2, 2):
k = 1
while k*k < i:
k += 2
if i % k == 0:
break
else:
counter += 1
if counter == n:
return i
print(nth_prime(100001))
1
Nice. It's still pretty close to OP's code while not being too inefficient. You needprint(nth_prime(10001))
, though.
– Eric Duminil
Feb 22 at 10:31
add a comment |
up vote
3
down vote
up vote
3
down vote
I'm not going to pay attention to your algorithm, as Arnav is right there, but instead focus on style problems. It should be a giant red flag when you raise a ZeroDivisionError
when you aren't dividing by zero. The correct solution here is to put your code inside a function, which will let you return the correct result. While here, you might as well make the upper limit of your range n*n
instead of 1,000,000
, which will let it work for bigger values. Also, I know I said I wouldn't focus on the algorithm, but you can make the inner loop be while k*k<i
, as any prime factor of n
will be less than the n**.5
. This simple change makes your code take .1 second instead of 30.
def nth_prime(n):
counter = 2
for i in range(3, n**2, 2):
k = 1
while k*k < i:
k += 2
if i % k == 0:
break
else:
counter += 1
if counter == n:
return i
print(nth_prime(100001))
I'm not going to pay attention to your algorithm, as Arnav is right there, but instead focus on style problems. It should be a giant red flag when you raise a ZeroDivisionError
when you aren't dividing by zero. The correct solution here is to put your code inside a function, which will let you return the correct result. While here, you might as well make the upper limit of your range n*n
instead of 1,000,000
, which will let it work for bigger values. Also, I know I said I wouldn't focus on the algorithm, but you can make the inner loop be while k*k<i
, as any prime factor of n
will be less than the n**.5
. This simple change makes your code take .1 second instead of 30.
def nth_prime(n):
counter = 2
for i in range(3, n**2, 2):
k = 1
while k*k < i:
k += 2
if i % k == 0:
break
else:
counter += 1
if counter == n:
return i
print(nth_prime(100001))
answered Feb 21 at 22:45
Oscar Smith
2,698922
2,698922
1
Nice. It's still pretty close to OP's code while not being too inefficient. You needprint(nth_prime(10001))
, though.
– Eric Duminil
Feb 22 at 10:31
add a comment |
1
Nice. It's still pretty close to OP's code while not being too inefficient. You needprint(nth_prime(10001))
, though.
– Eric Duminil
Feb 22 at 10:31
1
1
Nice. It's still pretty close to OP's code while not being too inefficient. You need
print(nth_prime(10001))
, though.– Eric Duminil
Feb 22 at 10:31
Nice. It's still pretty close to OP's code while not being too inefficient. You need
print(nth_prime(10001))
, though.– Eric Duminil
Feb 22 at 10:31
add a comment |
up vote
3
down vote
Upper bound for p_n
There is a known upper bound for the n-th prime.
It means that you don't need to guess how large it could be. upper_bound_for_p_n(10001)
tells us in less than a micro-second that the desired number cannot be larger than 114320
.
You just need to apply the Sieve of Erathosthenes up to 114320 and you're done:
from math import log, ceil
def find_primes(limit):
nums = [True] * (limit + 1)
nums[0] = nums[1] = False
for (i, is_prime) in enumerate(nums):
if is_prime:
yield i
for n in range(i * i, limit + 1, i):
nums[n] = False
def upper_bound_for_p_n(n):
if n < 6:
return 100
return ceil(n * (log(n) + log(log(n))))
def find_n_prime(n):
primes = list(find_primes(upper_bound_for_p_n(n)))
return primes[n - 1]
It calculates the 10001th prime in 15ms on my computer, compared to 35s for your code.
Also,1.26*n*log(n)
is a tighter upper bound forn>17
– Oscar Smith
Feb 22 at 20:08
add a comment |
up vote
3
down vote
Upper bound for p_n
There is a known upper bound for the n-th prime.
It means that you don't need to guess how large it could be. upper_bound_for_p_n(10001)
tells us in less than a micro-second that the desired number cannot be larger than 114320
.
You just need to apply the Sieve of Erathosthenes up to 114320 and you're done:
from math import log, ceil
def find_primes(limit):
nums = [True] * (limit + 1)
nums[0] = nums[1] = False
for (i, is_prime) in enumerate(nums):
if is_prime:
yield i
for n in range(i * i, limit + 1, i):
nums[n] = False
def upper_bound_for_p_n(n):
if n < 6:
return 100
return ceil(n * (log(n) + log(log(n))))
def find_n_prime(n):
primes = list(find_primes(upper_bound_for_p_n(n)))
return primes[n - 1]
It calculates the 10001th prime in 15ms on my computer, compared to 35s for your code.
Also,1.26*n*log(n)
is a tighter upper bound forn>17
– Oscar Smith
Feb 22 at 20:08
add a comment |
up vote
3
down vote
up vote
3
down vote
Upper bound for p_n
There is a known upper bound for the n-th prime.
It means that you don't need to guess how large it could be. upper_bound_for_p_n(10001)
tells us in less than a micro-second that the desired number cannot be larger than 114320
.
You just need to apply the Sieve of Erathosthenes up to 114320 and you're done:
from math import log, ceil
def find_primes(limit):
nums = [True] * (limit + 1)
nums[0] = nums[1] = False
for (i, is_prime) in enumerate(nums):
if is_prime:
yield i
for n in range(i * i, limit + 1, i):
nums[n] = False
def upper_bound_for_p_n(n):
if n < 6:
return 100
return ceil(n * (log(n) + log(log(n))))
def find_n_prime(n):
primes = list(find_primes(upper_bound_for_p_n(n)))
return primes[n - 1]
It calculates the 10001th prime in 15ms on my computer, compared to 35s for your code.
Upper bound for p_n
There is a known upper bound for the n-th prime.
It means that you don't need to guess how large it could be. upper_bound_for_p_n(10001)
tells us in less than a micro-second that the desired number cannot be larger than 114320
.
You just need to apply the Sieve of Erathosthenes up to 114320 and you're done:
from math import log, ceil
def find_primes(limit):
nums = [True] * (limit + 1)
nums[0] = nums[1] = False
for (i, is_prime) in enumerate(nums):
if is_prime:
yield i
for n in range(i * i, limit + 1, i):
nums[n] = False
def upper_bound_for_p_n(n):
if n < 6:
return 100
return ceil(n * (log(n) + log(log(n))))
def find_n_prime(n):
primes = list(find_primes(upper_bound_for_p_n(n)))
return primes[n - 1]
It calculates the 10001th prime in 15ms on my computer, compared to 35s for your code.
answered Feb 22 at 10:27
Eric Duminil
2,0261613
2,0261613
Also,1.26*n*log(n)
is a tighter upper bound forn>17
– Oscar Smith
Feb 22 at 20:08
add a comment |
Also,1.26*n*log(n)
is a tighter upper bound forn>17
– Oscar Smith
Feb 22 at 20:08
Also,
1.26*n*log(n)
is a tighter upper bound for n>17
– Oscar Smith
Feb 22 at 20:08
Also,
1.26*n*log(n)
is a tighter upper bound for n>17
– Oscar Smith
Feb 22 at 20:08
add a comment |
up vote
3
down vote
What I dislike about your solution is the unnecessarily large amount of complexity your code has, which takes a toll on its performance.
When I solved this problem myself, I used the Sieve of Eratosthenes to generate a list of prime numbers up to an arbitrary limit (I also picked one million, but you could use a formula to compute it) and indexed that list at 10,000 to get the 10,001st number.
Here is how I implemented the sieve:
def primes_upto(limit):
limitN = limit+1
not_prime = set()
primes = [2]
for i in range(3, limitN, 2):
if i in not_prime:
continue
for j in range(i*3, limitN, i*2):
not_prime.add(j)
primes.append(i)
return primes
As you can see, this approach reduces the complexity of your code. Also, this is approximately 28 seconds quicker than your approach.
add a comment |
up vote
3
down vote
What I dislike about your solution is the unnecessarily large amount of complexity your code has, which takes a toll on its performance.
When I solved this problem myself, I used the Sieve of Eratosthenes to generate a list of prime numbers up to an arbitrary limit (I also picked one million, but you could use a formula to compute it) and indexed that list at 10,000 to get the 10,001st number.
Here is how I implemented the sieve:
def primes_upto(limit):
limitN = limit+1
not_prime = set()
primes = [2]
for i in range(3, limitN, 2):
if i in not_prime:
continue
for j in range(i*3, limitN, i*2):
not_prime.add(j)
primes.append(i)
return primes
As you can see, this approach reduces the complexity of your code. Also, this is approximately 28 seconds quicker than your approach.
add a comment |
up vote
3
down vote
up vote
3
down vote
What I dislike about your solution is the unnecessarily large amount of complexity your code has, which takes a toll on its performance.
When I solved this problem myself, I used the Sieve of Eratosthenes to generate a list of prime numbers up to an arbitrary limit (I also picked one million, but you could use a formula to compute it) and indexed that list at 10,000 to get the 10,001st number.
Here is how I implemented the sieve:
def primes_upto(limit):
limitN = limit+1
not_prime = set()
primes = [2]
for i in range(3, limitN, 2):
if i in not_prime:
continue
for j in range(i*3, limitN, i*2):
not_prime.add(j)
primes.append(i)
return primes
As you can see, this approach reduces the complexity of your code. Also, this is approximately 28 seconds quicker than your approach.
What I dislike about your solution is the unnecessarily large amount of complexity your code has, which takes a toll on its performance.
When I solved this problem myself, I used the Sieve of Eratosthenes to generate a list of prime numbers up to an arbitrary limit (I also picked one million, but you could use a formula to compute it) and indexed that list at 10,000 to get the 10,001st number.
Here is how I implemented the sieve:
def primes_upto(limit):
limitN = limit+1
not_prime = set()
primes = [2]
for i in range(3, limitN, 2):
if i in not_prime:
continue
for j in range(i*3, limitN, i*2):
not_prime.add(j)
primes.append(i)
return primes
As you can see, this approach reduces the complexity of your code. Also, this is approximately 28 seconds quicker than your approach.
edited Feb 22 at 11:33
answered Feb 21 at 22:10
Arnav Borborah
693121
693121
add a comment |
add a comment |
up vote
0
down vote
One way to solve this problem and use memory efficiently is through generators, this way only one prime at the time is processed and you won't get out of memory
def is_prime(n):
if n == 2:
return True
if n % 2 == 0 or n < 2:
return False
limit = int(n ** 0.5) + 1
for i in range(3, limit, 2):
if n % i == 0:
return False
return True
def next_prime(count_limit):
yield 2
count = 1
n = 3
while True:
if is_prime(n):
yield n
count += 1
if count == count_limit:
return
n += 2
n = 10001
# Good
item = None
for item in next_prime(n):
pass
print(item)
# Better
from collections import deque
dd = deque(next_prime(n), maxlen=1)
print(dd.pop())
Aditionally, if you need to run it several times, memoizing is suggested:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def is_prime(n):
...
The first half of this isn't so much a review as an alternate method. You talk about reducing memory, but OP's algo was alreadyO(1)
– Oscar Smith
Feb 22 at 3:23
You could also useislice
to access the n-th element of your generator. You could also rename your functions. I wouldn't expectnext_prime
to return a generator of primes.
– Eric Duminil
Feb 22 at 10:32
add a comment |
up vote
0
down vote
One way to solve this problem and use memory efficiently is through generators, this way only one prime at the time is processed and you won't get out of memory
def is_prime(n):
if n == 2:
return True
if n % 2 == 0 or n < 2:
return False
limit = int(n ** 0.5) + 1
for i in range(3, limit, 2):
if n % i == 0:
return False
return True
def next_prime(count_limit):
yield 2
count = 1
n = 3
while True:
if is_prime(n):
yield n
count += 1
if count == count_limit:
return
n += 2
n = 10001
# Good
item = None
for item in next_prime(n):
pass
print(item)
# Better
from collections import deque
dd = deque(next_prime(n), maxlen=1)
print(dd.pop())
Aditionally, if you need to run it several times, memoizing is suggested:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def is_prime(n):
...
The first half of this isn't so much a review as an alternate method. You talk about reducing memory, but OP's algo was alreadyO(1)
– Oscar Smith
Feb 22 at 3:23
You could also useislice
to access the n-th element of your generator. You could also rename your functions. I wouldn't expectnext_prime
to return a generator of primes.
– Eric Duminil
Feb 22 at 10:32
add a comment |
up vote
0
down vote
up vote
0
down vote
One way to solve this problem and use memory efficiently is through generators, this way only one prime at the time is processed and you won't get out of memory
def is_prime(n):
if n == 2:
return True
if n % 2 == 0 or n < 2:
return False
limit = int(n ** 0.5) + 1
for i in range(3, limit, 2):
if n % i == 0:
return False
return True
def next_prime(count_limit):
yield 2
count = 1
n = 3
while True:
if is_prime(n):
yield n
count += 1
if count == count_limit:
return
n += 2
n = 10001
# Good
item = None
for item in next_prime(n):
pass
print(item)
# Better
from collections import deque
dd = deque(next_prime(n), maxlen=1)
print(dd.pop())
Aditionally, if you need to run it several times, memoizing is suggested:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def is_prime(n):
...
One way to solve this problem and use memory efficiently is through generators, this way only one prime at the time is processed and you won't get out of memory
def is_prime(n):
if n == 2:
return True
if n % 2 == 0 or n < 2:
return False
limit = int(n ** 0.5) + 1
for i in range(3, limit, 2):
if n % i == 0:
return False
return True
def next_prime(count_limit):
yield 2
count = 1
n = 3
while True:
if is_prime(n):
yield n
count += 1
if count == count_limit:
return
n += 2
n = 10001
# Good
item = None
for item in next_prime(n):
pass
print(item)
# Better
from collections import deque
dd = deque(next_prime(n), maxlen=1)
print(dd.pop())
Aditionally, if you need to run it several times, memoizing is suggested:
def memoize(f):
memo = {}
def helper(x):
if x not in memo:
memo[x] = f(x)
return memo[x]
return helper
@memoize
def is_prime(n):
...
answered Feb 22 at 3:03
Ezequiel Castaño
417
417
The first half of this isn't so much a review as an alternate method. You talk about reducing memory, but OP's algo was alreadyO(1)
– Oscar Smith
Feb 22 at 3:23
You could also useislice
to access the n-th element of your generator. You could also rename your functions. I wouldn't expectnext_prime
to return a generator of primes.
– Eric Duminil
Feb 22 at 10:32
add a comment |
The first half of this isn't so much a review as an alternate method. You talk about reducing memory, but OP's algo was alreadyO(1)
– Oscar Smith
Feb 22 at 3:23
You could also useislice
to access the n-th element of your generator. You could also rename your functions. I wouldn't expectnext_prime
to return a generator of primes.
– Eric Duminil
Feb 22 at 10:32
The first half of this isn't so much a review as an alternate method. You talk about reducing memory, but OP's algo was already
O(1)
– Oscar Smith
Feb 22 at 3:23
The first half of this isn't so much a review as an alternate method. You talk about reducing memory, but OP's algo was already
O(1)
– Oscar Smith
Feb 22 at 3:23
You could also use
islice
to access the n-th element of your generator. You could also rename your functions. I wouldn't expect next_prime
to return a generator of primes.– Eric Duminil
Feb 22 at 10:32
You could also use
islice
to access the n-th element of your generator. You could also rename your functions. I wouldn't expect next_prime
to return a generator of primes.– Eric Duminil
Feb 22 at 10:32
add a comment |
up vote
0
down vote
I use generator also.
def prime():
import itertools
yield 2
for i in itertools.count(3, 2):
if i == 2:
yield 2
else:
e = int(i**.5) + 1
for j in range(2, e+1):
if i % j == 0:
break
elif j < e:
continue
else:
yield i
for i, n in enumerate(prime()):
if i < 10001:
pass
elif i == 10001:
print(n)
else:
break
New contributor
add a comment |
up vote
0
down vote
I use generator also.
def prime():
import itertools
yield 2
for i in itertools.count(3, 2):
if i == 2:
yield 2
else:
e = int(i**.5) + 1
for j in range(2, e+1):
if i % j == 0:
break
elif j < e:
continue
else:
yield i
for i, n in enumerate(prime()):
if i < 10001:
pass
elif i == 10001:
print(n)
else:
break
New contributor
add a comment |
up vote
0
down vote
up vote
0
down vote
I use generator also.
def prime():
import itertools
yield 2
for i in itertools.count(3, 2):
if i == 2:
yield 2
else:
e = int(i**.5) + 1
for j in range(2, e+1):
if i % j == 0:
break
elif j < e:
continue
else:
yield i
for i, n in enumerate(prime()):
if i < 10001:
pass
elif i == 10001:
print(n)
else:
break
New contributor
I use generator also.
def prime():
import itertools
yield 2
for i in itertools.count(3, 2):
if i == 2:
yield 2
else:
e = int(i**.5) + 1
for j in range(2, e+1):
if i % j == 0:
break
elif j < e:
continue
else:
yield i
for i, n in enumerate(prime()):
if i < 10001:
pass
elif i == 10001:
print(n)
else:
break
New contributor
New contributor
answered 22 mins ago
Matt Cao
1
1
New contributor
New contributor
add a comment |
add a comment |
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f188053%2fproject-euler-problem-7-in-python-10001st-prime-number%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown