Almost Perfect Kattis (Time Limit Exceeded ) - python

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.

Related

Function displays nothing after returning

import math
def erathosthene(n):
for d in range(2, int(math.sqrt(n) + 0.5)):
while n % d != 0:
d =+ 1
if n % d == 0:
print('this number isn\'t prime')
return False
else:
print('this number is prime')
return True
erathosthene(35)
it literally display nothing and honestly idk why it display nothing
there's nothing after return in terminal
What you're doing is a primality test and the problems of your code are
let the for loop increase d, don't increase it by yourself too
if n is divisible by d then you end as it is not prime
if n is NOT divisible by the current d, that doesn't mean it is prime, you wait to wait
loop until sqrt(x)+1 not sqrt(x)+0.5, because for
add condition for numbers < 2
def erathosthene(n):
if n < 2:
return False
for d in range(2, int(math.sqrt(n) + 1)):
if n % d == 0:
return False
return True
Then call with a print so your code displays something
print(erathosthene(6))
For better implementation, you can see isPrime Function for Python Language for example

Python Beginner Question “Prime Number Count”

def prime_count(a, b):
for i in range(a,b):
if i % 2 != 0:
return sum(i)
else:
return 0 "
I am a beginner programmer, I have been practicing on some challenges on Edabit, small problems but that require some thinking (for me).
I am trying to count how many prime numbers are on a and b, they are already integers and there is no user input.
I am not very good at loops yet and thought this was going to be a good challenge to practice, what am I doing wrong? I keep getting int object is not iterable
If reference need, here is the link for the challenge.
Link : https://edabit.com/challenge/6QYwhZstMuHYtZRbT
it is an interesting problem that you are solving. You will have to run two-loops here. One to iterate from a to b and the inner loop to check if each element in a -->b is prime or not (the inner loop should run from 2 to j in [a,b).
def primecheck(a,b):
printlist=[]
if a > 1:
for i in range(a,b+1):
for j in range(2,i):
if i % j == 0:
break
else:
printlist.append(i)
if len(printlist) == 0:
return 0
else:
return len(printlist), printlist
Try this out.
As people say in the comment section, calling sum() is what's causing an error.
But, even if you somehow got that part right, you wouldn't quite get what you want. Maybe you were just trying a simple for loop to check if numbers are odd...?
Anyway, I normally like using Sieve of Eratosthenes to generate prime numbers because it's simple.
def sieve_of_eratosthenes(start, end):
if start > end:
raise AssertionError
# end = end + 1 # If end is inclusive, then uncomment this line.
if end < 2:
return 0
sieve = [i for i in range(2, end)] # Initialize an array of number from 2 to end.
size = len(sieve)
p = 2 # Initial prime.
count = 0
# This block implements Sieve of Eratosthenes.
while count < size:
for i in range(count, size):
num = sieve[i]
if num != p and num % p == 0:
sieve[i] = 0
if count == size-1:
break
count += 1
while sieve[count] == 0:
count += 1
if count == size-1:
break
p = sieve[count] # Update the next prime.
# This block calculates the numbers of primes between start and end.
num_of_primes = 0
for p in sieve:
if p == 0 or p < start:
continue
num_of_primes += 1
print(sieve)
return num_of_primes
sieve_of_eratosthenes(1, 100) # This should return 25.

How to print the 1398th prime number in python? [duplicate]

This question already has an answer here:
finding nth prime in python
(1 answer)
Closed 3 years ago.
hey guys i'm newbie please tell me how to make this code work to print the 1398th prime number.
https://code.sololearn.com/c1a3lvSiIF9w/?ref=app
#newbie
def IsPrime(X):
IsPrime = 1
for i in range(2):
if i < X:
if X % i == 0:
IsPrime = 0
if IsPrime == 0:
print ("X Is Prime")
else:
print ("X Is Not Prime")
else:
i = i + 1
else:
if IsPrime == 0:
print ("X Is Prime")
else:
print ("X Is Not Prime")
#newbie
for i in range(2):
C = 0
if C < 1398:
if IsPrime(i) == 1:
C = C + 1
i = i + 1
else:
i = i + 1
else:
print (i - 1)
#newbie
There were a few errors with your code structre. Ive also tried to make your code a little cleaner. Try to follow the PEP8 python style guide, it helps with making code more readable and understandable to others.
This should do the trick:
def IsPrime(X):
count = 0
for i in range(X):
if X % (i + 1) == 0:
count = count + 1
if count == 2:
return True
else:
return False
def findPrime(n):
count = 0
i = 1
while count < n:
if IsPrime(i) == True:
count = count + 1
i = i + 1
return i - 1
print (findPrime(1398))
If you're dealing with reasonably small numbers, the following algorithm will find first N primes:
N = 1398
primes = [1]
n = primes[-1]
while len(primes) < N:
n, d = n + 1, None
for p in primes:
if p > 1 and n % p == 0:
d = p
break
if not d:
primes.append(n)
# first 10 primes
print(primes[:10])
# 1398-th prime
print(primes[-1])
What does it do?
start with some known primes (no one missing from that range)
let n be the last prime plus one
let d be any known prime p but 1 dividing n
if no d was found, n is prime
stop after finding N primes

Which is the most pythonic way for writing a prime number function using for and while loop?

I am about to execute a function which aim is to return a Prime/Not prime statement if its argument is or isn't a prime number. I succeeded using a for loop:
def prime1(n):
z = []
for i in range (1, n+1):
if (n/i).is_integer():
z.append(i)
i=i+1
if len(z) == 2:
print ("Prime")
else:
print ("Not prime")`
Then I tried to do the same but using the while loop:
def prime2(n):
z = []
i = 1
while i < int(len(range(1, n+1))):
if (n/i).is_integer():
z.append(i)
i=i+1
if len(z) == 2:
print ("Prime")
else:
print ("Not prime")
Unfortunately, my system continues to calculating without printing me an output.
Can you explain me where I have made a mistake?
The i = i + 1 does nothing in your for loop, since the value of i is overwritten with the next value of the iterator; effectively, the for loop is performing i = i + 1 for you on every iteration, whether or not i divides n. You need to do the same thing in your while loop:
while i < n + 1:
if (n/i).is_integer():
z.append(i)
i = i + 1
The most pythonic way I could think of is below:
def isPrime(n):
return all(n % i for i in range(2, int(n ** 0.5) + 1)) and n > 1
for i in range(1, 20):
print(isPrime(i))
Explanation:
all makes sure that every item in the given expression returns True
n % i returns True if n != 0 (even negative numbers are allowed)
int(n ** 0.5) is equivalent to sqrt(n) and as range always returns numbers up to n - 1 you must add 1
n > 1 makes sure that n is not 1
The problem in your code is that your i = i + 1 in the wrong scope
Your program checks if (n/i).is_integer() which returns False as n / 2 is not a integer
Improving your code:
Instead of (n/i).is_integer() you can use n % i == 0, which returns the remainder equals 0
Next you must place i = i + 1 in the outer scope
And personally, I was never a fan of i = i + 1. Use i += 1
I think the best way is using the code I have shown above.
Hope this helps!
Edit:
You can make it print 'Prime' or 'Not Prime' as follows:
def isPrime(n):
print('Prime' if all(n % i for i in range(2, int(n ** 0.5) + 1))
and n > 1 else 'Not Prime')
for i in range(1, 20):
isPrime(i)
You are increment the iterable variable i inside the if statement, so the variable is never incremented, stucking on an infinite loop.
When you used for it worked because the iterable changes itself after every full iteration of the block.
Moving the incremenf of i one identation block to the left (inside the while instead of for) will work just fine
Code adapted from https://www.programiz.com/python-programming/examples/prime-number
You don't need to check until num and you can go 2 by 2 if you don't have a database of prime numbers
import math
#num = 437
if num > 1:
# check for factors
for i in range(2, int(math.ceil(math.sqrt(num))), 2):
if (num % i) == 0:
print(num, "is not a prime number")
print(i, "times", num // i, "is", num)
break
else:
print(num, "is a prime number")
# if input number is less than
# or equal to 1, it is not prime
else:
print(num, "is not a prime number")
Our preferred method should not be while loops if we don't need to use them, that being said, we could use list comprehensions:
def prime(n):
z = []
[z.append(i) for i in range(1, n+1) if (n/i).is_integer()]
[print("Prime") if len(z) == 2 else print("Not Prime")]
prime(101)
But lets take a loop at what you got your for loop:
for i in range (1, n+1):
if (n/i).is_integer():
z.append(i)
i=i+1
The line i = i + doesn't serve the purpose you intend, the loop is going to iterate from 1 to n+1 no matter what
Now the while loop:
while i < int(len(range(1, n+1))):
if (n/i).is_integer():
z.append(i)
# i=i+1 does not go inside if statement
i += 1
Now you do need to increment i but if that incrementing only occurs when the if conditions are met, then if the if condition is not met you are going to be stuck at the same i looping over it.
Also try using i += 1 means the same thing

how to write a code about perfect numbers in 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))

Categories