#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(цифры), сумма(цифры), сумма(цифры) == значение суммы)