I'm writing a function that, given a random int, will return the next int that is both a prime number and a palindrome. i.e getint(13) will return 101.
One of the conditions of this function is that recursion is not allowed.
Where am i going wrong here?
def golf(number):
x = number +1
for i in range(2, x):
while str(x) != str(x)[::-1] and x % i == 0:
x += 1
return x
Divide the problem into smaller pieces. It will be easier for you to understand what's going on:
def golf(number):
x = number + 1
while True:
if is_palindrome(x) and is_prime(x):
return x
x += 1
Now all you have to do is implement is_palindrome(x) and is_prime(x):
import math
def is_prime(x):
for i in xrange(2, math.ceil(math.sqrt(x))+1):
if x % i == 0:
return False
return True
def is_palindrome(x):
x = str(x)
return x == x[::-1]
Side note: the math.ceil(math.sqrt(x))+1 might be an overkill (perhaps int(...)+1 is enough) if math.sqrt works correctly for squares (i.e. does not depend on floating point calculations so math.sqrt(a*a)==a is always true). Well in worst case the loop will do one more iteration then necessary. Better safe then sorry.
Your for loop will only go as far as x's initial value: the range(2,x) is computed only once, right after x = number + 1. So increasing x inside the loop doesn't make a difference. Consider using a while loop, something like:
i = 2
while i <= x:
...
i += 1
And you should probably first check is x is a palindrome (a "cheap" operation) and then, if it is, check weather it is prime (an "expensive" operation), not try do it all in a couple of nested loops that make little sense.
In your code:
def golf(number):
x = number +1
for i in range(2, x):
while str(x) != str(x)[::-1] and x % i == 0:
x += 1
return x
The program execution will not satisfy the while loop half of the time since any even number will not be divisible by any odd number and vice-versa. Also in a single iteration of the for loop, x will be incremented every time the while loop is satisfied.
You need to separate the prime checking and palindrome checking. The approach given by freakish is the simplest.
Related
So its just a simple prime factorization calculator
Im not sure why its infinitely looping. Im pretty new to python and not entirely sure on how the while loop works
def print_prime_factors(number):
x = 2
while x < number:
if number % x == 0:
y = number/x
print(str(x)+",")
y = number
if x > y:
break
x = x + 1
print_prime_factors(100)
# Should print 2,2,5,5
# DO NOT DELETE THIS COMMENT```
Your code has an indentation error.
This line:
x = x + 1
should be shifted over one indent. You're only incrementing x whenever it is a factor of the number, which means that the program will enter an infinite loop by repeatedly checking whether number is divisible by a non-factor of number.
after the first iteration x changes and the if statements is never true again, which makes x never changes again. Seens to be just indentation problem.
(1) The first bug is, as others have said, that your line x = x + 1 that increments candidate x should be unindented one level, so it's under the while-loop.
(2) But you also have a bug with what you're doing with quotient y, it's mystifying.
When you identify that x is a factor of number, just print x. You compute the quotient y = number/x, silently throw it away, then assign y = number, which again gets thrown away. You could have just directly tested if x > number: ... break.
but even that is roundabout. Your while-loop that starts x at 2, increments x by +1, and stops when x > number, is really just a for-loop in disguise: for x in range(2, number+1): ...
But you can show we strictly only need to do:
for x in range(2, ceil(sqrt(number)+1): ... where we use math.sqrt, math.ceil
...really you need to store the quotient between iterations, and when it gets to 1 you know you can terminate early; you've found all the divisors of number
The question: Assume the availability of a function is_prime. Assume a variable n has been associated with positive integer. Write the statements needed to find out how many prime numbers (starting with 2 and going in increasing order with successively higher primes [2,3,5,7,11,13,...]) can be added before exceeding n. Associate this number with the variable k.
The code:
def is_prime():
i = 2
k = 0
Again = True
while Again = True:
if total > n:
Again = False
for x in range(2,n):
if x % i == 0:
total = total
k = k
i += 1
else:
total += x
k += 1
return k
Your code is not correct for an issue involving prime number tracking and consecutive addition. Nor anything else. The obvious issue is that it doesn't run, so it can't be correct. One syntax bug is this:
while Again = True:
which should be:
while Again == True:
Another is that total is never initialized before it's value is used:
total += x
Once we fix those problems, your code still doesn't appear to work. But let's back up a bit. The stated problem says,
Assume the availability of a function is_prime.
But you didn't do that -- you wrote your solution with the name is_prime(). We should expect that there is a function named is_prime(n) and it tests if n is prime or not, returning True or False. You are either given this, need to find one, write one, or simply assume it exists but never actually test your code. But once you have this function, and it works, you shouldn't change it!
Here's my example is_prime(n) function:
def is_prime(n):
""" Assume the availability of a function is_prime. """
if n < 2:
return False
if n % 2 == 0:
return n == 2
for m in range(3, int(n ** 0.5) + 1, 2):
if n % m == 0:
return False
return True
Now write your solution calling this function, but not changing this function. Here's one possible algorithm:
Write a function called primes_in_sum(n)
Set the variable prime to 2 and the variable k (our counter) to
0.
Subtract prime from n.
While n >= 0, increment k, and compute the next value of prime
by keep adding one to prime until is_prime(prime) returns true.
Then again subtract prime from n. Back to the top of this loop.
When the while condition fails, return k.
Test your code works by outputting some values:
for n in range(2, 100):
# Assume a variable n has been associated with a positive integer
print(n, primes_in_sum(n))
Check in your head that the results are reasonable.
I need to write a program that prints the greatest common divisor of two entered integers, and also prove the correctness of it. I wrote the following:
def main():
x = int(input("Enter the first integer: "))
y = int(input("Enter the second integer: "))
print(gcd(x,y))
def gcd(x,y):
if x > y:
smaller = y
else:
smaller = x
for i in range(1, smaller + 1):
if ((x % i == 0) and (y % i == 0)):
gcd = i
return gcd
main()
The precondition is clearly that x and y should be two integers. The postcondition is the greatest common divisor of x and y. I need to identify the loop invariant, and show that it is ok after initialization, that it remains true after every iteration. Also, I'm suppose to prove the postcondition by using the loop invariant and show that the loop is finite.
I think the loop invariant is that i is always smaller or equal to x and y, and that x % i = r and y % i = s for some integers r and s. This clearly holds for every iteration. The loop continues until r = 0 and s = 0, and then it terminates. Finiteness is guaranteed because the iteration has an upper bound.
Is my reasoning correct here? Does this proves the correctness of the loop?
I think you can state a loop invariant a bit more clearly if you initialize the gcd variable to 1 before entering the loop (which be over a range starting at 2 if you want). Your invariant will be:
gcd is the largest integer less than or equal to i such that x % gcd == y % gcd == 0.
Your loop ends because i iterates over a finite range (ending with i == min(x, y)). The postcondition is that gcd is the greatest common divisor of x and y, which is proved by the loop invariant (as long as you can prove the GCD of two numbers is not larger than the smaller of them).
I don't get the concept of loops yet. I got the following code:
x=0
while x < n:
x = x+1
print x
which prints 1,2,3,4,5.
That's fine, but how do I access the computation, that was done in the loop? e.g., how do I return the product of the loop( 5*4*3*2*1)?
Thanks.
Edit:
That was my final code:
def factorial(n):
result = 1
while n >= 1:
result = result *n
n=n-1
return result
You want to introduce one more variable (total) which contains accumulated value of a bunch of actions:
total = 1
x = 1
while x <= 5:
total *= x
x += 1
print x, total
print 'total:', total
Actually, more pythonic way:
total = 1
n = 5
for x in xrange(1, n + 1):
total *= x
print total
Note, that the initial value of total must be 1 and not 0 since in the latter case you will always receive 0 as a result (0*1*.. is always equals to 0).
By storing that product and returning that result:
def calculate_product(n):
product = 1
for x in range(n):
product *= x + 1
return product
Now we have a function that produces your calculation, and it returns the result:
print calculate_product(5)
A "one-liner"
>>> import operator
>>> reduce(operator.mul, xrange(1, n + 1))
120
>>>
Alternately you could use the yield keyword which will return the value from within the while loop. For instance:
def yeild_example():
current_answer = 1
for i in range(1,n+1):
current_answer *= i
yield current_answer
Which will lazily evaluate the answers for you. If you just want everything once this is probably the way to go, but if you know you want to store things then you should probably use return as in other answers, but this is nice for a lot of other applications.
This is called a generator function with the idea behind it being that it is a function that will "generate" answers when asked. In contrast to a standard function that will generate everything at once, this allows you to only perform calculations when you need to and will generally be more memory efficient, though performance is best evaluated on a case-by-case basis. As always.
**Edit: So this is not quite the question OP is asking, but I think it would be a good introduction into some of the really neat and flexible things about python.
use a for loop:
sum_ = 1
for i in range(1, 6):
sum_ *= i
print sum_
If you prefer to keep your while loop structure, you could do it like (there are 1000 +1 ways to do it ...):
x=1
result = 1
while x <= n:
x += 1
result *= x
Where result will store the factorial. You can then just return or print out result, or whatever you want to do with it.
to access the computation done in the loop, you must use counter(with useful and understandable name), where you will store the result of computation. After computation you just return or use the counter as the product of the loop.
sum_counter=0
x=0
while x < 10:
sum_counter +=x
x+=1
print sum_counter
This question already has answers here:
How to create the most compact mapping n → isprime(n) up to a limit N?
(29 answers)
Closed 7 years ago.
I'm trying to do a simple primality test in Python.
Accoding to Wikipedia, a primality test is the following:
Given an input number n, check whether any integer m from 2 to n − 1 divides n. If n is divisible by any m then n is composite, otherwise it is prime.
I started with ruling out the even numbers - with the exception of 2 - as candidates to prime
def prime_candidates(x):
odd = range(1, x, 2)
odd.insert(0, 2)
odd.remove(1)
return odd
Then writing a function to check for primes, according to the rules above.
def isprime(x):
for i in range(2, x-1):
if x % i == 0:
return False
else:
return True
And this is the main function, which iterates over a list of 8000 prime candidates and tests their primality
def main():
end = 8000
candidates = prime_candidates(end)
for i in candidates:
if isprime(i) and i < end:
print 'prime found ' + str(i)
The problem is that the isprime function returns True for numbers that aren't primes.
Have a look at the Miller–Rabin primality test if a probabilistic algorithm will suffice. You could also prove a number to be prime, with for instance Elliptic Curve Primality Proving (ECPP), but it takes more effort.
A simple trial division algorithm is the following
def prime(a):
return not (a < 2 or any(a % x == 0 for x in range(2, int(a ** 0.5) + 1)))
Edit:
Here's a more educational version because the first solution is very condensed and perhaps harder to read:
from math import sqrt
def prime(a):
if a < 2: return False
for x in range(2, int(sqrt(a)) + 1):
if a % x == 0:
return False
return True
I've substituted in sqrt(a) in place of a ** 0.5 to make things more clear. The square root is used to not look at more factors than we have to.
In brief, your isprime(x) checks whether the number is odd, exiting right after if x % 2 == 0.
Try a small change so that you would actually iterate:
def isprime(x):
for i in range(2, x-1):
if x % i == 0:
return False
else:
return True
Note that else: is now part of the for loop rather than if statement.
Your function actually returns whether your number is odd.
Indeed, what you're doing is you're checking whether 2 divides your number, and return immediately. You never check for the other numbers.
What you need to do is take this return true out of the if's else clause and the for loop back into the main function body.
On a sidenote, If you're looking for the primes lower than a given number, you could store the primes you found in memory and then only try dividing you new number by those primes !
(because if d is composite and divides q, then p exists such that p is prime and p divides q).
The problem is that you put return False in the else clause rather than at the end of the function. So your function will return right after the first divisor is checked, rather than going on to check other divisors.
Here is a simple primality test similar to yours:
def is_prime(n):
d = 2
while d * d <= n:
if n % d == 0:
return False
d += 1
return n > 1