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, завершаться и только потом добавляться к общей сумме. Без сброса аккумулятора вы по сути считаете цепочки произведений через несколько цифр, что расходится с задумкой и приводит к завышенным результатам.

Выводы

Когда цикл вычисляет величины «на элемент» — факториал, степень, часть контрольной суммы, — убедитесь, что соответствующий аккумулятор переинициализируется внутри цикла. Общую сумму держите снаружи, а состояние для каждого элемента — внутри. Если выходные значения выглядят аномально большими, проверьте, какие переменные сохраняют значения между итерациями и какие следует сбрасывать.