2016-04-10 2 views
-2

Я хочу найти эффективный алгоритм для деления целочисленного числа на некоторое значение в диапазоне max, min. Должно быть как можно меньше значений.разделить значение на значения в max, min range

Например: макс = 7, 3 мин = затем

8 = 4 + 4 
9 = 4 + 5 
16 = 5 + 5 + 6 (not 4 + 4 + 4 + 4) 

РЕДАКТИРОВАТЬ

Для того, чтобы сделать его более ясным, давайте рассмотрим пример. Предположим, что у вас есть куча яблок, и вы хотите упаковать их в корзины. Каждая корзина может содержать от 3 до 7 яблок, и вы хотите, чтобы количество корзин было как можно меньше.

** Я упомянул, что значение должно быть равномерно разделено, но это не так важно. Меня больше беспокоит меньшее количество корзин.

+0

Как вы определяете "равномерно разделенный"? Что делает «16 = 5 + 5 + 6» лучшим решением, чем «16 = 4 + 4 + 4 + 4»? –

+0

Извините, что я не дал понять, я обновил вопрос, спасибо – TomNg

+0

Хорошо, следующий вопрос: что именно делает «16 = 5 + 5 + 6» лучше, чем «16 = 6 + 6 + 4»? –

ответ

1

Это поразило меня как забавную проблему, поэтому я решил быстро взломать решение. Я думаю, что это может быть интересной отправной точкой, это либо даст вам действительное решение с максимально возможным числом чисел, либо с максимально возможными числами, все в пределах диапазона, заданного параметрами min_bound и max_bound число = INT (вход ("номер:")) min_bound = 3 max_bound = 7

def improve(solution): 
    solution = list(reversed(solution)) 
    for i, num in enumerate(solution): 
     if i >= 2: 
      average = sum(solution[:i])/i 
      if average.is_integer(): 
       for x in range(i): 
        solution[x] = int(average) 
       break 
    return solution 

def find_numbers(number, division, common_number): 
    extra_number = number - common_number * division 
    numbers_in_solution = [common_number] * division 
    if extra_number < min_bound and \ 
    extra_number + common_number <= max_bound: 
     numbers_in_solution[-1] += extra_number 
    elif extra_number < min_bound or extra_number > max_bound: 
     return None 
    else: 
     numbers_in_solution.append(extra_number) 
    solution = improve(numbers_in_solution) 
    return solution 

def tst(number): 
    try: 
     solution = None 
     for division in range(number//max_bound, number//min_bound + 1): # Reverse the order of this for numbers as close in value to each other as possible. 
      if round (number/division) in range(min_bound, max_bound + 1): 
       solution = find_numbers(number, division, round(number/division)) 
      elif (number // division) in range(min_bound, max_bound + 1): # Rarely required but catches edge cases 
       solution = find_numbers(number, division, number // division) 
      if solution: 
       print(sum(solution), solution) 
       break 
    except ZeroDivisionError: 
     print("Solution is 1, your input is less than the max_bound") 

tst(number) 
for x in range(1,100): 
    tst(x) 

Этот код просто продемонстрировать идею, я уверен, что он может быть изменен для лучшей производительности.

+0

. С коротким решением вы, вероятно, можете перебирать список, чтобы узнать, было ли среднее значение, которое приблизило бы числа. Например, если ваше решение было [5, 5, 5, 2], сначала будет выглядеть 5 и 2, их среднее значение равно 3,5, поэтому оно пропустит его. Затем он будет смотреть на 5, 5, 2, их среднее значение равно 4, поэтому оно может обновить решение до [5, 4, 4, 4]. –

+0

, если ввод равен 20, тогда результат будет [5, 5, 5, 5]. Это должно быть [7, 7, 6] – TomNg

+0

Больше! Я обновил его выше. Ему нужно было проверить округленное деление до разделения пола. Я добавил в идею усреднения, поэтому он попытается взять такие ответы, как [5, 5, 5, 2] и превратить их в [5, 4, 4, 4] –

Смежные вопросы