So I'm trying to find the 10,001st prime #. Here's my code -
counter = 3
primes = [1]
while len(primes) < 10002:
for i in range(2, counter):
if counter % i == 0:
counter += 1
else:
primes.append(counter)
counter += 1
print counter
So what I get as an output in primes is a list of numbers, the first few numbers are 1, 3, 5, 7, 11... so far, so good... 13, 17, 19, 23, 27... wait, 27? So at that point it breaks down and starts returning mostly primes but not all primes. And it takes forever.
I'm new to programming, made it through CodeAcademy's Python course and now trying to figure out how to get past what was essentially just an introduction to the grammar. I don't come from a math background, so while I know what a prime is, I know there are far better ways to go about this. If there's anyone in a similar boat who wants to "partner up" and work together on learning Py2.7, I'm more than happy to.
I won't implement anything for you, since that's why you're doing Project Euler, but I will point you strongly in the direction of The Sieve of Eratosthenes. It will calculate in seconds what your code will do in hours.
It works as such: (in pseudocode)
for known_prime in a huge list of numbers:
k=2
while known_prime*k < the biggest number:
known_prime*k is not prime
k += 1
Once you've made it through sqrt of the list, you've found every prime number within the list.
Since you're doing a project Euler puzzle, you obviously want comments on your code rather than the solution.
Your code:
counter = 3
primes = [1]
while len(primes) < 10002:
for i in range(2, counter):
if counter % i == 0:
counter += 1
else: # Mis-aligned else (assuming it's intended for the if)
primes.append(counter)
counter += 1
print counter
Your else is mis-aligned with the if
Your for loop goes all the way to counter, and testing divisibility against itself is bound to find remainder 0.
Your else clause will hit for each non-factor of counter. Most numbers will not be a factor, so you don't want to take action in that case. Instead break out of the loop when the if part triggers.
After exiting the for loop, you'll want to check if a factor was found and if not, add counter to your list of primes.
Looks like you are trying to implement a naive un-optimized brute force search, and that is fine.
Maybe try and write out the algorithm in words or pseudo code before coding it.
As an exercise for you instead of writing for you a simple step by step code I will write a complex line of code with a solution to a similar problem.
Try to figure out what is going on here in this line as an exercise to understand python.
This code will find the prime numbers until n number not the first n prime numbers that you want
def primes(n):
return sorted(set(range(2, n+1)) - set([p*i for p in range(2, n+1) for i in range(p, n+1)]))
If you want to write an efficient and smart code, you may use the Sieve of Eratosthenes, a good algorithm for finding prime numbers in a given range.
For more information, read this:
http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
import time
start_time = time.time()
def is_prime(limit):
aval = True
for j in range(2,int(limit**0.5)+1):
if limit == 2:
aval = True
break
elif limit % j == 0:
aval = False
break
return aval
counter = 0
for i in range(2,1000000):
if is_prime(i):
counter += 1
if counter == 10001:
print("the 10001th prime number is: ",i)
break
print("seconds: ", time.time() - start_time)
Here is my solution to this problem. It may not be so quick but it is not precisely for problem 7.
import time
start = time.time()
n = int(input('Please enter a number: '))
def nth_prime(n):
primes = [2]
x = 3
max_amount = int(input('How much would you like to go for?: '))
while True:
try:
while x < max_amount:
for i in primes:
if x % i == 0:
break
else:
primes.append(x)
x += 2
print(primes[n])
except IndexError:
max_amount = int(input("Please enter a greater number: "))
continue
else:
print(f('Good job. You\'ve found the {n+1}st prime number :) ')
break
nth_prime(n)
end = time.time()
print(str(float(end - start)) + " seconds")
Related
The output shows a different result. Yes, the factorials of those numbers are right but the numbers outputted aren't right.
Here's the code:
input:
n = int(input("Enter a number: "))
s = 0
fact = 1
a = 1
for i in range(len(str(n))):
r = n % 10
s += r
n //= 10
while a <= s:
fact *= a
a += 1
print('The factorial of', s, 'is', fact)
Output:
Enter a number: 123
The factorial of 3 is 6
The factorial of 5 is 120
The factorial of 6 is 720
You're confusing yourself by doing it all in one logic block. The logic for finding a factorial is easy, as is the logic for parsing through strings character by character. However, it is easy to get lost in trying to keep the program "simple," as you have.
Programming is taking your problem, designing a solution, breaking that solution down into as many simple, repeatable individual logic steps as possible, and then telling the computer how to do every simple step you need, and what order they need to be done in to accomplish your goal.
Your program has 3 functions.
The first is taking in input data.
input("Give number. Now.")
The second is finding individual numbers in that input.
for character in input("Give number. Now."):
try:
int(character)
except:
pass
The third is calculating factorials for the number from step 2. I won't give an example of this.
Here is a working program, that is, in my opinion, much more readable and easier to look at than yours and others here. Edit: it also prevents a non numerical character from halting execution, as well as using only basic Python logic.
def factorialize(int_in):
int_out = int_in
int_multiplier = int_in - 1
while int_multiplier >= 1:
int_out = int_out * int_multiplier
int_multiplier -= 1
return int_out
def factorialize_multinumber_string(str_in):
for value in str_in:
print(value)
try:
print("The factorial of {} is {}".format(value, factorialize(int(value))))
except:
pass
factorialize_multinumber_string(input("Please enter a series of single digits."))
You can use map function to get every single digit from number:
n = int(input("Enter a number: "))
digits = map(int, str(n))
for i in digits:
fact = 1
a = 1
while a <= i:
fact *= a
a += 1
print('The factorial of', i, 'is', fact)
Ok, apart from the fact that you print the wrong variable, there's a bigger error. You are assuming that your digits are ever increasing, like in 123. Try your code with 321... (this is true of Karol's answer as well). And you need to handle digit zero, too
What you need is to restart the calculation of the factorial from scratch for every digit. For example:
n = '2063'
for ch in reversed(n):
x = int(ch)
if x == 0:
print(f'fact of {x} is 1')
else:
fact = 1
for k in range(2,x+1):
fact *= k
print(f'fact of {x} is {fact}')
So, I wrote a code to find if a number is PRIME or NOT...
I wrote it in 2 different ways, they are almost same but I just had a doubt. So here it is:
1st code:
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
2nd Code:
num = int(input("Enter the number: "))
for i in range(2,num):
if num % i == 0:
print("Prime!")
break
else:
print("Not Prime!")
The 1st code takes the input(num) and according to the input sets a limit(which is the half number + 1)
and then checks if the num is divisible by all the numbers in range (2 to lim)
The second one is same but instead of setting a limit it just checks all numbers lower than the input, which means it has to do a little more work...
Now both of these are almost same, the only difference is I saved a line in 2nd one and output efficiency is also better!
Which code would you want me to prefer/
also if this code has any problems, pointing them out would be helpful!
Thanks :)
Explanation
The most important piece of iteration, namely determining whether a number is prime or not, is to keep track of it. Without this process and in the OP's program, a variable is not used to handle this, meaning that he checks whether a number is or isn't prime every single time and concludes at that point. He also uses an else statement which is syntactically incorrect.
To prevent this, we can use a variable to keep track of this. Let's call it isprime. We need to assume that a number will always be a prime unless otherwise said. This can be achieved by setting isprime to default be True, and setting it to be False when we conclude that it is not a prime, because is has a divisor. Finally, we can check this variable at the end and determine whether that number is a prime or not, because it would be set to False if not, or left as True if it is.
Another observation made is that the limit for determining primes can be reduced down to sqrt(n). This is because we do not need to find every factor if it exists, just its lowest corresponding factor. Let's look at an example:
Factors of 24: 2, 3, 4, 6, 8, 12
We can stop checking for the factors right here:
2, 3, 4 | 6, 8, 12, 24
This is because if a number has a factor (such as greater than the square root), it will have a corresponding factor less than the square root. As a result, we can set our limit to be sqrt(n), just for peace of mind + a time complexity of O(sqrt(n)) v. O(n).
As an extra note, sqrt is not inbuilt into Python. You will have to import it from the math library using:
from math import sqrt
Final Code
# Setup
num = int(input("Enter the number: "))
lim = sqrt(num)
isprime = True
# Loop & check
for i in range(2,lim):
if num % i == 0:
isprime = False
break
# Results
if isprime:
print("Prime!")
else:
print("Not prime!")
The logic of the solution is wrong. You gave to switch the "Prime" and "Not Prime" tags. Like follows;
num = int(input("Enter the number: "))
lim = num//2 + 1
for i in range(2,lim):
if num % i == 0:
print("Not Prime!")
break
else:
print("Prime!")
The solution 1 is more efficient because you do not need to do extra
computation to check num//2 + 1. So it is preferable.
I have some code which gives me the answer I want, but I'm having trouble stopping it once I get the
answer I want.
Here's my code:
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
This is an attempt at solving problem 5 of Project Euler. Essentially, I'm supposed to get the smallest multiple of all the digits within a given range.
Now, when i run the above code using the example given (1-10 should yield 2520 as the smallest multiple), i get the answer right. However, the code continues to run infinitely and print the answer without breaking. Also, the moment I add the break statement to the end like so:
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
break
The code just keeps spamming the number 30. Any ideas why this is happening. For the record, I'm not really looking for an alternative solution to this question (the goal is to learn after all), but those are welcome. What I want to know most of all is where I went wrong.
You never break out of your while loop. The for is the entire while body. break interrupts only the innermost loop; you have no mechanism to leave the while loop. Note that your continue doesn't do anything; it applies to the for loop, which is about to continue, anyway, since that's the last statement in the loop (in that control flow).
I can't really suggest a repair for this, since it's not clear how you expect this to solve the stated problem. In general, though, I think that you're a little confused: you use one loop to control n and the other to step through divisors, but you haven't properly tracked your algorithm to your code.
One way to deal with this is to have an exception. At best a custom one.
multiples = range(1,10)
n = 1
class MyBreak(Exception):
pass
while n>0:
try:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
raise MyBreak()
except MyBreak:
# now you are free :)
break
With this brake you stop only for loop, to exit whole cycle you should create trigger variable, for example:
multiples = range(1,10)
n = 1
tg = 0
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
tg = 1
break
if tg != 0:
break
Or it'll be better to use a function and stop a cycle by return:
def func():
multiples = range(1,10)
n = 1
while n>0:
for i in multiples:
if n%i!=0:
n = n + 1
continue
elif n%10==0:
print(n)
return n
Where can I put a print statement to print the final list but still retain the return, and are there any ways you can think of to improve this function. I wrote the function but am unsure as to its relative quality
def buildPrimeList ():
primeList = [1, 2]
possiblePrime = 3
print "To display all prime values less than or equal a number..."
x = raw_input("Enter a number higher then 3 ")
while (possiblePrime <= x):
divisor = 2
isPrime = True
while (divisor < possiblePrime and isPrime):
if (possiblePrime % divisor == 0):
isPrime = False
divisor = divisor + 1
if (isPrime):
primeList.append(possiblePrime)
possiblePrime = possiblePrime + 2
return primeList
buildPrimeList()
It's quite straight-forward to print result of a function:
print buildPrimeList()
Also I've noticed that you do not convert raw_input's result (which is string) to int:
x = int(raw_input("Enter a number higher then 3 "))
Another way to do the same thing in python might look like:
from itertools import count
def is_prime(n):
"""Checks if given number
n is prime or not."""
for i in xrange(2, n/2):
if n % i == 0:
return False
else:
return True
def prime_numbers():
"""Generator function which lazily
yields prime numbers one by one."""
for i in count(1):
if is_prime(i):
yield i
if __name__ == '__main__':
maxprime = int(raw_input("Enter a number:"))
for prime in prime_numbers():
if prime < maxprime:
print prime
else:
break
A number of python idioms and language features were used:
generator functions and iterators [1];
snake_case_method_naming [2];
docstrings [3];
if __name__ == '__main__': ... [4].
[1] http://www.ibm.com/developerworks/library/l-pycon/index.html
[2] PEP 8: Style Guide for Python Code
[3] http://www.learningpython.com/2010/01/08/introducing-docstrings/
[4] What does if __name__ == "__main__": do?
p.s. As jellybean and rpInt noted in their answers and comments there are a number of ways to speed things up. But most likely you shouldn't do that (unless you absolutely have to) as "Simple is better than complex" [5].
[5] PEP 20: The Zen of Python
You can print the list immediately before returning it.
As for the efficency of the algorithm, consider the sieve of erathostenes.
You can improve the function greatly by just taking every 2nd number and dividing by it.
First, 1 isn't a prime, you shouldn't use it in that way. The reason for this is the prime factorization, that is unique for every number, like 9 = 3*3. If you would add 1 to your prime pool, 9 = 3*3, 9 = 3*3*1, 9=3*3*1*1, every one is a valid prime factorization, but it isn't unique anymore for every number.
Second, you don't have to check the number with every natural number. If you think about the natural numbers, every second of them is even and divisable by 2. So, if a number is divisable by 4, it is per definition divisable by 2. You can reduce the amount of calculations you have to do by a factor of 2 if you use this property. Also, you seem to use a technique called "The Sieve of Erastothenes" http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes which just adds prime numbers to the pool, and checks if the next natural number is divisable by any of them. You can exploit that easily.
def buildPrimeList ():
#One is not really a prime, so we cut it out.
primeList = [2]
possiblePrime = 3
print "To display all prime values less than or equal a number..."
upperlimit = raw_input("Enter a number higher then 3 ")
try:
upperlimit = int(upperlimit)
except:
print "Sorry. You didn't enter a number."
return
while (possiblePrime <= upperlimit):
#lets check if the possible prime is divisable by any prime we already know.
isPrime = True
for prime in primeList:
if(possiblePrime % prime == 0):
#we can abort the check here, since we know already that this number can't be a prime
isPrime = False
break
if (isPrime):
primeList.append(possiblePrime)
possiblePrime = possiblePrime + 2
return primeList
print buildPrimeList()
This should work as expected.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Simple Prime Generator in Python
First I will prompt user to input any number. Then my code will check whether does the number input by the user is a Prime number not.
Here is my codes:
num = int(raw_input("Input any of the number you like:"))
for x in range(2, int(num**0.5)+1):
if num % x == 0:
print "It is not a prime number"
else:
print "It is a prime number"
But question is I cant seem to get the output for 2 and 3. And when I randomly input any numbers like 134245, the system will output alot of sentences. And I do not know why?
Appreciate any kind souls to help me up :)
import urllib
tmpl = 'http://www.wolframalpha.com/input/?i=is+%d+a+prime+number'
def is_prime(n):
return ('is a prime number' in urllib.urlopen(tmpl % (n,)).read())
you should stop once num % x == 0 is true (no need for further testing) and print 'it is a prime number' only if the loop completed without anything printed before.
A number is prime if it only divides by 1 and itself. A pseudocode follows:
boolean prime = true;
for (int i = 2; i * i <= num; i++)
if (num % i == 0) {
prime = false;
break;
}
if (prime)
println("It is prime!");
else
println("It is not prime!");
Look at your code like this:
num = ...
for x in range(2, int(num**0.5)+1):
print something
The body of the loop is executed at every iteration. That means you're printing something at every iteration, i.e. for each x that you check to see if it's a factor of num, you print. That's not what you should be doing; in order to determine whether a number is prime, you check all possible factors first, then print your result. So you shouldn't be printing anything until after the loop.
But question is I cant seem to get the output for 2 and 3.
You're looping from 2 to ceil(sqrt(n)). For 2 and 3, this is an empty range, hence no iteration happens. Either special-case it or rewrite the code such that it assumes that n is prime and tries to disprove it in the loop.
the system will output alot of sentences.
You're printing on every iteration. Instead, use a boolean flag (or a premature return, if you factor it out into a function) to determine prime-ness and print once, after the loop, based on that prime.
Your code is not structured well-- the algorithm continues to loop all the way up to the top of your range, even if you already know that the number is composite, and it also prints some result on each iteration when it should not.
You could put the logic into a function and return True or False for prime-ness. Then you could just check the result of the function in your if statement.
def is_prime(num):
for x in range(2, int(num**0.5)+1):
if num % x == 0:
return False
return True
num = int(raw_input("Input any of the number you like:"))
if not is_prime(num):
print "It is not a prime number"
else:
print "It is a prime number"
Here are two Python routines for calculating primes. (Hint: Google for Sieve of Eratosthenese):
def pythonicSieve(maxValue):
"""
A Pythonic Sieve of Eratosthenes - this one seems to run slower than the other.
see http://love-python.blogspot.com/2008/02/find-prime-number-upto-100-nums-range2.html
"""
return [x for x in range(2,maxValue) if not [t for t in range(2,x) if not x%t]]
def sieveOfEratosthenes(maxValue):
"""
see http://hobershort.wordpress.com/2008/04/15/sieve-of-eratosthenes-in-python/
"""
primes = range(2, maxValue+1)
for n in primes:
p = 2
while n*p <= primes[-1]:
if n*p in primes:
primes.remove(n*p)
p += 1
return primes