简体   繁体   中英

sum to turn divisible by one element of the list each time

Given the list:

n = [3, 6, 12, 24, 36, 48, 60]

I need to turn a random number divisible by 3, after by 6, after by 12, after by 24, after by 36, after by 48 and after by 60. One at each time, not the divisible for the seven numbers simultaneously.

But, to make the number divisible, I need to sum another number to reach the number divisible by 3, 6, 12, 24, 36, 48 or 60.

I don't know the random number neither the number to add to this random number in order to turn it divisible by 3, 6, 12, 24, 36, 48 or 60.

Can someone help me, please?

Using the map function list comprehension:

import random

n = [3, 6, 12, 24, 36, 48, 60]
a = random.randint(start, stop)

result = [a + x - a % x if a % x else a for x in n]
addition = [x - a for x in result]

print(a)
print(result)
print(addition)

start and stop are the limits for your random number.

Output for a = 311:

 311
[312, 312, 312, 312, 324, 336, 360]
[1, 1, 1, 1, 13, 25, 49]

Begin of the old answer to the rather unclear question before the first edit by the author.

The following post answers the question: Which is the next number after a , which is a multiple of all numbers of the list n , if it is not a ?

First the least common multiple lcm of the numbers from the list must be determined. For this purpose, the method least_common_multiple is executed for the complete list. The modulo operation then checks whether a is not already a multiple of the numbers. If this is the case, a is output. Otherwise, the next multiple of lcm is output.

from math import gcd
from functools import reduce

n = [3, 6, 12, 24, 36, 48, 60]
a = 311

def least_common_multiple(x, y):
    return abs(x * y) // gcd(x, y)

lcm = reduce(least_common_multiple, n)
result = a if a > 0 else 1  # can be change if necessary, see edit
mod = result % lcm
if mod:
    result += (lcm - mod)

print('Current number: ' + str(a))
print('The next number divisible by any number from the given list: ' + str(result))
print('Necessary addition: ' + str(result - a))

Output:

Current number: 311
The next number divisible by any number from the given list: 720
Necessary addition: 409

Edit : Changed the code so that 0 is no longer a valid result for a non-positive a . However, if it is valid, you can change the code at the commented part with: result = a .

New answer for the clarified question:

import math

def f(x, a):
    return math.ceil(a / x) * x - a

n = [3, 6, 12, 24, 36, 48, 60]
a = 311
result = [f(x, a) for x in n]
print(result)

Old answer:

I think you're looking for the LCM (lowest common multiple) of all numbers in n. We can get the LCM for two numbers using the GCD (greatest common divisor). We can then use reduce to get the LCM for the whole list. Assuming x can be negative, simply subtract a from the LCM to get your answer. The code could look like this:

import math
from functools import reduce

def lcm(a, b):  # lowest common multiple
    return a * b // math.gcd(a, b)

n = [3, 6, 12, 24, 36, 48, 60]
smallest_divisible_by_all = reduce(lcm, n)

a = 311
x = smallest_divisible_by_all - a
print(x)

which outputs

409

If speed is not important, you could also do a brute force solution like this:

ns = [3, 6, 12, 24, 36, 48, 60]
a = 311
x = 0

while not all([(a + x) % n == 0 for n in ns]):
    x += 1

(assuming that x >= 0)

So I can think of 2 solutions:

First if you want a list which show how much you have to add for the random number to get to a divisible number:

def divisible(numbers,random):
    l = []
    for number in numbers:
        if random % number != 0:
            l += [number - (random % number)]
        else:
            l += [0]
    return l

a = 311
n = [3, 6, 12, 24, 36, 48, 60]

print(divisible(n,a))

Output:

[1, 1, 1, 1, 13, 25, 49]

Or if you want to know how far is the smallest number from the random number that everyone shares as divisible. For this take a look how you calculate lcm.

from math import gcd

def divisible_all(numbers, random):
    lcm = numbers[0]
    for i in numbers[1:]:
        lcm = lcm*i//gcd(lcm, i)
    tempLcm = lcm
    while lcm < random: # in case the lcm is smaller than the random number add lcm until it is bigger (I assume you only allow positive numbers)
        lcm += tempLcm
    return lcm-random

print(divisible_all(n,a))

Output:

409

You can do:

import math

n = [3, 6, 12, 24, 36, 48, 60]

div_n={el: False for el in n}
a=311

a0=math.ceil(a/max(n)) * max(n)

while not all(div_n.values()):
    div_n={el: False for el in n}
#   print(a0)
    for el in n:
        if(a0 % el > 0):
            a0=math.ceil(a0/el) * el
            break
        else:
            div_n[el]=True

print(a0-a)

Output:

409

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM