how to write a code about perfect numbers in python? - python

I was trying to write a code including a function in order to find numbers that are complete(perfect number:the number which is = its denominator's summation)
but I had some problem with it...would you help me?
L=[]
def denominator(n):
k=1
while(int(k) < int(n)):
s=int(n%k)
if(s==0):
L+=[s]
k+1
return L
def isPerfect(n):
return denominator(n)
a=sum(L)
return(a==n)
n=input("enter a number:")
if(isPerfect(n)):
print("it is perfect.")
else:
print("it's not perfect.")

With #Serenity's answer and the comments to your post I think you have all that you need to correct the errors in your code. Let me also give you this nearly one-liner that does what you want:
def is_perfect(n):
return False if n <= 0 else (sum([s for s in range(1, n) if n%s == 0]) == n)

I think, this is more pythonic code for this problem:
if sum([x for x in range(1,n) if n%x==0])==n and n>0:
print "complete"
else:
print " Not complete"

You have a lot of mistakes in your code. L has to be defined in denominator; you has to add k not s to L; in while you has to increment k; denominator has to return list of dividers; you has to convert n to int after input and it is enough to check dividers until [n/2+1]. After removing these misprints your code will work:
def denominator(n):
L = []
k=1
while(k < int(n/2.+1)):
if(n%k==0):
L+=[k,]
k=k+1
return L
def isPerfect(n):
L = denominator(n)
a=sum(L)
return(a==n)
n=input("enter a number:")
if(isPerfect(int(n))):
print("it is perfect.")
else:
print("it's not perfect.")
However you may reduce your code like:
def isPerfect(n):
if (n < 1): return False
sum = 0
for k in range(1, int(n/2+1)):
if n % k == 0:
sum += k
return sum == n
print(isPerfect(6), isPerfect(28))

Related

Almost Perfect Kattis (Time Limit Exceeded )

Hope you can help me in this problem :
So the problem is Almost Perfect in Kattis.
https://open.kattis.com/problems/almostperfect
This is my code. the first test is passed but the second no it gives me am message (Time Limit Exceeded)
def isperfect(n):
l=0
for i in range(1,n):
if n%i==0:
l+=i
if l>n+2 :
print(f"{n} not perfect")
break
if(l==n):
print(f"{n} perfect")
elif abs((n-l))<=2:
print(f"{n} almost perfect")
else :
print(f"{n} not perfect")
while True:
try :
n = int(input())
isperfect(n)
except EOFError:
break;
Where is the mistake ? or how can I optimise it ?
Thank you in advance
The issue is that the code is simply too slow. Luckily, there's a simple optimization that can save you.
Note that if d is a divisor of n, then n / d is also a divisor. Furthermore, if d is lesser than sqrt(n), then n / d is greater than sqrt(n) (and vice-versa).
What this effectively means is we only need to check numbers up to sqrt(n) instead of checking all the way to n. And for every divisor d we find, we also make sure to add n / d to the divisor sum, except when d is 1 or exactly sqrt(n).
Here's what that might look like in your code:
l = 1
for i in range(1, int(sqrt(n)) + 1):
if n % i == 0:
l += i
if i < sqrt(n): l += n // i
if l > n + 2: break
Another minor bug is that when l > n + 2 you'll print the message twice, which is easily solved by removing the print before break.
import sys
import math
def almostPerfect(num):
count = 1
for i in range (2,int(math.sqrt(num)) + 1):
if(num % i == 0):
count += i
if(i*i != num):
count += num // i
if(count == num):
return "{} perfect".format(num)
elif (count == (num-2)):
return "{} almost perfect".format(num)
elif (count == (num+2)):
return "{} almost perfect".format(num)
elif (count == (num-1)):
return "{} almost perfect".format(num)
elif (count == (num+1)):
return "{} almost perfect".format(num)
else:
return "{} not perfect".format(num)
for line in sys.stdin.readlines():
line = int(line)
print(almostPerfect(line))
This could be another solution that works for python, and I think we need to take note about (i*i != num), so that we don't start adding the same number.

Get a list of prime numbers in python 3

Beginner. I'm trying to return a list that includes all the prime numbers from 0 to num. Could someone please help me find what's wrong with my code? I always get an empty list. Thanks a lot! (I'm using python 3.6)
def task(num):
num = int(num)
lst = []
if num < 3:
return lst
else:
for i in range(3,num):
if not i & 1:
lst = lst
else:
primetest = range(3, int(i ** 0.5) + 1, 2)
for n in primetest:
if i % n != 0:
lst.append(i)
return lst
task(5)
Updates:
Thank you guys for all your comments! Really helpful.
This is what my revised code looks like.
def task(num):
num = int(num)
lst = []
if num < 2:
return lst
if num >= 2:
lst.append(2)
for i in range(3, num + 1):
if i % 2 == 1:
switch = True
for n in range(3, int(i ** 0.5) + 1, 2):
if i % n == 0:
switch = False
break
if switch:
lst.append(i)
return lst
The main problem lies with your inner for loop :
With your code you will append the list with i each time you find a number in the primetestrange that is not a divisor of i.
You might want to use a boolean here to store the fact that you found a divisor of i, then only append it to the list if you didn't.
To answer your question, your list is empty because the primetestrange is always empty in your example :
int(3**0.5) + 1 = 3 and int(5**0.5) + 1 = 3
range(3,3,2) = []
The array is empty because the range function will not include the upper limit, and since the inner loop is not doing what it should be expected to do in your code, the result will be an empty list until the parameter of the task function is superior or equal to 9
Your code gets it wrong on several counts, tell me if you understand why the following works?
def task(num):
num = int(num)
lst = [2]
if num < 3:
return lst
for i in range(3, num + 1):
if i % 2 == 1:
for n in range(3, int(i ** 0.5) + 1, 2):
if i % n == 0:
break
else:
lst.append(i)
return lst
(note: the for else clause is quite natural here, for else clauses are used when you search for something in a loop, you break when you find that something, if not break is encountered and the regular stopIteration is used to exit the loop the else part is performed, I say it is natural here since in pseudo code you would say something like "if my number can be divided by another number less than its square it is not prime, otherwise add it to the list of primes" see http://book.pythontips.com/en/latest/for_-_else.html for more detauls)
Its by no means a fast way to do it but I tried to stay as close to the spirit of your attempt while improving the aesthetics of the code
you can find prime numbers and the most dividable one in a dateset.`
a=[ int(x) for x in input("Enter 10 values: ").split() ]
c=[]
prime=[]
b=max(a)
for num in range(1,b+1):
for i in range(2,num):
if (num%i)==0:
break
else:
prime.append(num)
for i in a:
for j in prime:
if i%j==0:
c.append(i)
from collections import Counter
e=Counter(c)
f=e.most_common(1)
f
def prim(z):
lst = []
for i in range(2, z+1):
for j in range(2,i):
if i % j == 0:
break
else:
lst = lst + [i]
return lst
print(prim(20))
result:
[2, 3, 5, 7, 11, 13, 17, 19]

Finding the largest palindrome of the product of two 3-digit numbers in Python

So the challenge I'm trying to solve is to find the largest palindrome made from the product of two 3-digit numbers. I'm new to Python and so my code is not elegant or refracted yet, but there is a logical error that I can't seem to find.
def ispalindrome(n):
rev_n = str(n)[::-1]
if n == rev_n:
return True
else:
return False
first_num = 100
second_num = 100
mylist=[]
while first_num < 1000:
while second_num < 1000:
item = first_num * second_num
mylist.append(item)
second_num += 1
second_num = 100
first_num +=1
# print (mylist)
num_as_string = []
for i in mylist:
i = str(i)
num_as_string.append(i)
print("Total products of two 3-digit numbers: {}").format(len(num_as_string))
print("-----------------------------------------------------")
def convert_to_num_list(string_list):
new_num_list = []
item = int(string_list)
new_num_list.append(item)
return new_num_list
palindrome_list = []
for j in num_as_string:
if ispalindrome(j) == True:
palindrome_list.append(j)
palindrome_list.sort()
# print(palindrome_list)
x = convert_to_num_list(j)
largest_palindrome = max(x)
print("Total palindroms of product of two 3-digit numers: {}").format(len(palindrome_list))
print("Largest palindrome = {}").format(largest_palindrome)
The problem is that I'm getting the largest palindrome as 580085, which is 995*583 but is NOT the largest palindrome. I believe the largest palindrome is 906609, which is 993*913, but my code is not finding this. Can anyone help me with the flaw in my logic?
Your code does a lot of unnecessary conversion between numbers and strings, which made the error hard to find. The only place in the code that needs a string representation is when determining if the number is a palindrome or not. So that should be the only place that the code does the conversion.
The logic error is in your function convert_to_num_list(). It takes a string representation of one number and returns a 1-list containing that number. So, "123321" gets returned as [123321]. You then take the max() of that 1-list, which is always the value that was passed to convert_to_num_list(). So the code never keeps the largest value because if a smaller value comes in later it will be overwritten. The code reports 995*583 as the largest because it comes in later than 993*913, which in turn is because 995 > 993.
You can fix that error with an if statement, but the program is overcomplicated and may well contain other bugs. I recommend reducing the code to the essential task of producing the largest palindrome, without printing out the intermediate results, because the simpler the code the easier it is to see a logic error.
def ispalindrome(n):
return str(n) == str(n)[::-1]
mylist=[]
for first_num in range(100,1000):
for second_num in range(100,1000):
item = first_num*second_num
if ispalindrome(item):
mylist.append(item)
print(max(mylist))
This gives your expected answer:
906609
Here is a function for finding the largest palindrome of the product of two 3-digit numbers that I found in stackoverflow.
Link to what i found- https://stackoverflow.com/a/7460573
def is_pal(c):
return int(str(c)[::-1]) == c
maxpal = 0
for a in range(999, 99, -1):
for b in range(a, 99, -1):
prod = a * b
if is_pal(prod) and prod > maxpal:
maxpal = prod
print maxpal
n1=999
n2=999
k=0
sl=[]
while n1>1:
count=n1
while count>=1:
result=n1*count
res=str(result)
res1=res[::-1]
if (res==res1):
sl.insert(k,result)
k+=1
count=count-1
n1=n1-1
print("largest pelindrom of 3 digit product is is %d" %(max(sl)))
palin=[]
for a in (range(1,1000)):
for b in (range(1,1000)):
d = a*b
d=str(d)
if len(d)>5:
if d[0]==d[5]:
if d[1]==d[4]:
if d[2]==d[3]:
palin.append(d)
palin.sort()
print(palin[len(palin)-1])
Using List comprehension can reduce the lines of code but i'll give an alternate option so that it's more readable.
List_of_palindromes = [i*j for i in range(100,1000) for j in range(i,1000) if str(i*j)==str(i*j)[::-1]]
print(max(List_of_palindromes))
More Readable form
List_of_palindromes = []
for i in range(100,1000):
for j in range(100,1000):
if str(i*j)==str(i*j)[::-1]:
List_of_palindromes.append(i*j)
print(max(List_of_palindromes))
Check this out..!
This can be shortened but its better understandable this way(for beginners).
l = list(range(100, 1000))
m = list(range(100, 1000))
prod_max = 0
def is_palindrome(num):
temp = num
rev=0
while num > 0:
div = num%10
rev = rev*10 + div
num = num //10
if rev == temp:
return True
else:
return False
for i in range(len(l)):
for j in range(len(m)):
prod = l[i]*m[j]
if is_palindrome(prod) == True:
if prod > prod_max:
prod_max = prod
num1 = l[i]
num2 = m[j]
print(f'{prod_max} the product of {num1} and {num2} is a palindrome')

How to write a recursive function for palindromic primes?

I have been trying to write a Python program which uses a recursive function to find the palindromic primes between two integers supplied as input. Example of palindromic prime: 313
I already know how to write a recursive function for palindromes, but I am struggling with this one a lot. I would appreciate any help. Thanks
recursive function for palindromes
Presumably to do the palindrome check recursively you check the outer characters:
def is_pali(s):
if len(s) <= 1:
return True
else:
return s[0] == s[-1] and is_pali(s[1:-1])
Now you can iterate over the numbers and see which are palindromes:
[i for i in range(n, m) if is_pali(str(i))]
Since 30000 is the limit, this works (101101 is the smallest number it gets wrong):
>>> [n for n in range(2, 500) if str(n) == str(n)[::-1] and (2**n-1)%n == 1]
[2, 3, 5, 7, 11, 101, 131, 151, 181, 191, 313, 353, 373, 383]
You can of course also use the (2**n-1)%n == 1 primality test in your own recursive palindrome function that you already have.
http://en.wikipedia.org/wiki/Fermat_primality_test
Probably you already went through this idea but here's what I would do...
If you have a palindrome function like this one:
def palindrome(word):
if len(word) == 1 or (len(word) == 2 and word[0] == word[1]):
return True
else:
if word[0] == word[len(word)-1]:
return palindrome(word[1] + word[len(word)-2])
else:
return False
And let's say you have a function to figure out if a number is prime (this I take from here):
def is_prime(number):
if number > 1:
if number == 2:
return True
if number % 2 == 0:
return False
for current in range(3, int(math.sqrt(number) + 1), 2):
if number % current == 0:
return False
return True
return False
You can just call the validation when you find out if your number is a palindrome (casting it to str first).
The missing part is generate the combination of the two integers you might get but well, that's a simple one.
Hope this helps.
-Edit:
Adding a recursive function for getting primes:
def prime(number,limit = 1):
if limit == number:
return True
else:
if number % limit == 0 and limit != 1:
return False
else:
return prime(number, limit + 1)
Instead of recursive solution, what about using more effective list slicing?
def isPalindrome(number):
nstr = str(number)
return nstr == nstr[::-1]
This works by converting the number to string and comparing it's reversed counterpart. There is also known algorithm for determining the palindrome,
using global variable:
sum = 0
def is_palindrome(number):
return palindrome_sum(number) == number
def palindrome_sum(number):
global sum
if number != 0:
remainder = number % 10
sum = sum * 10 + remainder
palindrome_sum(number / 10) * 10 + remainder
return sum
For mathematical recursive function without global variable, this algorithm can be used:
import math
def is_palindrome(number):
return palindrome_sum(number) == number
def palindrome_sum(number, sum=0):
iters = 0
if number != 0:
iters = int(math.log10(number))
remainder = number % 10
sum = palindrome_sum(number / 10) + remainder * 10 ** iters
return sum
It uses the length of number to find it's position in the resulting number. The length can be computed by int(math.log10(number)).
This solution uses the Sieve of Eratosthenes to find the prime numbers less than n. It then uses a basic palindrome check which of those prime numbers are palindromes. The check avoids converting the ints to strs, which is a time consuming operation.
#!/usr/bin/env python2.7
def primeslt(n):
"""Finds all primes less than n"""
if n < 3:
return []
A = [True] * n
A[0], A[1] = False, False
for i in range(2, int(n**0.5)+1):
if A[i]:
j = i**2
while j < n:
A[j] = False
j += i
return (num for num in xrange(n) if A[num])
def is_palindrome(n):
digits = []
while n > 0:
digits.append(n%10)
n /= 10
return digits == digits[::-1]
def main():
while True:
try:
i = int(raw_input("Palindromic primes less than... "))
break
except ValueError:
print "Input must be an integer."
print filter(is_palindrome, primeslt(i))
if __name__ == '__main__':
main()
If you have any questions about how this code works, feel free to ask me by commenting on my answer. Best of luck!

How do I print a fibonacci sequence to the nth number in Python?

I have a homework assignment that I'm stumped on. I'm trying to write a program that outputs the fibonacci sequence up the nth number. Here's what I have so far:
def fib():
n = int(input("Please Enter a number: "))
if n == 1:
return(1)
elif n == 0:
return(0)
else:
return (n-1) + (n-2)
mylist = range[0:n]
print(mylist)
I'm thinking I could use separate functions but I can't figure out how to pass the argument that calculates the fibonacci sequence. Then the next step would be to to print out the sequence of numbers up to that number.
Non-recursive solution
def fib(n):
cur = 1
old = 1
i = 1
while (i < n):
cur, old, i = cur+old, cur, i+1
return cur
for i in range(10):
print(fib(i))
Generator solution:
def fib(n):
old = 0
cur = 1
i = 1
yield cur
while (i < n):
cur, old, i = cur+old, cur, i+1
yield cur
for f in fib(10):
print(f)
Note that generator solution outperforms the non-recursive (and non-recursive outperforms recursive, if memoization is not applied to recursive solution)
One more time, recursive with memoization:
def memoize(func):
memo = dict()
def decorated(n):
if n not in memo:
memo[n] = func(n)
return memo[n]
return decorated
#memoize
def fib(n):
#added for demonstration purposes only - not really needed
global call_count
call_count = call_count + 1
#end demonstration purposes
if n<=1:
return 1
else:
return fib(n-1) + fib(n-2)
call_count = 0 #added for demonstration purposes only - not really needed
for i in range(100):
print(fib(i))
print(call_count) #prints 100
This time each fibbonacci number calculated exactly once, and than stored. So, this solution would outperform all the rest. However, the decorator implementation is just quick and dirty, don't let it into production. (see this amazing question on SO for details about python decorators :)
So, having fib defined, the program would be something like (sorry, just looping is boring, here's some more cool python stuff: list comprehensions)
fib_n = int(input("Fib number?"))
fibs = [fib(i) for i in range(fib_n)]
print " ".join(fibs)
this prints all numbers in ONE line, separated by spaces. If you want each on it's own line - replace " " with "\n"
def fibonacci(n):
if n <= 1:
return n
else:
return fibonacci(n-1) + fibonacci(n-2)
print(fibonacci(int(input())))
And since you want to print up to the nth number:
[print(fibonacci(n)) for n in range (int(input()))]
And for python2.7 change input to raw_input.
Please note, in your call
You are not calling fib() recursively
You need a wrapper method so that the input is not requested every time the method is called recursively
You do not need to send in a list. Just the number n is good enough.
This method would only give you the nth number in the sequence. It does not print the sequence.
You need to return fib(n-1) + fib(n-2)
def f():
n = int(input("Please Enter a number: "))
print fib(n)
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1)+fib(n-2)
This might be faster incase of long list
# Get nth Fibonacci number
def nfib(nth):
sq5 = 5**.5
phi1 = (1+sq5)/2
phi2 = -1 * (phi1 -1)
resp = (phi1**(nth+1) - phi2**(nth+1))/sq5
return long(resp)
for i in range(10):
print i+1, ": ", nfib(i)
OUTPUT
1 : 1
2 : 1
3 : 2
4 : 3
5 : 5
6 : 8
7 : 13
8 : 21
9 : 34
10 : 55
def fib(n):
if n == 1:
return(1)
elif n == 0:
return(0)
else:
return fib(n-1) + fib(n-2)
my_num = int(input("Enter a number:"))
print fib(my_num)
Im not really sure what your question is... but the answer is probably something like this
Separate functions would be best, as the recursive function would be far easier to deal with. On the other hand, you could code an iterative function that would take only one parameter
Recursively::
def fib(n):
if n == 1:
return (1);
elif n == 0:
return (0);
else:
return fib(n-1) + fib(n-2);
def callFib():
n = int(raw_input('Enter n::\t'));
mylist = fib(n);
print mylist;
callFib();
Iteratively::
def fib():
n = int(raw_input('Enter n::\t'));
terms = [0,1];
i=2;
while i<=n:
terms.append(terms[i-1] + terms[i-2]);
i=i+1;
print terms[n];
fib();
for a recursive solution:
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
x=input('which fibonnaci number do you want?')
print fib(x)
explanation:
if n is 0, then ofcourse the '0th' term is 0, and the 1st term is one. From here, you know that the next numbers will be the sum of the previous 2. That is what's inferred by the line after the else.
It looks like you might be trying to solve the same homework problem I was, where you don't actually need user input. You just pass in the parameter when you call the function.
def compute_nth_fib(num):
if num == 0:
return 0
elif num == 1:
return 1
else:
return compute_nth_fib(num-1) + compute_nth_fib(num-2)
#test with different parameters
print(compute_nth_fib(3))
Hope that's helpful to someone!

Categories