Printing prime factors of a number using a "points system" - python

We've been given a challenge to write a program that prints prime factors of an input number. We're given an outline: the program checks for factors of the original number; each such factor gets one point. Then, if that factor is prime, it gets another point. Each factor with two points gets printed.
Here's what I have so far.
print('Please enter a number')
x = int(input('Number:'))
a = int(0)
b = int(0)
c = int(1)
d = int(0)
counter = int(0)
while (a < x-1):
a = a + 1
counter = 0
if (x / a % 1 == 0):
b = a
counter = counter + 1
while(c < b - 1):
c = c + 1
if((b / c) % 1 != 0):
d = b
counter = counter + 1
if(counter == 2):
print(d)
With input of 15, I get 3 and 5, but also 15 (wrong). With 24, I get 3, 4, 6, 8, and 12; several of these are not prime.
I believe the issue lies somewhere in the innermost loop, but I can't pinpoint the problem.
At first the issue was I wasn't resetting the "counter", so future factors would exceed 2 "points" and nothing would print. I fixed that by resetting it before it enters the innermost loop, but sadly, that didn't fix the problem.
I've also tried getting rid of 'b' and 'd' and just using two variables to see if I was somehow overcomplicating it, but that didn't help either.
EDIT: Edited slightly for clarity.

Your first sentence was enough of a clue for me to unravel the rest of your posting. Your main problems are loop handling and logic of determining a prime factor.
In general, I see your program design as
Input target number
Find each factor of the number
For each factor, determine whether the factor is prime. If so, print it.
Now, let's look at the innermost loop:
while(c < b - 1):
c = c + 1
if((b / c) % 1 != 0):
d = b
counter = counter + 1
if(counter == 2):
print(d)
As a styling note, please explain why you are building for logic from while loops; this makes your program harder to read. Variable d does nothing for you. Also, your handling of counter is an extra complication: any time you determine that b is a prime number, then simply print it.
The main problem is your logical decision point: you look for factors of b. However, rather than waiting until you know b is prime, you print it as soon as you discover any smaller number that doesn't divide b. Since b-1 is rarely a factor of b (only when b=2), then you will erroneously identify any b value as a prime number.
Instead, you have to wait until you have tried all possible factors. Something like this:
is_prime = True
for c in range(2, b):
if b % c == 0:
is_prime = False
break
if is_prime:
print(b)
There are more "Pythonic" ways to do this, but I think that this is more within your current programming sophistication. If it's necessary to fulfill your assignment, you can add a point only when you've found no factors, and then check the count after you leave the for loop.
Can you take it from there?

I'm not entirely sure I follow you're problem description, but here is my attempt at interpreting it as best I can:
import math
def is_factor(n,m):
return m % n == 0
def is_prime(n):
if n % 2 == 0 and n > 2:
return False
return all(n % i for i in range(3, int(math.sqrt(n)) + 1, 2))
def assign_points(n):
for i in range(1,n+1):
if is_factor(i,n) and is_prime(i):
print('two points for: ', i)
elif is_factor(i,n):
print('one point for: ', i)
print(assign_points(15))

Related

Sum of all prime numbers between 1 and N in Python

I'm new to programming. While trying to solve this problem, I'm getting the wrong answer. I checked my code a number of times but was not able to figure out the mistake. Please, help me on this simple problem. The problem is as follows:
Given a positive integer N, calculate the sum of all prime numbers between 1 and N (inclusive). The first line of input contains an integer T denoting the number of test cases. T testcases follow. Each testcase contains one line of input containing N. For each testcase, in a new line, print the sum of all prime numbers between 1 and N.
And my code is:
from math import sqrt
sum = 0
test = int(input())
for i in range(test):
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(max)) + 1
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
print(sum)
For input 5 and 10, my code is giving output 6 and 48 respectively, while the correct answer is 10 and 17 respectively. Please, figure out the mistake in my code.
Here, I implemented simple program to find the sum of all prime numbers between 1 to n.
Consider primeAddition() as a function and ip as an input parameter. It may help you to solve your problem.Try it.
Code snippet:
def primeAddition(ip):
# list to store prime numbers...
prime = [True] * (ip + 1)
p = 2
while p * p <= ip:
# If prime[p] is not changed, then it is a prime...
if prime[p] == True:
# Update all multiples of p...
i = p * 2
while i <= ip:
prime[i] = False
i += p
p += 1
# Return sum of prime numbers...
sum = 0
for i in range (2, ip + 1):
if(prime[i]):
sum += i
return sum
#The program is ready... Now, time to call the primeAddition() function with any argument... Here I pass 5 as an argument...
#Function call...
print primeAddition(5)
This is the most broken part of your code, it's doing the opposite of what you want:
res = x%y
if res==0:
sum = sum + x
break
You only increment sum if you get through the entire loop without breaking. (And don't use sum as you're redefining a Python built-in.) This can be checked using the special case of else on a for loop, aka "no break". I've made that change below as well as corrected some inefficiencies:
from math import sqrt
T = int(input())
for _ in range(T):
N = int(input())
sum_of_primes = 0
if N < 2:
pass
elif N == 2:
sum_of_primes = 2
else:
sum_of_primes = 2
for number in range(3, N + 1, 2):
for odd in range(3, int(sqrt(number)) + 1, 2):
if (number % odd) == 0:
break
else: # no break
sum_of_primes += number
print(sum_of_primes)
OUTPUT
> python3 test.py
3
5
10
10
17
23
100
>
A slight modification to what you have:
from math import sqrt
sum = 0
test = int(input())
max = int(input())
for x in range(test,max+1):
if x == 1:
pass
else:
half = int(sqrt(x)) + 1
for y in range(2,half):
res = x%y
if res==0:
break
else:
sum = sum + x
print(sum)
Your biggest error was that you were doing the sum = sum + x before the break rather than outside in an else statement.
PS: (although you can) I'd recommend not using variable names like max and sum in your code. These are special functions that are now overridden.
Because your logic is not correct.
for y in range(2,half):
res = x%y
if res==0:
sum = sum + x
break
here you check for the factors and if there is a factor then adds to sum which is opposite of the Primes. So check for the numbers where there is no factors(except 1).
from math import sqrt
test = int(input())
for i in range(test):
sum = 0
max = int(input())
if max==1:
sum = 0
elif max==2:
sum += 2
else:
sum = sum + 2
for x in range(3,max+1):
half = int(sqrt(x)) + 1
if all(x%y!=0 for y in range(2,half)):
sum = sum + x
print(sum)
First of all, declare sum to be zero at the beginning of the for i loop.
The problem lies in the if statement at almost the very end of the code, as you add x to the sum, if the res is equal to zero, meaning that the number is indeed not a prime number. You can see that this is the case, because you get an output of 6 when entering 5, as the only non-prime number in the range 1 to and including 5 is 4 and you add 2 to the sum at the beginning already.
Last but not least, you should change the
half = int(sqrt(max)) + 1
line to
half = int(sqrt(x)) + 1
Try to work with my information provided and fix the code yourself. You learn the most by not copying other people's code.
Happy coding!
I believe the mistake in your code might be coming from the following lines of code:
for x in range(3,max+1):
half = int(sqrt(max)) + 1
Since you are looping using x, you should change int(sqrt(max)) to int(sqrt(x)) like this:
for x in range(3,max+1):
half = int(sqrt(x)) + 1
Your code is trying to see if max is prime N times, where you should be seeing if every number from 1-N is prime instead.
This is my first time answering a question so if you need more help just let me know.

Project Euler #5 using python

The problem statement goes like this:
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?
Here is my solution:
x=2520.0
list=[]
true_list=[11.0, 12.0, 13.0, 14.0, 16.0, 17.0, 18.0, 19.0, 20.0]
b=1
def test():
for n in true_list:
z=x/n
if z%2==0:
list.append(n)
while b==1:
test()
if list==true_list:
b=2
print x
else:
x=x+20
list=[]
-> Basically, I have defined an empty list which gets filled up by the function test(). What test() does is it checks if the given number (x in this case) is evenly divisible by values from 11-20. If it is, it places that value(between 11-20) in the empty list.
When test() has run it's course, the program checks whether the list is equal to a predefined true_list which contains all numbers from 11-20. If it is, x is printed. Else, the program continues after incrementing the value of x.
This means that if list is equal to true_list, all the numbers from 11-20 are evenly dividing our number (x), which is what's asked in the problem.
It gives the answer: 465585120.0 after running for a minute or so. This happens to be incorrect. I do not know why that is. I've been trying to solve this for 8+ hours now and am at my wit's end. What is the error?
You do not need to read ahead, but in case you have queries about why I've used certain things in my solution, then I've addressed some of them here:
->I have not used all 20 numbers in true_list to speed up the program as any number evenly divisible by 11-20 is also evenly divisible by 1-20 as well.
->I have used x=x+20 to speed up the program because it is just as valid as x=x+1 or x+2;only, it is faster.
->I have used float values because I am using z=x/n in the function 'test()', and i do not want to chop off the decimal part because doing that would make even float values eligible for the subsequent operation i.e. z%2.
example:
1) with int values:
x=17
n=2
z=x/n=8
Here, z%2==0 is valid which should not be the case since it is not actually valid in mathematics.
2) with float values:
x=17.0
n=2.0
z=x/n=8.5
Here, z%n != 0 which is how it should be.
Like other people have mentioned just find the lcm, but here is a simple way to do it. Just remember lcm(a, b, c) = lcm(a, lcm(b, c)). That's all this is:
from fractions import gcd
print(reduce(lambda a, b: a * b / gcd(a, b), range(1, 21)))
If you want to write your own gcd function, it works like this (https://en.wikipedia.org/wiki/Euclidean_algorithm):
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
Tht % operator is called the "modulus" operator. In english: a % b is read "a mod b" and means "the remainder of a/b". So 100%3=1 and 12%5=2.
A common way to check divisibility is to check "Does my number modulo my divisor equal 0?". Or in code:
if a%b == 0:
print("b divides a!")
In your code you want to check if n divides x. You checked:
z=x/n
if z%2==0:
print("n divides x?") #No not really
z is the quotient of x and n. if z%2==0 can be interpreted as "If z is divisible by 2".
So you are asking "Is the quotient of x and n divisible by 2?" Which of course is nowhere close to what you want. Instead simply do
if x%n==0:
print("n divides x?") # YES!
I suggest you do a couple python tutorials so that you can get the basics down before attempting problems. :)
If you need anymore help let me know. :)
First of all as I stated in the comment, why are you trying to do it the brute force way? You could much easier calculate the LCM of the numbers 1 through to 20 in a couple of seconds.
Second of all, your line of code,
if z%2==0:
list.append(n)
That essentially gives you double the answer you want, as this statement causes you to calculate the LCM*2, as it must divide into an extra factor of 2.
The correct answer is 232792560, which I calculated using a piece of paper and a calculator in <20 seconds.
As you can see, the answer you are getting is double that
<-- Edit my previous code was wrong. this one works----->
You can correct this by doing:
x=2520.0
list=[]
true_list=[11.0, 12.0, 13.0, 14.0, 16.0, 17.0, 18.0, 19.0, 20.0]
b=1
def test():
for n in true_list:
if x%n==0:
list.append(n)
while b==1:
test()
if list==true_list:
b=2
print(x)
else:
x=x+20
list=[]
This is how you can do it by working out the LCM:
allFactors={}
#for each divisor (ignore 1 as it can divide into everything)
for n in range(2,21,1):
factors={}
i=2
while i<=n:
while n%i==0:
try:
factors[i]+=1
except KeyError:
factors[i]=1
n=n/i
i+=1
for pf,v in factors.iteritems():
try:
if allFactors[pf] < v:
allFactors[pf]=v
except KeyError:
allFactors[pf]=v
lcm=1
for pf,v in allFactors.iteritems():
lcm=lcm*(int(pf)**v)
print(lcm)
There are many ways to solve this problem. Since you're doing an early exercise from Project Euler, I suppose you'd like to develop an approach that helps you understand the basic Python constructs (as opposed to the "batteries included" approach with gcd and so on).
Here's a basic approach, not efficient in run time or developer time :) but a decent exercise:
found = None
n = 0
while not found:
n += 1
for d in xrange(2,21):
if n % d:
break
else:
found = n
print found
Which goes like this:
Examine a numerator n starting at 0. (You could actually start at 2520 since we know the answer must be no smaller than the answer to the 1-10 case, but that's a tiny optimization.)
Loop forever until a solution is found. (In a real-world program, you would probably put in some kind of safety check so this can't run forever, but this is fine for what we're doing.)
If we haven't found a solution yet, bump the numerator up by one for the next round.
Divide the numerator by a denominator d in the 2-20 range. If any value of d results in a non-zero remainder, break out of the loop - no point in testing the remaining denominators. (If we wanted to be more efficient, we could use xrange(2,n) since there is no point in dividing by a value greater than the numerator. If efficiency was an extreme concern, like if the range was vastly larger (2-1000 instead of 2-20), we could actually use xrange(2,floor(sqrt(n)) since there is no possibility of no remainder for a divisor great than the square root).
If we make it all the way through the for loop without breaking out early, the else clause operates, and we record the curent value of the numerator - this is the solution.
This approach is clearly brute force. It's fine as a learning exercise. For larger versions of the same problem, you'd be much better off using Euclid's algorithm and hardware-aware optimizations.
import time
start_time = time.time()
for i in range(2520,10000000000):
if i % 11 == 0 and\
i % 12 == 0 and\
i % 13 == 0 and\
i % 14 == 0 and\
i % 15 == 0 and\
i % 16 == 0 and\
i % 17 == 0 and\
i % 18 == 0 and\
i % 19 == 0 and\
i % 20 == 0:
print(i)
break
print(time.time() - start_time," seconds")
You can find the LCM of the Prime Numbers and the Composite Numbers separately, and then find the LCM of their LCMs. Gets the job done in almost a second! Here's my code:
import time
start_time = time.time()
nums = []
primeNums = []
allNums = []
def findFactors(num):
factors = []
for i in range(1, num + 1):
if num % i == 0:
if i not in factors:
factors.append(i)
x = int(num / i)
factors.append(x)
else:
break
return factors
def isDivisibleByAll(number, numbers):
isDivisbleBy = []
for num in numbers:
if number % num == 0:
isDivisbleBy.append(num)
return isDivisbleBy == numbers
for i in range(11, 21):
nums.append(i)
for num in nums:
if findFactors(num) == [1, num]:
primeNums.append(num)
nums.remove(num)
currentNum = nums[-1]
currentPrimeNum = primeNums[-1]
while isDivisibleByAll(currentNum, nums) == False:
currentNum = currentNum + nums[-1]
print(currentNum)
while isDivisibleByAll(currentPrimeNum, primeNums) == False:
currentPrimeNum = currentPrimeNum + primeNums[-1]
print(currentPrimeNum)
allNums.append(currentNum)
allNums.append(currentPrimeNum)
currentAllNum = allNums[-1]
while isDivisibleByAll(currentAllNum, nums) == False:
currentAllNum = currentAllNum + allNums[-1]
print(currentAllNum)
print(currentNum, currentPrimeNum, currentAllNum)
end_time = time.time()
print("Time taken: ", end_time - start_time)
A more efficient and shorter way of solving this problem will be the code mentioned below. So, as we know from the question that number that is divisible from all numbers between 1 to 10 is 2520. And we know that the factors of x are also the factors of yx. So, we can create a function that checks whether the number is divisible from all the numbers from 11 to 20. And we can make a while loop in which will increment the value of x by 2520 until the value of x is the answer. This method takes less than a second(on my i5 machine and 0.6083979606628418 seconds exactly).
def isdivisiblebyall(n):
for i in range(11, 21):
if n % i != 0:
return False
return True
no = 2520
while not isdivisiblebyall(no):
## if number is not divisible by range of 11 to 20 the value of 'no' will be incremented by 2520
no+=2520
print(no)

Amicable Numbers

I am struggling with optimizing these functions that I have used to calculate the sum of the amicable pairs under 10000. An amicable pair is a pair (a, b) where the sum of the divisors of "a" excluding "a" itself equals b and the sum of the divisors of "b" excluding "b" itself equals "a".
I.e. divisors of 220 are 1, 2, 4, 5, 10, 11, 20, 22, 44, 55 and 110: The sum of which is 284. And the sum of the divisors of 284 (1, 2, 4, 71 and 142) equals 220.
My code is:
import math
def Divisorsbaritself(x):
divList = [1]
y = 2
while y <= math.sqrt(x):
if x % y == 0:
divList.append(y)
divList.append(int(x / y))
y += 1
return sum(divList)
def amicable():
solution = []
for i in range(10000):
if Divisorsbaritself(Divisorsbaritself(i)) == i:
solution.append(i)
return sum(solution)
print amicable()
I need help with understanding why the amicable function is not working. To me it makes logical sense that the if Divisorsbaritself(Divisorsbaritself(i)) == i: condition is the right condition to include i in the list, but it is giving me 40285, rather than 31626, the answer.
If Divisorsbaritself(i)==i you shouldn't count i.
def amicable():
solution = []
for i in range(10000):
if Divisorsbaritself(i)!=i and Divisorsbaritself(Divisorsbaritself(i)) == i:
solution.append(i)
return sum(solution)
But you should also fix the bug that would be an issue if i is a perfect square and in an amicable pair.
You can improve this with list comprehensions.
def amicable():
solution = [i for i in xrange(10000) if Divisorsbaritself(i)!=i and Divisorsbaritself(Divisorsbaritself(i)) == i]
return sum(solution)
They're amicable numbers only if they're different. So if divsum(i) is equal to i, then that's not included, despite the fact that means that divsum(divsum(i)) also equals i.
In addition, your current check counts the square root of a perfect square twice, even though it's only one factor.
And, on top of that, I wouldn't be using a list then summing it at the end when you can simply use an accumulator. And it's usually faster to do multiplication than square roots so you can change the while loop to take that into account.
Finally, for the love of whatever deities you believe in, comment your code! It'll make it so much easier to understand what's going on, both for others and for yourself six months down the track.
Incorporating those changes gives you the following DivisorsBarItself function:
def DivisorsBarItself(num):
# Maintain sum of factors.
divSum = 1
# Go through every integer up to but excluding sqrt(num).
testnum = 2
while testnum * testnum < num:
# If factor, add it and the complement (guaranteed integer).
if num % testnum == 0:
divSum += testnum + num/testnum
testnum += 1
# If perfect square, add the square root once.
if testnum * testnum == num:
divSum += testnum
# Return the sum.
return divSum
Fixing the logic for detecting amicable numbers and using a sum rather than a list gives you:
def AmicableSum():
# Set sum to zero and process all numbers below 10,000.
solution = 0
for num in range(10000):
# Get the "friend", add only if different and f(f(x)) = x.
numFriend = DivisorsBarItself(num)
if numFriend != num and DivisorsBarItself(numFriend) == num:
solution += num
return solution
print AmicableSum()
which gives the correct result of 31626.
I have fixed the bug now by going:
def Divisorsbaritself(x):
divList = [1]
y = 2
while y <= math.sqrt(x):
if x % y == 0:
if y is not int(x/y):
divList.append(y)
divList.append(int(x / y))
else:
divList.append(y)
y += 1
return sum(divList)
I have written the whole thing you said as a function
def devisor(a):
listOfFactors=[]
for possibleFactor in range(1,a):
if a%x==0:
listOfFactors.append(possibleFactor)
sumOfFactors=0
for item in z:
sumOfFactors+=item
factorsOfNewSumAddedUp=0
for x in range(1,sumOfFactors):
if temp%x==0:
factorsOfNewSumAddedUp+=x
if a==factorsOfNewSumAddedUp:
print("this is a divisor")

Project Euler #7 Python

I'm having trouble with my code. The question is:
"By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10 001st prime number?"
This is what it looks like:
div = 10001
i = 2
count = 0
prime = 0
now = []
while count < div:
for x in range (2,i+1):
if len(now) ==2:
break
elif i%x == 0:
now.append(x)
if len(now)==1:
prime = i
count += 1
now = []
i+=1
print(prime)
I have tried div up to 1000 and it seems to work fine(for div 1000 I receive 7919). However, when I try div = 10001 I get nothing, not even errors. If someone would help me out I would really appreciate it.
Thank you.
# 7 10001st prime
import itertools
def is_prime(n):
for i in range(2, n//2 + 1):
if n % i == 0:
return False
else:
continue
return True
p = 0
for x in itertools.count(1):
if is_prime(x):
if p == 10001:
print(x)
break
p += 1
Try this code:
prime_list = lambda x:[i for i in xrange(2, x+1) if all([i%x for x in xrange(2, int(i**0.5+1))])][10000]
print prime_list(120000)
Lambda in Python defines an anonymous function and xrange is similar to range, defining a range of integer numbers. The code uses list comprehension and goes through the numbers twice up to the square root of the final number (thus i**0.5). Each number gets eliminated if it is a multiple of the number that's in the range count. You are left with a list of prime numbers in order. So, you just have to print out the number with the right index.
With just some simple modifications (and simplifications) to your code, you can compute the number you're looking for in 1/3 of a second. First, we only check up to the square root as #Hashman suggests. Next, we only test and divide by odd numbers, dealing with 2 as a special case up front. Finally, we toss the whole now array length logic and simply take advantage of Python's break logic:
limit = 10001
i = 3
count = 1
prime = 2
while count < limit:
for x in range(3, int(i ** 0.5) + 1, 2):
if i % x == 0:
break
else: # no break
prime = i
count += 1
i += 2
print(prime)
As before, this gives us 7919 for a limit of 1000 and it gives us 104743 for a limit of 10001. But this still is not as fast as a sieve.
m=0
n=None
s=1
while s<=10001:
for i in range(1,m):
if m%i==0:n=i
if n==1:print(m,'is prime',s);s+=1
m+=1

Find the smallest equally divisible in a range of numbers in Python, puzzle

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 :)

Categories

Resources