In problem 4 from http://projecteuler.net/ it says:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 * 99.
Find the largest palindrome made from the product of two 3-digit numbers.
I have this code here
def isPalindrome(num):
return str(num) == str(num)[::-1]
def largest(bot, top):
for x in range(top, bot, -1):
for y in range(top,bot, -1):
if isPalindrome(x*y):
return x*y
print largest(100,999)
It should find the largest palindrome, it spits out 580085 which I believe to be correct, but project euler doesn't think so, do I have something wrong here?
When I revered the for loop I didn't think it through, I removed the thing that checks for the biggest, silly me. Heres the working code
def isPalindrome(num):
return str(num) == str(num)[::-1]
def largest(bot, top):
z = 0
for x in range(top, bot, -1):
for y in range(top,bot, -1):
if isPalindrome(x*y):
if x*y > z:
z = x*y
return z
print largest(100,999)
it spits out 906609
Iterating in reverse doesn't find the largest x*y, it finds the palindrome with the largest x. There's a larger answer than 580085; it has a smaller x but a larger y.
This would more efficiently be written as:
from itertools import product
def is_palindrome(num):
return str(num) == str(num)[::-1]
multiples = ( (a, b) for a, b in product(xrange(100,999), repeat=2) if is_palindrome(a*b) )
print max(multiples, key=lambda (a,b): a*b)
# (913, 993)
You'll find itertools and generators very useful if you're doing Euler in Python.
Not the most efficient answer but I do like that it's compact enough to fit on one line.
print max(i*j for i in xrange(1,1000) for j in xrange(1,1000) if str(i*j) == str(i*j)[::-1])
Tried making it more efficient, while keeping it legible:
def is_palindrome(num):
return str(num) == str(num)[::-1]
def fn(n):
max_palindrome = 1
for x in range(n,1,-1):
for y in range(n,x-1,-1):
if is_palindrome(x*y) and x*y > max_palindrome:
max_palindrome = x*y
elif x * y < max_palindrome:
break
return max_palindrome
print fn(999)
Here I added two 'break' to improve the speed of this program.
def is_palindrome(num):
return str(num) == str(num)[::-1]
def max_palindrome(n):
max_palindrome = 1
for i in range(10**n-1,10**(n-1)-1,-1):
for j in range(10**n-1,i-1,-1):
if is_palindrome(i*j) and i*j > max_palindrome:
max_palindrome = i * j
break
elif i*j < max_palindrome:
break
return max_palindrome
n=int(raw_input())
print max_palindrome(n)
Simple:
def is_pallindrome(n):
s = str(n)
for n in xrange(1, len(s)/2 + 1):
if s[n-1] != s[-n]:
return False
return True
largest = 0
for j in xrange(100, 1000):
for k in xrange(j, 1000):
if is_pallindrome(j*k):
if (j*k) > largest: largest = j*k
print largest
Each time it doesnot have to start from 999 as it is already found earlier.Below is a simple method using string function to find largest palindrome using three digit number
def palindrome(y):
z=str(y)
w=z[::-1]
if (w==z):
return 0
elif (w!=z):
return 1
h=[]
a=999
for i in range (999,0,-1):
for j in range (a,0,-1):
l=palindrome(i*j)
if (l==0):
h=h+[i*j]
a-=1
print h
max=h[0]
for i in range(0,len(h)):
if (h[i] > max):
max= h[i]
print "largest palindrome using multiple of three digit number=%d"%max
Here is my code to solve this problem.
lst = []
for i in range(100,1000):
for n in range(2,i) :
lst.append (i* n)
lst.append(i*i)
lst2=[]
for i in lst:
if str(i) == str(i)[::-1]:
lst2.append(i)
print max(lst2)
Here is my Python code:
max_pal = 0
for i in range(100,999):
for j in range(100,999):
mult = i * j
if str(mult) == str(mult)[::-1]: #Check if the number is palindrome
if mult > max_pal:
max_pal = mult
print (max_pal)
def div(n):
for i in range(999,99,-1):
if n%i == 0:
x = n/i
if x % 1 == 0:
x = n//i
if len(str(x)) == 3:
print(i)
return True
return False
def palindrome():
ans = []
for x in range(100*100,999*999+1):
s = str(x)
s = int (s[::-1])
if x - s == 0:
ans.append(x)
for x in range(len(ans)):
y = ans.pop()
if div(y):
return y
print(palindrome())
580085 = 995 X 583, where 906609 = 993 X 913.
Found it only by applying brute-forcing from top to bottom!
Here is the function I made in python to check if the product of 3 digit number is a palindrome
Function:
def is_palindrome(x):
i = 0
result = True
while i < int(len(str(x))/2):
j = i+1
if str(x)[i] == str(x)[-(j)]:
result = True
else:
result = False
break
i = i + 1
return result
Main:
max_pal = 0
for i in range (100,999):
for j in range (100,999):
x = i * j
if (is_palindrome(x)):
if x > max_pal:
max_pal = x
print(max_pal)
Here is my solution for that:
lst1 = [x for x in range(1000)]
palindrome = []
def reverse(x):
a = str(x)[::-1]
return int(a)
x = 0
while x < len(lst1):
for y in range(1000):
z = lst1[x] * y
if z == reverse(z):
palindrome.append(z)
x += 1
duppal = set(palindrome)
sortpal = sorted(duppal)
total = sortpal[-1]
print(sortpal)
print('Largest palindrome: ' + str(total))
ReThink: efficiency and performance
def palindrome(n):
maxNumberWithNDigits = int('9' * n) #find the max number with n digits
product = maxNumberWithNDigits * maxNumberWithNDigits
#Since we are looking the max, stop on the first match
while True:
if str(product) == str(product)[::-1]: break;
product-=1
return product
start=time.time()
palindrome(3)
end=time.time()-start
palindrome...: 997799, 0.000138998031616 secs
Related
I wrote this code to print how many prime numbers there are in a given list of numbers,
but it is not outputting anything. What am I doing wrong?
def count_primes(nums):
primes = 0
number_of_primes = 0
a_list = []
listing = 0
a_list == nums
for x in a_list:
if a_list % 2 == 0:
primes = primes + a_list
listing == len(primes)
print(listing)
You haven't called the function which is why you're not getting an output.
You may try this code to print the prime numbers at a given range.
from math import sqrt
def isPrime(x):
if x == 2:
return True
if x < 2:
return False
for i in range(2, int(sqrt(x))+1):
if x % i == 0:
return False
return True
n = int(input())
for i in range(1, n+1):
if isPrime(i):
print(i, end=" ")
I have a function that takes a number (for example, 5) and returns the first prime number after the input number (in this case, it would be 7).
This is my code:
def prime(n):
np=[]
isprime=[]
for i in range (n+1,n+200):
np.append(i)
for x in range(2,199):
for j in np:
if x%j!=0:
isprime.append(x)
return min(isprime)
However, this code doesn't work (it always returns 2). Where is the mistake?
You have a few mistakes, most notably np is clearly meant to be the potential primes (it starts at n+1 which is the first potential number that fits your critera "the first prime number after the input number"), and yet you add x to your prime list, which is from range(2,199), you should be using:
isprime.append(j)
Your primality test is also the wrong way round as a result, you should be using:
j % x != 0
Lastly, you can't append a number if that condition is true in one case, it has to be true in all cases (where x is an integer which satisfies 2 <= x < j), because of this you should switch your second set of for loops around (the x loop should be the inner loop), and you should also only loop up to j-1 (the number being tested). Additionally, you should instead choose to not add an item if j % x == 0:
for ...:
val_is_prime = True
for ...:
if j % x == 0:
val_is_prime = False
break
if val_is_prime:
isprime.append(j)
This results in the following code:
def prime(n):
np=[]
isprime=[]
for i in range (n+1,n+200):
np.append(i)
for j in np:
val_is_prime = True
for x in range(2,j-1):
if j % x == 0:
val_is_prime = False
break
if val_is_prime:
isprime.append(j)
return min(isprime)
And test run:
>>> prime(5)
7
>>> prime(13)
17
>>> prime(23)
29
Note that there's several other efficiency improvements that could be made, but this answer focuses on the mistakes rather than improvements
Try this one, the most pythonic and clear way to do this that I found (but probably not the most efficient):
def is_prime(x):
return all(x % i for i in range(2, x))
def next_prime(x):
return min([a for a in range(x+1, 2*x) if is_prime(a)])
print(next_prime(9))
https://www.geeksforgeeks.org/python-simpy-nextprime-method/
from sympy import *
# calling nextprime function on differnet numbers
nextprime(7)
nextprime(13)
nextprime(2)
Output:
11 17 3
This code working.
def prime(n):
next_prime = n + 1
prime = True
while True:
for i in range(2, next_prime):
if next_prime%i ==0:
prime = False
break
if prime:
return next_prime
else:
next_prime = next_prime + 1
if next_prime % 2 == 0:
next_prime = next_prime + 1
prime = True
if __name__=="__main__":
print(prime(5))
Here is one working sample.
inputNumber = int(input("Enter number to find next prime: "))
def nextPrime(inputNum):
for nextNumToChk in range(inputNum+1, inputNum +200):
if nextNumToChk > 1:
# If num is divisible by any number between 2 and val, it is not prime
for i in range(2, nextNumToChk):
if (nextNumToChk % i) == 0:
break
else:
#found the prime
return nextNumToChk
result = nextPrime(inputNumber)
print "Next Prime is : ",result
Output:-
Enter number to find next prime: 5
Next Prime is : 7
def is_prime(n):
# Corner case
if n <= 1:
return False
# Check from 2 to n-1
for i in range(2, n):
if n % i == 0:
return False
return True
def first_prime_over(n):
prime_number = (i for i in range(n) if is_prime(i))
try:
for i in range(0,n):
(next(prime_number))
except StopIteration:
prime_number_next = (i for i in range(n,n+1000) if is_prime(i))
print(next(prime_number_next))
first_prime_over(10)
Try this one:
def find_next_prime(n):
return find_prime_in_range(n, 2*n)
def find_prime_in_range(a, b):
for c in range(a, b):
for i in range(2, c):
if c % i == 0:
break
else:
return c
return None
def main():
n = int(input('Find the next prime number from: '))
print(find_next_prime(n+1))
if __name__ == '__main__':
main()
n = int(input("Enter a number"))
while True:
n+=1
for x in range(2,n):
if n%x==0:
break
else:
print("next prime number is",n)
break
Can somebody solve this problem on Python ?
A positive integer m can be partitioned as primes if it can be written as p + q where p > 0, q > 0 and both p and q are prime numbers.
Write a Python function that takes an integer m as input and returns True if m can be partitioned as primes and False otherwise.
Tried this, but does not work for all testcases, for example it should return True for 3432, it returns False.
def partition(num):
primelist=[]
for i in range(2,num + 1):
for p in range(2,i):
if (i % p) == 0:
break
else:
primelist.append(i)
for x in primelist:
y= num-x
for z in range(2,y):
if y%z == 0:
return False
return True
The error lies in the second for loop. You are looping through possible primes x, and wish to then check that y = num - x is also prime.
The error in your logic is that in the second for loop, if the first element in the loop y = num - x is not prime, it will return False, without checking any of the other possible values.
You could correct this by moving the return False statement out one loop, but since you have already generated a list of primes less than num, primelist (and since y = num - x, (if prime y exists) it will be in this list), you can just check for membership of the list:
for x in primelist:
y= num-x
# Note: num = x + y, thus need only check y prime
if y in primelist:
return True
# If no such y is prime, not possible
else:
return False
Note: I would advise making the logic of your script more modular, separating out the prime list generator into its own function:
def partition(num):
"""
Return True if there exist primes x,y such that num = x + y.
Else return False.
"""
primelist = primes(num)
for x in primelist:
y= num-x
# Note: num = x + y, thus need only check y prime
if y in primelist:
return True
# If no such y is prime, not possible
else:
return False
def primes(num):
"""Return list of all primes less than num."""
primelist=[]
for i in range(2,num + 1):
for p in range(2,i):
if (i % p) == 0:
break
else:
primelist.append(i)
return primelist
final solution i got:
def primepartition(m):
primelist=[]
if m<0:
return False
else:
for i in range(2,m + 1):
for p in range(2,i):
if (i % p) == 0:
break
else:
primelist.append(i)
for x in primelist:
y= m-x
if y in primelist:
return True
return False
The given below code can hopefully give you the correct output.
def factors(n):
factorslist = []
for i in range(1, n+1, 1):
if n % i == 0:
factorslist.append(i)
return(factorslist)
def prime(n):
if factors(n) == [1, n] and n > 1:
return(True)
def primelist(n):
primenolist = []
for i in range(1, n+1, 1):
if prime(i) == True:
primenolist.append(i)
return(primenolist)
def primepartition(m):
if m > 0:
primenolist = primelist(m)
checklist = []
for p in primenolist:
q = m - p
if q in primenolist and p > 0 and q > 0:
checklist.append((p,q))
if len(checklist) > 0:
return(True)
else:
return(False)
else:
return(False)
Another approach,
Initially, we store all prime elements upto m and check for pair of primes whose sum equal to m
def primepartition(a):
l=[2]#since 'a' should be >=2 for below loops, we took here 2(1st prime).
for i in range(2,a):
flag=0
for j in range(2,i):
if i%j==0:
flag=0
break
else:
flag=1
if flag==1:
l.append(i)
for i in l:
for j in l:
if i+j==a:
return True
return False
n=int(input("Enter any number: "))
list=[]
for num in range(0,n + 1):
if num > 1:
for i in range(2,num):
if (num % i) == 0:
break
else:
list.append(num)
if (n<= 1):
print("False")
#print("It is not positive ")
else:
for i in list:
y = num -i
if (y in list):
print("True")
#print(y,"+",i,"=",n)
#print(i,"+",y,"=",n)
#print("The number can be expressed as the sum of two prime numbers.")
break
else:
print("False")
#print("The number can not be expressed as the sum of two prime numbers.")
Slight Variation of your code:
def primepartition0(m):
primelist=[]
if m<0:
return False
else:
for i in range(2,m + 1):
for p in range(2,i):
if (i % p) == 0:
break
else:
primelist.append(i)
for x in primelist:
for y in primelist:
if x != y and x+y == m:
return True
return False
An alternate approach that attemps to reduce the amount of code necessary:
def primepartition(m):
if m > 3:
for number in range(m // 2, m - 1):
difference = m - number
for psuedoprime in range(2, int(number ** 0.5) + 1):
if number % psuedoprime == 0 or difference > psuedoprime and difference % psuedoprime == 0:
break
else: # no break
return number, difference # as good a non-False result as any other...
return False
def factors(n):
factlist = []
for i in range(1,n+1):
# Since factors of 2 cannot be primes, we ignore them.
if n%i==0 and i%2!=0:
factlist.append(i)
return factlist
def isprime(n):
return(factors(n)==[1,n])
def preimesupto(n):
primelist = []
if n>=2:
primelist.append(2)
for i in range(n):
if isprime(i):
primelist.append(i)
return primelist
def primepartition(n):
if n<0:
return False
primelist = preimesupto(n)
for i in primelist:
j = n-i
if j in primelist:
return True
else:
return False
If you're not required to produce the actual primes but only test if there exists a pair of primes p and q such that p+q == N, you could make this very simple based on the Goldbach conjecture. All even numbers can be expressed as the sum of two primes. So return True if the number is even and check if N-2 is prime for odd numbers (because 2 is the only even prime and that's the only prime that will produce another odd number when starting from an odd number). This will boil down to a single prime test of N-2 only for odd numbers.
def primePart(N):
return N%2==0 or all((N-2)%p for p in range(3,int(N**0.5)+1,2))
primePart(3432) # True
primePart(37+2) # True
primePart(13+41) # True
primePart(123) # False
If you want to actually find a pair of primes that add up to N, you can generate primes up to N and return the first prime >= N/2 where N - prime is one of the primes already found:
def findPQ(N):
if not primePart(N): return
if N%2: return 2,N-2
isPrime = [0]+[1]*N
for p in range(3,N,2):
if not isPrime[p]: continue
if 2*p>=N and isPrime[N-p]: return p,N-p
isPrime[p*p::p] = [0]*len(isPrime[p*p::p])
output:
findPQ(3432) # (1723, 1709)
findPQ(12345678) # (6172879, 6172799)
To go beyond 10^9 you will need a more memory efficient algorithm than the sieve of Eratosthenes that is just as fast. This can be achieved with a dictionary of multiples of primes to skip:
def findPQ(N):
if not primePart(N): return
if N%2: return 2,N-2
skip,primes = {},{2}
for p in range(3,N,2):
if p in skip:
prime = skip.pop(p)
mult = p + 2*prime
while mult in skip: mult += 2*prime
if mult <= N: skip[mult] = prime
else:
if 2*p>=N and N-p in primes: return p,N-p
if p*p<=N: skip[p*p]=p
if 2*p<=N: primes.add(p)
output (takes a while but doesn't bust memory space):
findPQ(1234567890) # (617283983, 617283907)
def checkprime(number):
fact=1
for r in range(2,number):
if number%r==0:
fact=fact+1
return(fact<2)
def primepartition(m):
for i in range(2,m):
flag=0
if checkprime(i) and checkprime(m-i)==True:
flag=1
break
return(flag==1)
def matched(s):
list_of_string=list(s)
for y in range(len(list_of_string)):
if list_of_string[y]=='(':
for z in range(y,len(list_of_string)):
if list_of_string[z]==')':
list_of_string[y]='#'
list_of_string[z]='#'
break
return('('not in list_of_string and ')'not in list_of_string)
def rotatelist(l,k):
if k>len(l):
k=int(k%len(l))
return(l[k:]+l[0:k])
This is my implementation, but it not efficient when given 6 digit number.
Input : n = 2
Output : 9009
9009 is the largest number which is product of two
2-digit numbers. 9009 = 91*99.
def isPali(x):
n = str(x)
for i in range(len(n)):
if not n[i] == n[-i-1]:
return False
return True
def isProduct(x,A):
counter = A
while counter > 1:
if x // counter <= A and x % counter == 0:
return True
else:
counter-=1
return False
def largestProduct(A):
for i in range(A*A,1,-1):
if isPali(i) and isProduct(i,A):
return i
return False
largestProduct(999999)
Let x and y be the two n-digit factors of the palindrome number.
You can iterate over them in a descending number.
Key is to stop as soon as possible, which mean, once a first solution has been found, you don't check any product below that solution.
def get_max_palindrome(n):
res = 0
for x in range(10 ** n - 1, 1, -1):
for y in range(10 ** n - 1, 1, -1):
p = x * y
if res > p:
break
if str(p) == str(p)[::-1]:
res = p
break
if (x - 1) ** 2 < res:
break
return res
print(get_max_palindrome(6))
Exec in 0.378s on my laptop.
Codewise, this is not too difficult:
n = 999999
max_pali =0
t = ()
for i in range(1,n+1):
for j in range(i,n+1):
m = i*j
s = str(m)
if s == s[::-1] and m > max_pali:
max_pali = m
t = (i,j)
print(max_pali,t)
However, this is a brute force approach. For numbers with 6 digits, this will not terminate in a reasonable amount of time. Even if it will, I could ask you the same question for 7 or 42 digits. I suggest you look for some structure, or property, of those numbers whose multiple is a palindrome. Could such a pair be any pair of numbers? Is the case 91*99 = 9009 a mere coincidence, or is there a pattern?
n = 0
for a in xrange(999, 100, -1):
for b in xrange(a, 100, -1):
x = a * b
if x > n:
s = str(a * b)
if s == s[::-1]:
n = a * b
print n
I have a question about this solution to the problem.
I know it is right but I am wondering why in the xrange(999,100,-1) the -1 is there
For the a and b for loops. Please explain. I am new to this :)
The third parameter to xrange() is the increment value. The default is 1, which means the counter will count in an increasing direction. To count in a decreasing direction, use -1. Your a counter will go from 999 to 101 (the xrange() iterator stops just before it reaches the second parameter value).
For future reference, see the xrange() documentation.
The -1 specifies a negative step. Thus moving from 999 descending to 100 (exclusive).
xrange function takes three arguments: start, stop and step.
It returns a range of numbers starting from start continuing to stop, but not including it. If 'start' is bigger than stop, negative step must be provided.
So basically xrange(999, 100, -1) will give you [999, 998, ..., 101]
It means that you are decreasing (hence the negative sign) in increments of 1, from 999 to 100
This is what I got for the project Euler #4 question:
def Palindrome(s):
if s == s[::-1]:
return True
else:
return False
i = 100
j = 100
greatest = 0
while (i <= 999):
while (j <= 999):
product = i * j
if (product > greatest and Palindrome(str(product))):
greatest = product
j += 1
j = 100
i += 1
print "Answer: " + str(greatest)
-M1K3
My Python solution:
container = []
for i in range(100, 999):
for j in range(100, 999):
num = i * j
if str(num) == str(num)[::-1]:
container.append(num)
print(max(container))
__author__ = 'shreysatapara'
f=0
for a in range(100,1000):
for b in range(100,1000):
c=a*b
d=c
s=0
x=0
for i in range(0,len(str(c))):
s=c%10
x=x*10+s
c=c//10
if(x==d):
if(x>f):
f=x
print(f)
bingo answer is your last number in compiler....
import time
start_time = time.time()
largest_number = 0
for i in range(999,100,-1):
for j in range(i,100,-1):
string_number = str(i * j)
if string_number == string_number[::-1]:
if i*j > largest_number:
largest_number = i * j
print(largest_number)
print(time.time() - start_time," seconds")
The negative one is the modifier. Basically the loops start at 999, end at 100, and get there by modifying each number by negative one.
for x in range(100, 1000):
for y in range(100, 1000):
product = x*y
if product > x*y:
break
if str(product) == str(product)[::-1] and product > 900000:
print (x, y, product)
def reverse(s):
str = ""
for i in s:
str = i + str
return str
MAXN = 0
for i in range(100, 1000):
for j in range(100, 1000):
a = i * j
b = str(a)
if b == reverse(b) and a > MAXN:
MAXN = a
print(MAXN)