2025, Dec 29 18:01
Сумма факториалов цифр в Python: почему результат завышен и как это исправить
Разбираем ошибку в Python при подсчёте суммы факториалов цифр: забытый сброс аккумулятора. Даем исправленный код, объясняем причину и как избежать ошибки.
Когда перебираешь цифры числа и суммируешь их факториалы, чрезмерно большой итог нередко указывает на переменную с состоянием, которую забыли сбросить между итерациями. В этой ситуации множитель, применяемый для вычисления факториала каждой цифры, продолжает расти от одной цифры к следующей, раздувая сумму сильнее, чем задумано алгоритмом.
Проблема
Ниже приведен минимальный пример, который дает значительно больший итог, чем ожидается, потому что аккумулятор факториала не обнуляется для каждой цифры.
num = int(input())
acc = 0
digit = 0
fact = 1
while num != 0:
digit = num % 10
for k in range(1, digit + 1):
fact = fact * k
acc = acc + fact
num = num // 10
print(acc)В чем ошибка
Задумка проста: взять последнюю цифру, посчитать ее факториал, прибавить к накопленной сумме и перейти к следующей цифре. Однако аккумулятор факториала инициализируется лишь однажды перед циклом и затем переиспользуется для всех цифр. Это означает, что факториал текущей цифры перемножается поверх результата предыдущей, вместо того чтобы каждый раз начинаться с 1. Размещать извлечение цифры внутри цикла правильно, ведь на каждой итерации берется новая последняя цифра, но и аккумулятор факториала должен быть локален для итерации, чтобы не тянуть состояние.
Факториалы действительно очень быстро становятся «невероятно большими».
Наблюдение верное в целом, но здесь раздутую сумму дает именно несброшенный аккумулятор.
Решение
Переинициализируйте аккумулятор факториала на каждом проходе цикла, чтобы факториал каждой цифры считался независимо, затем прибавляйте его к сумме и продолжайте.
num = int(input())
acc = 0
while num != 0:
digit = num % 10
fact = 1
for k in range(1, digit + 1):
fact = fact * k
acc = acc + fact
num = num // 10
print(acc)Почему это важно
Состояние, непреднамеренно сохраняющееся между итерациями, — частый источник логических ошибок в циклах. Алгоритм здесь держится на изоляции: факториал каждой цифры должен стартовать с 1, завершаться и только потом добавляться к общей сумме. Без сброса аккумулятора вы по сути считаете цепочки произведений через несколько цифр, что расходится с задумкой и приводит к завышенным результатам.
Выводы
Когда цикл вычисляет величины «на элемент» — факториал, степень, часть контрольной суммы, — убедитесь, что соответствующий аккумулятор переинициализируется внутри цикла. Общую сумму держите снаружи, а состояние для каждого элемента — внутри. Если выходные значения выглядят аномально большими, проверьте, какие переменные сохраняют значения между итерациями и какие следует сбрасывать.