Well first of all, the set that actually needs to check any int z for divisibility is smaller than N for the range 1-N. Here is why:
Any number x that is divisible by 6, is also divisible by it's factors i.e 1,2,3,6.
So essentially, your algorithm is :
for number in rangeArray:
removeSubList(getAllFactors(number),rangeArray)
Translation into python code:
#Note: this can be sped up even faster by appending both the multiples
#at the same time instead of iterating over the range 1,number
#Note: get_all_factors(6) will return [1,2,3] but not [1,2,3,6]
def get_all_smaller_factors(number):
factors = [number,1]
for x in range(1,number):
if (number % x == 0 and number not in factors):
factors.append(x)
return factors
#Note: again, I'm too tired to find proper names, please improve later.
def min_factor_list(max):
factors = range(1,max)
for factor in factors:
#remove the sublist you get from get_all_factors
factors = [x for x in factor if x not in get_all_smaller_factors(x)]
return factors
#Note: again, I'm too tired to find proper names, please improve later.
def accept(input_var, range):
factors = min_factor_list(range)
for factor in factor:
if(input_var % factor is not 0):
return false
return true
Now that you have the boring stuff out of the way, here is a simple oneliner that will do your work:
print "Is %d divisible by range(1,%d)? %r"%(z,max,accept(z,max))
Disclaimer: I haven't actually tried out the code, but this SHOULD work.
Edit:
Another (not completely unrelated but certainly better) approach is to use the range (1..range_max) and find the least common multiple (i.e LCM). From there, you can simply check if the LCM is a factor of Z or not.
The min_factor_list method should help with this. You can simply multiply every element in that list and get the LCM (no elements in the list has another element as its factor or simply put, all the elements are relatively prime)
Why does this work? Because Z must be atleast as big as the LCM. Now what is the next time you get a number that is divisible by all the numbers? That is the same time as LCM*2. And the next time after that? LCM*3
i, but ignoring that), which they should since none of the numbers in that range are dividable by everything from 1 to 20. Are you sure you copied the code right?all(z % n == 0 for n in range(1,21))will be True only if a number is divisible by ALL numbers in the range 1..21. I'm not sure such number exist. Try your third example with range(1,3)