Unexpected output in Euler projects (project number 3) - python

I am attempting Project Euler Problem 3 with 13195 as the sample number and seem to have become stuck. Any help would be appreciate and maybe a nudge in the right direction.
This is to develop my python understanding.
multiples=[]
n = 13195
for i in range(1, 13196):
if n%i ==0:
multiples.append(i)
for m in multiples:
if n>m>1:
for y in (2, m):
if not m%y==0:
print (m)
I was expecting the output to be:
5
7
13
29
But I get all the factors of 13195.

The issue is with the prime number calculation part of your code snippet.
Say multiples has the value:[1, 5, 7, 13, 29, 35, 65]. When the applications goes to the loop for y in (2, m),
Iteration 1:
for y in (2, 5)
Initially, y is 2 and it does 5%2 and prints 5 since 5%2 is not 0. Then y will become 5 and it does 5%5 and prints nothing.
...
Iteration 7:
for y in (2, 65)
Initially, y is 2 and it does 65%2 and prints 65 since 65%2 is not 0. Then y will become 65 and it does 65%65 and prints nothing.
Since you used for y in (2,m) instead of for y in range (2,m), the loop will always execute twice, with the values of y=2 and y=m.
Basically, you do % operation on all the multiples with 2 and itself instead of calculating the prime. Below is an example snippet to achieve the desired output.
for m in multiples:
if n>m>1:
for y in range (2, (int)(m/2)):
if m%y==0:
flag=1
if flag==0:
print (m)
flag=0

import sympy
multiples=[]
n = 13195
for i in range(1, 13196):
if n%i ==0:
multiples.append(i)
for m in multiples:
if n>m>1:
if sympy.isprime(m):
print(m)
the rule of python is not to create function that is already created by others. the isprime function is already created so no need for recreating it.
multiples=[]
n = 13195
for i in range(1, 13196):
if n%i ==0:
multiples.append(i)
for m in multiples:
if n>m>1:
for i in range(2, m//2):
# If num is divisible by any number between
# 2 and n / 2, it is not prime
if (m % i) == 0:
break
else:
print(m)
it is using else with for loop concept, if the for loop breaks, the else part will not execute, if the for loop successfully completes without breaking, the else part will be executed.

Related

Python printing many times over for single print

My code is:
for n in range(1,10000000):
if n>1:
for i in range(2,n):
if n % i == 0:
break
else:
v = 2+n
for i in range(2,v):
if v % i == 0:
break
else:
print(n,v)
When I run the code, it prints multiple of each number with each having a random number of the particular two numbers. I am having trouble fixing the code. I have asked others who are more well-versed in coding than I am, but they were unable to solve the problem. Help would be greatly appreciated. Thank you!
The output is not random, but as the desired output is not defined, I'll start with explaining what the current algorithm actually does;
The code can be split in to two main functionalities. The first functionality looks for a prime number n. If n is not prime, the code continues to the next n:
for n in range(1,10000000):
if n>1:
for i in range(2,n):
if n % i == 0:
break
The second functionality comes into play only if n is prime (a clever use of for..else). It will now check to see if n+2 is divisible by any number from 2 up to n+1. I took the liberty of replacing v with n+2 in the following snippet, as I believe it makes things a bit clearer;
else:
#v = 2+n # taking liberty..
for i in range(2, n+2):
if (n+2) % i == 0:
break
else:
print(n, n+2)
To illustrate what actually happens, I chose primes 5, 7, 11, and 23, as I believe these four can explain the output pretty well. Starting with 5:
for i in range(2, 7): # i -> [2, 3, 4, 5, 6]
if (7) % i == 0:
break
else:
print(5, 7)
In the snippet above, 5 7 will be printed 5 times, once for each i in the loop, as 7 is a prime and is not divisible by any given i.
for i in range(2, 9): # i -> [2, 3, 4, 5, 6, 7, 8]
if (9) % i == 0:
break
else:
print(7, 9)
Here you will find that 7 9 is only printed once, because 9 is not divisible by 2, but it is divisible by 3 - in which case, the loop breaks, and continues to the next prime n. Now let's look at n=11:
for i in range(2, 13): # i -> [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
if (13) % i == 0:
break
else:
print(11, 13)
Here, like with n=5, n+2 is also prime (13). As it is not divisible by any number in i, the sequence 11 13 will be printed the length of i, which is 11 (it will always be n, as we start from 2, and add 2 to n).
for i in range(2, 25): # i -> [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
if (25) % i == 0:
break
else:
print(23, 25)
This is the first interesting case in the realm of lower numbers. Up to 23, all n+2 were either prime, or divisible by 3; they were printed n times, or just once. With n=23, the sequence 23 25 is printed 3 times, because 25 is not divisible by 2, 3, or 4 (3 prints), but it is divisible by 5, so now the loop breaks again, and continues to the next prime n.
Again, the resulting output you are looking for is not clear, but reading through previous comments I have to warn - this solution will not print two prime numbers separated by 2 (as #alani figured), it will simply ensure each line is printed just once:
for n in range(3,10000000):
for i in range(2,n):
if n % i == 0:
break
else:
v = 2+n
for i in range(3,v):
if v % i:
print(n,v)
break
I made it so it'll only print once each time, along with only going to the square root of each number as going past that is overkill
for n in range(2,10000000): #started at 2 instead of 1
#removed if statement because i changed start from 1 to 2
for i in range(2,int(n**0.5) + 2): #now goes to square root plus 1(to correct for automatic rounding down)
if n % i == 0:
break
else:
v = n + 2
for f in range(2,int(v**0.5) + 2): #now goes to square root plus 1(to correct for automatic rounding down)
if v % f == 0:
break
elif f == int(v**0.5) + 1: #changed else to elif with condition of being at last iterated integer
print(n,v)
I didn't want to totally revamp your code but if you do want to make this more efficient, i would recommend creating a list of prime numbers you find(by appending each time you find one) and then using a for loop iterating over the list up to the square root of the current value(as iterating over composite numbers is inefficient, since they are multiples of the prime numbers)
Hopefully this is what you wanted, if not i can try to help further though, also please don't take my recommendation as criticism or anything, it's just my opinion on what might make your code run faster

python code is not running.I am calculating prime factors of a number (project euler problem - 3)

I am trying to calculate prime factors of a number in python python 3.8.2 32bit (when i pass 35 in code its output should be 7,and so on).But for some reason the program does not return any answer (when i click run the cmd does not output anything).But when i run this javascript, the exact same code works there. (Previously i had an array(list) to which i would append prime factors and at last i would pop the last element which worked for smaller numbers , but for really large numbers i would get a Memory error,so i converted it to use only one variable which will be updated for every while loop). What is going on here ??
My code is :
import math
# Computes only prime factors of n
def compute(n):
arr = 0
# Checks if n is divisible by 2, and if it is divisible,returns 2 because there will be no any other
# prime factor.
if n % 2 == 0:
return 2
# Now that 2 is eliminated we only check for odd numbers upto (square root of n)+1
for i in range(1, round(math.sqrt(n)) + 1, 2):
while n % i == 0:
arr = n/i
n /= i
return str(arr)
print(compute(81))
I am a newbie in python so plz tell me if i have made any silly mistakes.
Ty.
For numbers that are not divisible by 2, your code runs into an infinite loop at
while n%i == 0
For numbers that are divisible by 2, your function returns 2. The execution of the return statement exits the function.
Even if you change the while in while n%i == 0 to if n% == 0 the function will not work.
You will have to restructure your code.
An easy fix would be to check for all factors of a number till n/2 + 1 and return the factors (in a list) that are prime (which can be checked using a separate isprime function.
def isprime(n):
for x in range(2,n//2+1):
if n%x==0:
return False
return True
def compute(n):
arr = []
for i in range(2, n//2+1):
if n % i == 0:
if isprime(i):
arr.append(i)
return arr
If you want all prime factors (which i guess) you shouldn't return values before you have all prime factors in a list for example.
And with this programm you only check once for a 2. But 4 has 2*2. Put it in a loop.
So this code saves all prime factors in a list:
from math import sqrt, ceil
def get_prime_factors(n):
prime_factors = []
while n > 1:
for i in range (2, ceil(sqrt(n))+1):
if n % i == 0:
possible_prime_number = i
while True:
for j in range(2, possible_prime_number//2-1):
if possible_prime_number % j == 0:
possible_prime_number //= j
break
prime_factors.append(possible_prime_number)
n //= possible_prime_number
break
return prime_factors
if you only want the highest one replace return prime_factors with return max(prime_factors)
OK. I think counting upto 600 billion is ridiculous(considering that i am on a 32 bit system). So here is the final code that i am setteling on which gives answer in acceptable time upto 99 million, without using any array and only 1 for loop.
from math import ceil
# Computes only prime factors of n
def compute(n):
arr = 0
# Checks if n is divisible by 2, and if it is divisible,sets arr =2
if n % 2 == 0:
arr = 2
# Now that 2 is eliminated we only check for odd numbers upto (square root of n)+1
for i in range(1, ceil(n/2) + 1, 2):
if n % i == 0:
arr = i
n //= i
return str(arr)
print(compute(999999999))
P.S.:- If you see any possible improvement in my code plz tell me.

How do I print the two elements of an array and the subsequent sum of these elements? (Goldbachs Primes Question)

I am trying to solve this problem: Goldbach Conjecture
Show with a program "goldbach.py" ​​that all even numbers up to 1000 can indeed be written as the sum of two primes. Specifically: for each even number, also show explicitly (on the screen) that it can be written as the sum of two primes, as in the example below
Even more important is of course if you find a number that does not meet Goldbach's suspicion. Make sure your program clearly displays such a discovery on the screen. Bingo!
python goldbach.py
16 = ...
18 = 5 + 13
20 = 3 + 17
22 = 5 + 17
24 = ...
Progress
So far, I have created a list where all the primes until 1000 are stored, and then I have created a list in which all the combination of primes of which the sum is an even number until 1000. I knew the format to have it print 3 + 17, but I am stuck in trying to have it say sum(pairs) = prime1 "+" prime2. Should be 3 + 17 = 20 for example. Also, I don't know how to have only 1 example of a pair of primes who's sum is of an even number until 1000. I need to break the loop some how.
Because the sum function was not working I found I could convert it to a "numpy array" and then use "accumulate". I just can't get it to work and know I'm getting the error message 'DeprecationWarning: elementwise == comparison failed; this will raise an error in the future.'
Could someone help me with the code?
from itertools import accumulate, islice
from numpy import array
import numpy as np
primes = []
pairs = []
numpy_pairs = np.asarray(pairs)
for num in range (4, 1000):
for j in range (2, num):
if (num % j) == 0:
break
else:
primes.append(num)
#for x in range(2,1000):
# if x in primes:
# print ("Ja, het getal {} komt voor in mijn primes".format(x))
for x in range(2,1000):
if x % 2 == 0:
for prime1 in primes:
for prime2 in primes:
if prime1 + prime2 == x and [prime1, prime2] not in numpy_pairs and [prime2, prime1] not in numpy_pairs:
np.append(numpy_pairs,[prime1,prime2])
results = ("{}+{}={}".format(i, j, k) for i, j in zip(numpy_pairs[0::2],
numpy_pairs[1::2]) for k in accumulate(islice(numpy_pairs,numpy_pairs.stop)))
print('\n'.join(results))
First things first, there are a lot of optimizations you can do to make the code logic better. the way you find primes can be improved, you only need to check numbers upto square root n to verify if n is a prime. Also, the actual verification of Goldbachs conjecture can be improved as well.
However, just focusing on the current code, You should stick to using lists if you want to append values, and to stop the code you need to use a sort of hack to stop the nested looping using the for-else syntax. Also, you can use f-strings to format strings nicely from python 3.6 onwards.
primes = []
pairs = []
for num in range (2, 1000): #modified. you forgot 2 and 3!
for j in range (2, num):
if (num % j) == 0:
break
else:
primes.append(num)
result = []
for x in range(2,1000):
if x % 2 == 0:
for prime1 in primes:
for prime2 in primes:
if prime1 + prime2 == x:
print(f"{x} = {prime1} + {prime2}")
result.append((prime1, prime2))
break
else: #this is a for-else syntax. enter this block if the for loop did not encounter a break
continue #go to next iteration of the mid-level loop. This prevents the line afterwards from being executed in cases where the inner loop did not "break"
break #break the mid level loop if you reach this line.
else:
print("You have done it! Bingo!!")

Why is my code displaying the wrong output?

I wrote a code that outputs "Yes" when the input number is a perfect number, and outputs "No" when the number isn't. But when I input 6, it outputs "No". I have specified it to print "Yes" with if-else statements when the sum of divisors equal to the original input. Why is the output wrong?
n=int(input())
myList=[]
for i in range(1,n):
if n%i==0:
myList.append(n)
sum=0
for i in range(0,len(myList)):
sum=sum+myList[i]
if sum==n:
print("Yes")
else:
print("No")
Sorry for the confusion regarding my previous answer. The problem was that you were appending n instead of i in myList.append(n). Moreover, you could simply use sum to sum your list.
Your output was wrong because you were appending the number n and hence when you do sum=sum+myList[i], you were just adding n to the sum three times because instead of adding 1, 2, 3 to sum, you were adding 6, 6, 6.
n=int(input())
myList=[]
for i in range(1,n):
if n%i==0:
myList.append(i)
if sum(myList)==n:
print("Yes")
else:
print("No")
A one liner suggested by Matthias
print(('No', 'Yes')[sum(i for i in range(1, n) if not n % i) == n])
There is a cool one liner in comment section of this answer
other have already pointed out your mistake so here is how you can optimize your code a little bit.
greatest divisor of 6( =n) other than 6 is 3( = n//2) since we don't add number itself to factors_sum
while checking whether sum of factors equals to number( ie while finding perfect number),so we don't need to check whether any number greater than 3
is a factor of 6 or not.
# perfect nums example 6, 28, 496, and 8,128
n = 8128
stop = (n//2) +1 # stop is exclusive thats why extra 1
factors_sum = 0
for i in range(1,stop):
if n % i == 0:
factors_sum += i
print('Yes' if factors_sum == n else 'No') # Yes
'''
benchmark result( using timeit ran each five times)
for smaller value of n there is no significant difference but as the value of n becomes very large you can clear see the difference.
n = 33550336
1) stop = (n//2) +1
6.580396663 ( time in secs)
2) stop = n
12.635774489000001 ( time in secs)
'''

did my program on perfect numbers in python and not sure if i should use (1,1000) or (2, n+1) in range

I did lab on perfect numbers in python it runs fine and prints numbers that I need. But not sure if I need to put (1, 1000) in range or (2, n+1) is fine? My instruction asking me to
"Write a python program to find all the perfect numbers from 1 to 10,000. When a perfect number is found, your logic should print it."
What is a perfect number:
In number theory, a perfect number is a positive integer that is equal to the sum of its proper positive divisors, that is, the sum of its positive divisors excluding the number itself (also known as its aliquot sum). Equivalently, a perfect number is a number that is half the sum of all of its positive divisors (including itself) i.e. σ1(n) = 2n.
When I run my program it prints out 6, 28, 496, and 8128.
n = 1
while True:
factors = [1]
[factors.append(i) for i in range(2,n+1) if n%i == 0]
if sum(factors) == 2*n: print n
n += 1
something like:
you can also use a range(1,n) as perfect number is equal to sum of all its divisors except itself, i.e. 6=1+2+3
n = 1
while True:
factors =(i for i in range(1,n) if n%i == 0) #use a generator expression
if sum(factors) == n:
print n
n += 1
output:
6
28
496
8128
or a one liner:
In [2]: [x for x in xrange(1,10001) if sum(y for y in xrange(1,x) if x%y==0)==x]
Out[2]: [6, 28, 496, 8128]
No need to go all the way up to n in your inner loop. You can just use range(2, n/2 + 1), and then if sum(factors) == n - 1. Your outer loop should be through range(2, 10001) (i.e. you should test every n in this range). Note that 1 is not considered a perfect number, so we shouldn't include it in our range.
for n in range(2, 10001):
if sum(i for i in range(2, n/2 + 1) if n % i == 0) == n - 1:
print n
Well, there are quite a few simple improvements you can add.
First off, use a range(2,n). You know n%n is 0, so no need to check n at all. Just remember that the sum should be n and not 2*n (you're seeing 2*n because you've added n to the list of factors).
If you really want to speed things up, use range(2, int(math.sqrt(n))). If a is a factor of n, so is n/a. So you can append ([i, n/i]) instead of just i. Don't forget to import math'.
You want to ger all numbers from range [1 .. n] that divide n, so you should use range(2, n+1). Here is simplified version of your code:
for n in range(1, 10001):
factors = [i for i in range(1,n+1) if n % i == 0]
if sum(factors) == 2*n: print n
Not that I wanted to insult you or something, but I really don't like the style of coding, when it takes time to understand, why something works properly (I mean, why writing n+1 and then sum(factors) == 2*n; why factors = [1] if you could just written factors = [] and in range(1,n). :)
I'd write the same as (or even removed list comprehension to spare the consciousness of python newbies):
n = 1
while True:
factors = []
[factors.append(i) for i in range(1,n) if n % i == 0]
if sum(factors) == n:
print n
n += 1
The same output.

Categories

Resources