FIND THE PERFECT NUMBER IN PYTHON - python-3.x

I do have an answer already but I'm curious if there's a better method on coding this problem through python. Thank you.
A number is called a perfect number if it is equal to the sum of all of its divisors, not including
the number itself. For instance, 6 is a perfect number because the divisors of 6 are 1, 2, 3, 6
and 6 = 1 + 2 + 3. As another example, 28 is a perfect number because its divisors are 1, 2, 4,
7, 14, 28 and 28 = 1 + 2 + 4 + 7 + 14. However, 15 is not a perfect number because its divisors
are 1, 3, 5, 15 and 15 6= 1 + 3 + 5. Write a program that finds all four of the perfect numbers
that are less than 10000.

Here is my answer.
for i in range(1,10000):
summ = 0
for m in range(i):
if i % (m+1) == 0:
summ = summ + (m+1)
g = summ - i
if g == i :
print(g)

Here is perfect number algorithm that checks for perfect numbers using the Lucas Lehmer Test:
def ffs(x):
return (x&-x).bit_length()-1
def levelx(N, withstats=False):
if N <= 1: return False
temp = N
newlevel = temp.bit_length()
primetest = temp//(2**(ffs(temp)))
offset = temp//primetest
s = 4
nextlevel = newlevel // 2
check = temp // (2**nextlevel)
prevtemp = 2**nextlevel
if withstats == True:
print (newlevel, newlevel, temp)
print (newlevel, nextlevel+one, prevtemp)
if (prevtemp & (prevtemp-1) == 0) and prevtemp != 0:
if offset.bit_length() == primetest.bit_length():
if ((primetest+1) & ((primetest+1)-1) == 0):
for x in range(primetest.bit_length()-1):
s = (s * s - 2) % primetest
if withstats == True:
print(s)
if s in [0,2]: return True
return False
else: return False
else: return False
else: return False
Here is the output:
In [645]: for x in range(2,100):
...: if levelx((2**(x-1))*(2**x-1)) == True:
...: print(x, (2**(x-1))*(2**x-1))
...:
...:
2 6
3 28
5 496
7 8128
13 33550336
17 8589869056
19 137438691328
31 2305843008139952128
61 2658455991569831744654692615953842176
89 191561942608236107294793378084303638130997321548169216
You can use gmpy2 to speed these up by about 10x.

for j in range(1,10000):
sum=0
for I in range(1,J):
if J%I==0:
sum= sum + I
if j==sum:
print(J," is a perfect square")

Related

Adding together elements contained in two lists

I am trying to add elements of two lists together e.g. listing all integers below 10 that are multiples of 3 or 5. The sum of these multiples should be 23 (3+5+6+9) but I keep getting 18. I have only just starting programming and learning python. Here's my code:
for i in range (1,10):
if i % 3 == 0:
print(i)
for x in range (1,10):
if x % 5 ==0:
print(x)
sum_multiples=i+x
print(sum_multiples)
What you are trying to do:
3 + 6 + 9 + 5 = 23
What you are doing:
9 + 9 = 18
This is what you want:
l1 = [x for x in range(1, 10) if x % 3 == 0]
l2 = [x for x in range(1, 10) if x % 5 == 0]
print(sum(l1) + sum(l2))
First off, let me address your problem. When you add variable i and variable x, they are both value of 9. This is because after the loop their value is 9, and because you are adding the values after the loop, you are adding 9 + 9.
You can fix this by making a variable outside the loop and adding the number to the variable. My code would be:
total = 0
for i in range (1,10):
if i % 3 == 0:
print(i)
total = total + i
for x in range (1,10):
if x % 5 ==0:
print(x)
total = total + x
print(total)
(this is just based off what you were doing, I would probably condense it into one loop)
You could so something like this:
sum_multiples = 0
for i in range(1, 10):
if i % 3 == 0 or i % 5 == 0:
sum_multiples += i
print(sum_multiples)
If you prefer a one line solution:
print(sum(i for i in range(1, 10) if i % 3 == 0 or i % 5 == 0))

Finding sum of n odd numbers following a given integer

Read an integer N that is the number of test cases that follows. Each test case contains two integers X and Y. Print one output line for each test case that is the sum of Y odd numbers from X including it if is the case. For example: for the input 4 5, the output must be 45, that is: 5 + 7 + 9 + 11 + 13 for the input 7 4, the output must be 40, that is: 7 + 9 + 11 + 13
Try this I was just working on it.
x = int(input("Enter Value of X: "))
y = int(input("Enter Value of Y: "))
result = 0
itt = 0
while itt != y:
if x % 2 == 0:
x += 1
else:
itt += 1
result += x
x += 1
print(result)

How to find number in list which has the biggest number of prime?

I want to write a program that receives 10 entries and at the end it should print the number that has the greatest number of prime factors along with the number of its prime factors in the output. And, if some of the inputs have the same condition, the program will print the biggest one.
The code that I wrote executed all conditions except the final condition.
How should I write a code for a case where two numbers have the same numbers of prime factors (when I want the bigger number to be my output)?
For example both 678 and 84 have 3 prime factors . The output of my code is 84, while I want the output to be 678 (the bigger number).
input:
123
43
54
12
76
84
98
678
543
231
Correct output:
678 3
but my output:
84 3
a = [0,0,0,0,0,0,0,0,0,0]
#a = [123,43,54,12,76,84,98,678,543,231]
b = [0,0,0,0,0,0,0,0,0,0]
def is_first (number):
Prime_number= 0
for m in range(1, (number //2)+1, 1):
if number % m == 0:
Prime_number += 1
if Prime_number > 1:
is_prime = 0
else:
is_prime = 1
return is_prime
for i in range(0,10,1):
a[i] = input()
for j in a:
numbers= 0
for k in range(2, int(j)//2, 1):
if int(j) % k == 0:
if is_first (k) == 1:
numbers += 1
b[a.index(j)] = numbers
index_of_same = [i for i, e in enumerate(b) if e == max(b)]
n = []
for t in index_of_same:
n.append(a[t])
print(str(max(n))+ ' ' + str(max(b)))
When you append the numbers that have the highest number of prime factors to the list n, you are storing them as strings and not integers. Hence when you do the max() function on n, which holds 84,678 and 231, 84 is returned. I would suggest you to convert the numbers using int(), when storing into n and then perform the max()function on it. Just tweak your code as under:
for t in index_of_same:
n.append(int(a[t]))
Your code is cumbersome IMO, so I'd like to suggest a simpler version:
def getNumOfFactors(n):
num = 0
factor = 1
while n > 1:
factor += 1
if n % factor == 0:
num += 1
n /= factor
while n % factor == 0:
n /= factor
return num
def getMaxValue(values):
factors = [getNumOfFactors(n) for n in values]
tuples = zip(factors,values)
sorted_tuples = sorted([tuple for tuple in tuples],key=lambda x: x[0])
max_tuples = [tuple for tuple in sorted_tuples if tuple[0] == sorted_tuples[-1][0]]
sorted_max_tuples = sorted([tuple for tuple in max_tuples],key=lambda x: x[1])
return sorted_max_tuples[-1]
maxValue = getMaxValue([123,43,54,12,76,84,98,678,543,231])
print(maxValue)

Why are some of the iterations of for loop skipped in this code?

The execution of body of the for loop is skipped at multiple times.
I tried running this code and got unexpected results. I noticed while debugging that some times the body of the for loop is just not executed. I checked for wrong indentation, but it seems fine.
def getOutput (X):
# Write your code here
sum = 0
if int(X) not in setA:
setA.append(int(X))
setA.sort()
for a in range(len(setA)-1):
if a == 0:
low = 1
else:
low = setA[a-1] + 1
sum += low
if a == (len(setA)-1):
high = N
else:
high = setA[a+1] - 1
sum += high
#print(setA, a, low, high)
return sum
N, M = map(int, input().split())
setA = []
while M > 0:
X = input()
out_ = getOutput(X)
print (out_)
M -= 1
Sample Input:
10 10
2
7
5
9
6
1
8
10
3
4
Expected output for the above input:
11
20
30
46
58
61
77
96
102
110
The for loop should be for a in range(len(setA)):
instead of for a in range(len(setA)-1):
I have tried to iterate the loop for all indices in the list.
range(len(setA) - 1) excludes the iteration for the last element of the list.
This is because the range function by default excludes the last element.
eg: range(5) would give us [0, 1, 2, 3, 4].
So no need to add the -1 in the above code.

Print prime numbers in a range of given numbers

I'm trying to print all primes into a range of given numbers (low and max, given numbers included).
For example:
num1=10, num2=20
>>> 11, 13, 17, 19
My code fails in some occasions and I can't understand why:
num1 = int(input('First number is: '))
num2 = int(input('Second number is: '))
if num2 <= num1:
num1,num2 = num2,num1
for i in range(num1, num2+1):
for p in range(2,int(num2**0.5)+1):
if i%p == 0:
break
else:
print(i,' ',end = '')
print('\n')
Results:
1 to 7 >>> 1 3 5 7 (omits 2)
1 to 30 >>> 1 7 11 13 17 19 23 29 (omits 2,3,5)
1 to 60 >>> 1 7 11 13 17 19 23 29 (omits 2,3,5,7)
0 to 0 >>> 0 (prints 0 -> not a prime number)
0 to 7 >>> 1 3 5 7 (omits 2)
How can I correct this? Thanks a bunch!
ps. number 1 is not a prime too.
The mistake in your code was not having an i in the second part of the inner for loop range as opposed to num2
num1 = int(input('First number is: '))
num2 = int(input('Second number is: '))
if num2 > num1:
num1, num2 = num2, num1
for i in range(num1, num2+1):
if i == 0 or i == 1: continue
for p in range(2,int(i**0.5)+1): # the second part should be int(i**0.5) + 1, not int(num2**0.5)+1
if i%p == 0:
break
else:
print(i,' ',end = '')
Also rather than having two branches for num1 < num2 and the other way around, you can do something like below. Further in terms of code design, it would be better to decompose this slightly into an is_prime method. That way, if you ever want to write a quicker primality tester, you could easily edit the helper function as opposed to messing with the main code.
def is_prime(num):
if i == 1: return False
for p in range(2,int(num**0.5)+1):
if num % p == 0:
return False
return True
inp1 = int(input('First number is: '))
inp2 = int(input('Second number is: '))
num1 = min(inp1, inp2)
num2 = max(inp1, inp2)
for i in range(num1, num2+1):
if is_prime(i):
print(i,' ',end = '')
print('\n')
You didn't consider the division of the number by the number itself into consideration.
i.e. When range was 1 to 30, sqrt(30)+1 = 5+1 = 6, all nos below six had a case where they were divided by the number itself as 2%2,3%3 ... i%i.
Workaround would be to change the range of inner for loop as :
for i in range(num1, num2+1):
for p in range(2,int(i**0.5)+1): #Change num2 to i to avoid i%i
if i%p == 0:
break
else:
print(i,' ',end = '')
It is better to abstract the code like the one done by gowrath to avoid mistakes.

Resources