Fastest and most compact way to get the smallest number that is divisible by numbers from 1 to n

Mathematically, you are computing the least common multiple of 1, 2, ..., n. lcm is easily derived from gcd, and lcm is an associative operation. reduce is useful for applying an associative operation to an interable. We can combine these ideas (as well as improvements due to Mark Dickinson and Eric Postpischil in the comments) to get a very fast solution:

from math import gcd
from functools import reduce

def lcm(a,b):
    return a // gcd(a,b) * b

def get_smallest_number2(n):
    return reduce(lcm,range(1 + n//2,n+1),1)

Some quick %timeit results in IPython:

%timeit get_smallest_number2(15)
2.07 µs ± 26.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit get_smallest_number(15)
443 ms ± 5.75 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

For n = 15 it is thus over 200,000 times faster. Your function fails to produce any output long before n = 100, but get_smallest_number2(100) evaluates to 69720375229712477164533808935312303556800 almost instantly.


Start by thinking about the factorial n!. This is obviously divisible by all numbers less then n, but is not the smallest such number. For example, you could divide n! by 6, and the smaller result would still be divisible by 2 and by 3, and hence still divisible by 6.

What numbers can we divide out? Composites, like 6, don't matter as long as all the required primes are present: 2 and 3 in that case. The primes give you the composites for free. So, concentrate on the primes.

Start with 2. Look at the powers of 2: 2, 4, 8, 16, ... Run through the powers of 2 until you find the highest power that is smaller than or equal to n. That is the only power of 2 you need, all the lower powers are unnecessary. You don't need to include 4 explicitly if n is 8 or higher because then you will have 8, 16 or whatever as a multiplier. Repeat for powers of 3: 3, 9, 27, 81, ... and so on through the primes up to sqrt(n). Beyond that point you only need the remaining primes less than n, since higher powers of those primes will exceed n.

Multiply the selected prime powers together to get the least n.

Use a Sieve of Eratosthenes to generate your initial list of primes up to n.