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
Related
I wanted to write a program which adds the digits until it becomes a single digit number, here is my code
n=int(input(""))
b=10**18
while not 1<=n<=b:
n=int(input(""))
else:
tot=0
while(n!=0):
dig=n%10
tot=tot+dig
n=n//10
s=0
if tot>=10:
while (tot!=0):
tot2=tot%10
s=s+tot2
tot=tot//10
else:
s=tot
print(s)
I thinked that it works correctly but when I type 88888888888 it gives me 16 as output not 7 ...but every thing is correct ...How can I fix that?
You can simply do
s = n % 9
Because from math we know that sum of digits of any number and a number itself has the same remainder when divided by 9. The only corner case is when n is divisible 9, in this case, you want s=9.
The final code would be:
n=int(input())
b=10**18
while not 1 <= n <= b:
n=int(input())
if (n%9 == 0):
s = 9
else:
s = n % 9
You could approach this recursively.
def sumDigits(N): return N if N<10 else sumDigits(sum(divmod(N,10)))
sumDigits(88888888888) # 7
If you want a mathematical solution:
def sumDigits(N): return (N+8)%9+1
the problem is simple that you don't do enough iterations, as Daniyar Aubekerov commented you need 3 round for 88888888888 (88888888888->88->16->7 ) but you only do 2
one way to solve it is simple factor out the commons parts into their own functions and use them as needed, for example
def digits(n):
"digits of the number n"
dig = []
while n>0:
n,d = divmod(n,10) # this do both n//10 and n%10
dig.append(d)
return dig
def sum_digits(n):
s = sum(digits(n)) #sum add together all the elements in the list
while s>10:
s = sum(digits(s))
return s
or even more simple, use a more direct approach to get it, as this is also know as the digital root of the number
def digital_root(n):
if n==0:
return 0
else:
return 1 + (n-1)%9
and some quick test
>>> digits(100)
[0, 0, 1]
>>> digits(88888888888)
[8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8]
>>> sum_digits(88888888888)
7
>>> digital_root(88888888888)
7
>>>
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.
I am trying to find the largest prime number in a list (ascending order). I created a while-loop which checks if a number in the list is prime by dividing it by each number less than itself and 'breaking' the loop when it finds a number that has no factor less than itself (greater than 1). This loop is nested in another while-loop which iterates backward through the list.
When I run the code, it keeps returning the number 8 (which is obviously not prime).
I have tried going through the code step-by-step on paper, inserting the variable values and doing the math. I must be miscalculating something.
factors = [2, 3, 4, 6, 8]
b = 1
y = len(factors) - 1
x = factors[y]
z = x - b
while y >= 0:
while b < x:
if x % z == 0:
break
else:
if b == x-1:
print(f'The number {x} is the largest prime in the list')
break #need to end the outer loop here
else:
b +=1
y -= 1
b = 1
print('There were no prime numbers in the list')
I expect the code to return 'The number 3 is the largest prime in the list'
What it actually returns:
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
The number 8 is the largest prime factor
A few main problems with your code:
You are not updating the values of x (outer loop) and z (inner loop) on each iteration. You will want to add for z:
else:
b += 1
z = x - b
and for x:
y -= 1
x = factors[y]
b = 1
The fact that you are having that many variables for that task makes it hard to read and understand. You could for example get rid of z all together and simply start b from 2 and go up.
Since both loops iterate over a known range (outer on the list, inner until x) it would be better to use for loops instead of while. That will also arrange your variables better. For example:
factors = [2, 3, 4, 6, 8]
for number in factors[::-1]:
for b in range(2, number):
if number % b == 0:
break
elif b == number-1:
print(f'The number {number} is the largest prime in the list')
break # you should put this whole code in a function and return here
print('There were no prime numbers in the list')
Notice that we don't use any other variables except the ones defined by the loops. That makes the code more readable.
The factors[::-1] means we are looping over the list in reverse order.
A nice little python feature is adding an else clause on a loop. This else will be executed only if the loop is exhausted without meeting any break statement. Which is perfect in our case because if the inner loop is exhausted, then the number is a prime for sure. So it can be:
factors = [2, 3, 4, 6, 8]
for number in factors[::-1]:
for b in range(2, number):
if number % b == 0:
break
else:
print(f'The number {number} is the largest prime in the list')
break # This now breaks the outer loop
else:
print('There were no prime numbers in the list')
Note the use of that same technique also in the outer-loop, as if the inner loop exhausted without hitting the break in the else block, it means no prime was found so we want to print the no-found message.
Can you check the below codes please?
def prime_numbers(numbers):
for i in numbers:
for j in range(2, i):
if i % j == 0:
break
else:
yield i
try:
print(f"{max(prime_numbers([2, 3, 5, 6, 8]))} is the largest prime number.")
except ValueError:
print("There are no prime numbers in the list.")
Hey awesome python people,
Warning: I am new to coding. Ok, now that you have been warned...
I am trying to write a python file that finds the largest prime number of a variable I declare inside the code.
Here is my thought process:
Step 1:Find Factors of X
Step 2:Put factors of X in an array a
Step 3:Analyze last element of array a
Step 4:Check if last element of array a is Prime
Step 5: if last element of array a is prime print "found the largest prime" along with the number itself, else, analyze second to last element in array a, and so on until at a[1]
Step 6: if no prime numbers in array, print "no primes found"
The issue is somewhere in the last else statement, when dealing with x=28 and its factors in an array:
[1, 2, 4, 7, 14] my code thinks 7 is not a prime...
My steps are listed in-line:
#find factors, put them in an array a
#1.Find factors of X
#2.Put factors of X in an array a
x=28
i=1
a=[]
length = 0
while i<x:
if x%i == 0: #checks to see if X is divisible by anything between 1 and X-1
a.append(i) #adds factor to array a
i = i+1
print "your factors are: ", "\n", a
print "\n"
#3. Analyze the last element in array a
# Before loop below, a = [1, 2, 4, 7, 14] and length = 5
length = 0
length = len(a)
n=a[length-1]-1
print "checking for primes in your array now...", "\n"
while len(a) > 2:
if a[length-1]%n != 0:
n=n-1
if n == 1:
print "PRIME TIME"
break
else:
print a[length-1], "is not a prime" #added
del a[-1]
length = len(a)
print "length = ",length
if length == 2:
print "NO Primes"
A few questions:
How would you re-assign variables like x, i a[], and n to make the code more readable
In the second loop, after the first iteration, when analyzing 7 why does the code not recognize that it is a prime number?
Thanks so much for any constructive feedback!!
Ok, I would do it like this:
def primes(n):
primfac = []
d = 2
while d*d <= n:
while (n % d) == 0:
primfac.append(d)
n /= d
d += 1
if n > 1:
primfac.append(n)
return primfac
print "Factors: ", primes(28)
print "The largest is: ", max(primes(28))
First use the primes function which I took from here. It returns an array containing all prime factors.
Then, simply aply the max-function, which gives you the largest element of the array.
The output is as follows:
Factors: [2, 2, 7]
The largest is: 7
I hope this helps.
I'm trying to solve a projecteuler puzzle detailed below. My current function works for the numbers 1 to 10, but when I try 1 to 20 it just loops forever without a result.
2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any remainder.
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
def calculate():
results = dict()
target = 20
num_to_test = 1
while len(results) < target:
for j in range(1, target+1):
results[num_to_test] = True
if num_to_test % j != 0:
# current num_to_test failed in the 1-10, move on
del results[num_to_test]
break
num_to_test += 1
return min(results)
Can anyone see any issues in the logic, and especially I'd like to know why it is working for a target of 10, but not 20. Thanks
Your algorithm is pretty inefficient, but the core of your problem is that your results dictionary is accumulating 1 value for each integer that's evenly divisible by the numbers from 1-20, and your while loop is trying to keep going until it has 20 such numbers.
This is one correct way to implement this inefficient algorithm:
def calculate():
target = 20
candidate = 1
success = False
divisors = range(1, target+1)
while not success:
for divisor in divisors:
if candidate % divisor != 0:
candidate += 1
break
else:
success = True
return candidate
Note that the else clause really is on the for loop, not the if. From the tutorial on flow control:
Loop statements may have an else clause; it is executed when the loop terminates through exhaustion of the list (with for) or when the condition becomes false (with while), but not when the loop is terminated by a break statement.
A somewhat more concise expression would be:
candidate = 0
while not success:
candidate += 1
success = all((candidate % divisor == 0 for divisor in divisors))
That uses a generator expression so all can short-circuit and avoid doing unnecessary calculation.
Since this is a puzzle I'll pass on suggesting better algorithms.
actually I have very efficient algorithm for that problem.
I'll not give you the code, but I could show you the way
For N = 10
1.Calculate all factors of all numbers from 5 to 10:
[[2, 3], [7], [2, 2, 2], [3, 3], [2, 5]]
2.calculate maximum number of each prime in the list
{2: 3, 3: 2, 5: 1, 7: 1}
3.get product of key power value
2^3 * 3^2 * 5 * 7 = 2520
A lot of the other answers mention the original code being inefficient, but they still loop through almost every number. Wouldn't it be more efficient to utilize an lcm function?
def calculate(num, current_lcm = 1):
if (num == 1): return current_lcm
return calculate(num - 1, lcm(num, current_lcm))
def lcm(a, b):
return a * b // gcd(a, b)
def gcd(a, b):
while b:
a, b = b, a % b
return a
print calculate(20)
While your algorithm is very inefficient, it may help a little to make this small change
if num_to_test % j = 0:
results[num_to_test] = True
else:
# current num_to_test failed in the 1-10, move on
break
Not sure why you are storing them all though? For debugging perhaps?
Hint. It would be better to calculate the prime factors of the result and simply multiply those together.
# spoiler
def calculate(target):
n = 1
for i in range(1, target+1):
for j in range(1, target+1):
if (n * j) % i == 0:
n *= j
break
return n
Dont store em all, instead just return early when you find it, get rid of that result dictionary, this is not optimal at all by the way, just a clean up
def calculate():
target = 20
num_to_test = 0
while True:
num_to_test += target
if all((num_to_test % j == 0) for j in range(1,target+1)):
return num_to_test
return -1
Also you dont need to test numbers that aren't multiples of your maximum. It'll run 20 times faster.
I switched to using a generator to test to see if the number was divisible by all() of the nubmers from 1 to 20
Props for writing your own algorithm and not copying one :)