0

I'm a python noob and have issues setting up a loop that checks if an int z is divisible by a set of numbers, e.g. by 1 - 10. I wrote the following code snippets, but they all return X =[all the numbers of z]... i.e. they fail to apply the if condition so that the mod is checked over all n in a given range/set.

X = []
z = 1
while z in range(1,1000):
    if all(z % n == 0 for n in range(1,21)):
        X.append(z) 
    z += 1

also tried:

X = []
if all(i % n == 0 for n in range(1,21)):
    X.append(i)

and

X = []
for z in range(1,1000000):
    if all(z % n == 0 for n in range(1,21)):
        X.append(z)  

Any idea what's going wrong in each of these (or at least 1) of these cases? Thanks for the help!

5
  • 1
    These return empty sets for me (well, the middle one doesn't define 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? Commented Jul 17, 2012 at 20:51
  • 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) Commented Jul 17, 2012 at 20:51
  • @Sergey it should exists, and I have tried on smaller numbers before, but the problem is that it returns X = [1,2,...,999999] in the third case, which seems to imply that the if statement isn't working correctly? Commented Jul 17, 2012 at 20:56
  • It does work with shorter sequences, e.q. 1..3 Commented Jul 17, 2012 at 21:05
  • Your right, my bad. Had some issues with my iPython. Thanks! Commented Jul 17, 2012 at 21:12

6 Answers 6

1

EDIT: was wrong, fixed answer.

Are you using numpy? There is something funny going on with numpy and it's version of all.

import numpy as np
all( z % n for n in range(1,5)) # NameError
np.all( z % n for n in range(1,5)) # True
z = 5
all( z % n for n in range(1,5)) # False
np.all( z % n for n in range(1,5)) # True
np.all([z % n for n in range(1,5)) # False
Sign up to request clarification or add additional context in comments.

5 Comments

It's a generator expression, and it definitely doesn't return True if z isn't defined; it NameErrors like you'd expect
It's perfectly valid to use all() with a generator expression.
@MichaelMrozek There is something funny going on with numpy
Yeah, if he did from numpy import * or was using an IPython which imported from pylab or something, that would explain it. Numpy's all doesn't play nicely with genexps. [+1 for the new idea, which is a good one even if it's wrong, and which I was typing up but you beat me..]
Yes, your right there is something strange with numpy--I was using it in iPython and it started to work when I didn't import it. strange.. but thanks for the help!
0
print [z for z in range(10000) if all(z%k==0 for k in range(1,10))]
>>> [0, 2520, 5040, 7560]

seems to work. Second example, i doesn't seem to be initialized. Third seems to work.

PS : beware that fact(21) is quite big and certainly bigger than 1000000 - it's not a perfect result but it might be a factor or two below the first answer (prime decomposition yadda yadda)

1 Comment

on that note, if OP is looking for a number that is divisible by any factorial wouldn't it be easier to make a list of factorials and then compare if the integer in question is in the list of factorials? Meaning make a list facts = [1!, 2!, 3!, 4!, ..., 10!] Then if a number is in that list it means that that number is divisible by every number 1 through 10. I think the number one should be left out btw.
0

The problem isn't with Python but with your math. x % n == x if x is less than n. In particular, no integer less than 21 can be zero mod every number up to 21. 3 % 18 is 3. So you need to rethink what you're asking. If you really try to find a number that is evenly divisible by every number from 1 to 21, the only numbers you'll get will be huge numbers (e.g., 21!).

Comments

0

In your first example you're doing some strange combination of a while and for loop, and I was sort of surprised it runs at all!

In the second example you're not initializing or updating i.

The third example works. However, the first number that's divisible by all numbers from 1 to 20 is 232792560, which is outside your range.

As an alternative you could also do it in one line

X = [z for z in range(1, 1000000) if all(z % n == 0 for n in range(1, 21))]

but again, you won't get any results below 232792560!

Comments

0

First off, all numbers are divisible by ONE, even zero. So your range(1,21) should probably exclude 1 by being range(2,21)

x % 1 == 0 

is always True if x > 0 and is an integer.

Then to clarify: if you have:

rangeOne = range(1,1000000)
rangeTwo = range(2,21)

Secondly are you looking only for numbers in rangeOne that are divisible by all numbers in rangeTwo?

Or are you looking for subset of possible primes from rangeOne such that you want to get a list of numbers that are not divisible by any number in rangeTwo (with a resultant integer verse a fraction)?

Or the inverse of that, all numbers from rangeOne that can be divisible by any one or more numbers in rangeTwo, meaning to exclude primes.

There are more cases like that.

2 Comments

The only numbers evenly divisible by 1,2,3,4,5,6,7,8,9 and 10 is (10! to the nth)
How about 10*9*8*7*6? That is divisible by all numbers in the range (1..10)
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.