0

newbie here. I've been trying to find the least common multiple of the numbers 1 thru 10. My code so far

def smallest_multiple():
a = 0
while True:
    a += 1
    if a%1 == 0 and a%2 == 0 and a%3 == 0 and a%4 == 0 and a%5 == 0 and a%6 == 0 and a%7 == 0 and a%8 == 0 and a%9 == 0 and a%10 == 0:
        return a

print(smallest_multiple())

My result is 2520, which seems to be correct. It is the smallest number that is divisible by the numbers 1 thru 10 without remainder. But is there a way to make the 5 line shorter (not that much modulus) by iterating over them? I've tried something like this

def smallest_multiple():
a = 0
while True:
    a += 1
    for i in range(1, 11):
        if a % i == 0:
            return a

print(smallest_multiple())

But that returns just 1, not 2520. Is there a way to make

if a%1 == 0 and a%2 == 0 and a%3 == 0 and a%4 == 0 and a%5 == 0 and a%6 == 0 and a%7 == 0 and a%8 == 0 and a%9 == 0 and a%10 == 0:

shorter?

Jose Gallo
  • 93
  • 2
  • 6
  • 1
    A suggestion: You can make your code a lot simpler, readable and efficient if you realize that `LCM(a, b, c) = LCM(LCM(a, b), c)` and `LCM(a, b) = (a * b) / GCD(a, b)` and use Euclidean algorithm for computing GCD https://en.wikipedia.org/wiki/Euclidean_algorithm#Implementations – lakshayg Sep 12 '18 at 15:25

3 Answers3

1

You could change it to

if all([a%i == 0 for i in range(1,11)]):

All takes a list and returns True if everything in the list is True

This uses a simple list comprehension to go through numbers 1 through 10, and check if they are all True with a%i == 0

Qwerty
  • 1,252
  • 1
  • 11
  • 23
1

You could use all:

def smallest_multiple():
    factors = [i for i in range(1, 11)]
    a = 0
    while True:
        a += 1
        if all([a % factor == 0 for factor in factors]):
            return a


print(smallest_multiple())

Output

2520

UPDATE

As suggested by @PatrickHaugh you can avoid the creation of lists:

def smallest_multiple():
    factors = range(1, 11)
    a = 0
    while True:
        a += 1
        if all(a % factor == 0 for factor in factors):
            return a


print(smallest_multiple())

Output

2520
Dani Mesejo
  • 61,499
  • 6
  • 49
  • 76
  • 1
    You're building a few unnecessary lists here. Why are you making `factors` a lit when you can already iterate over a `range`? You also don't need to make a list of your divisibility checks: if you use a generator expression `all(a % factor == 0 for factor in factors)` then `all` won't have to calculate all of the items if one of them is not equal to 0 – Patrick Haugh Sep 12 '18 at 15:27
  • you are unnesesarely making the range each time you need it. Patrick Haugh did not mean you shouldm't bring it out of the loop, just that the lis comprehension wasn't smart. – Jonas Wolff Sep 12 '18 at 15:40
  • @JonasWolff fixed it. – Dani Mesejo Sep 12 '18 at 15:47
0

Speaking of one-liners ^^

Not an Infinity loop, though

import sys
next(i for i in xrange(1, sys.maxsize) if len([j for j in range(1,10) if i % j == 0]) == 9)
#=> 2520

And this is not the most efficient solution.

fl00r
  • 82,987
  • 33
  • 217
  • 237