Basically what you want is to calculate the MMC (common minimum multiple) between these numbers. So it’s more of a mathematical question than pythonic. Suffice it to consider that:
- for 3 numbers
x
, y
and z
, the MMC(x, y, z)
is the same as MMC(MMC(x, y), z)
(which is also the same as MMC(x, MMC(y, z))
). That is, we can calculate the MMC of 2 in 2 numbers until we reach the final result
- one of the many ways to calculate is
MMC(x, y) = x * y / MDC(x, y)
(where MDC is the maximum common divisor)
Even Python 3.8 you can use the function math.gcd
to calculate the MDC, then just use it to calculate step 2. And for step 1, just do a loop in the numbers and go calculating the MMC between them:
from math import gcd
def mmc(numeros):
m = 1
for n in numeros:
m = m * n // gcd(m, n)
return m
numeros = range(2, 21)
print(mmc(numeros)) # 232792560
I used range(2, 21)
(all numbers between 2 and 20), as it makes no sense to include the 1
(all numbers are multiples of 1 and it is redundant to include it in the calculation).
From Python 3.9 you can use math.lcm
to calculate the MMC directly, without needing the above formula:
from math import lcm
print(lcm(*range(2, 21))) # 232792560
Detail that the numbers of range
has to be passed via unpacking (with the asterisk before the range
), so that the numbers are passed as parameters (without the asterisk, the actual range
is passed as a parameter and then does not work).
Of course you can optimize a little more because you don’t need to have all the numbers in the list. It could just be:
###########################################
# Até Python 3.8
from math import gcd
def mmc(numeros):
m = 1
for n in numeros:
m = m * n // gcd(m, n)
return m
print(mmc([11, 13, 14, 15, 16, 17, 18, 19, 20]))
###########################################
# A partir de Python 3.9
from math import lcm
print(lcm(11, 13, 14, 15, 16, 17, 18, 19, 20)) # 232792560
If the number is multiple of 20, it will surely also be multiple of 2, 4, 5 and 10, if it is multiple of 18, it will surely also be of 2, 3, 6 and 9, and so on. And since it is a multiple of 3 and 4, it will also be 12, etc. So you don’t need to have everyone on the list.
Another option is to use functools.reduce
, which makes the code shorter (but not necessarily easier to understand, varies according to each person’s opinion):
from math import gcd
from functools import reduce
def mmc(numeros):
return reduce(lambda x, y: x * y // gcd(x, y), numeros)
But this only for Python <= 3.8 as from version 3.9 just pass all numbers to math.lcm
, without the need to use reduce
.
Yes, it’s called MMC calculation. You can do it in 20 steps and you don’t need to verify divisibility at any time
– Jefferson Quesado
Or even fewer steps, since if it is multiple of any even value it will also be divisible by 2; if it is multiple of 16 it will already be multiple of 8, 4 and 2; if it is multiple of 15 it will already be also of 5 and 3, etc.
– Woss
Not that it’ll leave the algorithm much faster, but every number is divisible by 1, so you don’t need to test
numero % 1 == 0
:-)– hkotsubo
Here you can have some algorithmic ideas to implement without necessarily doing so by the raw force: https://www.calculatorsoup.com/calculators/math/lcm.php
– Giovanni Nunes