Генерация случайного числа с определенным количеством цифр и sum_of_digits (Python 3.8)

#python

#питон

Вопрос:

Я хочу сгенерировать случайное число с определенным количеством цифр (указанных пользователем), и эти цифры должны иметь определенную сумму, указанную пользователем. Я попытался назначить переменную команде random.randint(x,y), а затем проверить len() и sum() этой переменной, если она равна переменной, указанной пользователем, но это не привело к чему-то полезному. Код, который я пробовал, выглядит примерно так:

 required_length = input() required_sum = input() z = random.randint(0 , 99999) number = z length = len(z) sum1 = sum(int(digit) for digit in str(number)) if length == required_length and sum1 == required_sum:  print(z)  

Чтобы помочь, если я не был достаточно конкретен, допустим, я хочу сгенерировать число, которое должно состоять из 7 цифр, и сумма этих 7 цифр должна быть 7. Одним из этих случайных чисел может быть 1121101. Я надеюсь, что этот пример помог.

До скорой встречи всем, и большое спасибо за вашу помощь.

Комментарии:

1. Это может быть вовсе не случайное число. Например, N цифр, с суммой 1, у вас есть только один выбор. Я бы предложил придумать алгоритм для построения числа по вашему вкусу.

2. может ли число начинаться с нулей? вам нужно целое число или строка?

3. @norok2 выберите случайное число из пула чисел, соответствующих критериям.

4. @DanielF вопрос в том, как вы создаете такой пул

Ответ №1:

Простое решение

Вы можете создать список чисел, которые можно сгенерировать, а затем использовать random.choice() функцию для выбора 1 элемента из списка.

 import random  n = int(input("Amount of digits: ")) x = int(input("Sum of digits: ")) numbers = [num for num in range(10 ** (n - 1), 10 ** n) if sum(map(int, str(num))) == x] print(random.choice(numbers))  

Быстрое решение

 import random  t = []  def f(s, i):  r = sum(map(int, s))  if i == n:  if r == x:  t.append(s)  else:  for q in range(10) if len(s) else range(1, 10):  if r   q lt;= x:  f(s   str(q), i   1)  n = int(input("Amount of digits: ")) x = int(input("Sum of digits: "))  f("", 0) print(random.choice(t))  

Комментарии:

1. Ты пробовал свой код? Я получил 61 в результате, когда n=7 и x=7 .

2. Во-первых, использование глобальных переменных, как вы сделали во втором примере, не является хорошей практикой, а во-вторых, когда список чисел пуст, будет вызвана ошибка индекса.

3. Ошибка индекса возникает, например, когда n = 2 и x = 19

4. Я знаю, но в вопросе нет никаких инструкций для случаев, когда числа не могут быть сгенерированы.

5. Не могли бы вы объяснить, для чего нужны параметры функций «s» и «i»?

Ответ №2:

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

Идея состоит в том, что для данной цифры следует выбрать случайное число (от 0 до 9 включительно), за исключением случаев, когда результат может привести к нарушению ограничений, и в этом случае диапазон, из которого следует выбирать случайное число, должен быть соответственно уменьшен.

Другими словами, каждая цифра выбирается из числа допустимых значений с учетом «оставшейся» суммы и количества цифр.

Чтобы упростить вычисления, я работаю со списками цифр и предоставляю некоторую функцию для преобразования из списка цифр в целое число и наоборот. Обратите внимание, что для несовместимого числа цифр и значения суммы создается пустой список.

 import random   def seq_to_int(seq, base=10):  """Convert sequence of digits to an integer."""  result = 0  for i, x in enumerate(reversed(seq)):  if 0 lt;= x lt; base:  result  = x * base ** i  else:  msg = f"Invalid value in `seq` for given `base`"  raise ValueError(msg)  return result   def int_to_seq(n, base=10):  """Convert an integer to a sequence of digits."""  if n == 0:  return [0]  elif n lt; 0:  raise ValueError("`n` must be non-negative.")  else:  result = []  while n:  result.append(n % base)  n //= base  return result[::-1]   def random_digits_given_sum(num_digits, sum_value, base=10):   digits = []  max_digit = base - 1  if sum_value gt; max_digit * num_digits:  return digits  sum_left = sum_value  num_left = num_digits  while num_left gt; 0:  if sum_left gt; max_digit:  min_rand = max(0, sum_left - max_digit * (num_left - 1))  max_rand = max_digit  digit = random.randint(min_rand, max_rand)  elif sum_left gt;= 0 and num_left gt; 1:  min_rand = 0  max_rand = sum_left  digit = random.randint(min_rand, max_rand)  elif sum_left gt;= 0 and num_left == 1:  digit = sum_left  else:  raise ValueError   digits.append(digit)  sum_left -= digit  num_left -= 1  # ensure first digit is not 0  if digits[0] == 0:  non_zero_indices = [i for i, digit in enumerate(digits) if digit]  i = random.choice(non_zero_indices)  digits[0], digits[i] = digits[i], digits[0]  # shuffle remaining digits  shuffled = digits[1:]  random.shuffle(shuffled)  return digits[0:1]   shuffled  

Ниже приведен код, чтобы проверить, действительно ли он работает:

 random.seed(0) n = 2 # number of random inputs to gets k = 4 # number of different generations for _ in range(n):  num_digits = random.randint(1, 16)  sum_value = random.randint(1, num_digits * 9)  for _ in range(k):  digits = random_digits_given_sum(num_digits, sum_value)  print(digits, seq_to_int(digits), sum(digits), sum(digits) == sum_value)  

со следующим выводом:

 [6, 8, 8, 9, 8, 8, 0, 9, 9, 9, 9, 6, 9] 6889880999969 98 True [5, 9, 4, 7, 9, 5, 6, 9, 9, 9, 8, 9, 9] 5947956999899 98 True [8, 1, 9, 8, 2, 9, 9, 7, 9, 9, 9, 9, 9] 8198299799999 98 True [4, 2, 9, 7, 8, 9, 9, 9, 9, 9, 9, 9, 5] 4297899999995 98 True [6, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 9, 9] 699999999999499 127 True [4, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 9] 499999999999969 127 True [3, 9, 9, 9, 9, 7, 9, 9, 9, 9, 9, 9, 9, 9, 9] 399997999999999 127 True [9, 7, 5, 9, 9, 9, 9, 9, 8, 9, 8, 9, 9, 9, 9] 975999998989999 127 True  

показывая, что он работает так, как ожидалось.

Комментарии:

1. Большое спасибо за ваш подход к этому, однако я хотел бы знать, что означает число, стоящее за «Истинным». Протестировал его, и он действительно возвращает много за короткий промежуток времени даже при больших требованиях (например, 239). В остальном это очень функционально. Кстати, я уже давно не был в сфере программирования, поэтому и спрашиваю.

2. @noExplorer True печатается каждый раз, когда фактическая сумма цифр совпадает с запрошенной ( sum(digits) == sum_value ). Кроме того, если вы считаете, что этот ответ полезен, вы можете рассмотреть возможность его отмены.

3. Спасибо. Я действительно пытался проголосовать за это, но у меня нет необходимых кармических точек (у меня 13). Кроме того, когда я указываю число n и k как 239, оно возвращает 789 после «True».

4. n и k обратитесь к количеству тестов в соответствии с комментариями рядом с ними. Сами тесты генерируют случайные числа для количества цифр и их ожидаемой суммы и вводятся в качестве входных данных random_digits_given_sum() . Если у вас есть конкретные входные данные, просто передайте их непосредственно этой функции.

5. Попробовал, дело в том, что каждый результат, выданный пользователю, является ложным. Я отредактировал: random.seed(0) x = int(ввод(«Пожалуйста, укажите количество цифр «)) c = int(ввод(«Пожалуйста, укажите сумму цифр «)) n = 2 # количество случайных входов для получения k = 4 # количество разных поколений для _ в диапазоне(n): num_digits = random.randint(1, 16) значение суммы = random.randint(1, num_digits * 9) для _ в диапазоне(k): цифры = random_digits_given_sum(x, c) печать(цифры, seq_to_int(цифры), сумма(цифры), сумма(цифры) == значение суммы)