145 is a curious number, as 1! + 4! + 5! = 1 + 24 + 120 = 145.

Find the sum of all numbers which are equal to the sum of the factorial of their digits.

Note: as 1! = 1 and 2! = 2 are not sums they are not included.

from time import time

def fact(n):
    """returns factorial of n."""
    total = 1
    for number in range(2, n + 1):
        total *= number
    return total

def fact_curious(n, factorials={1:1, 2:2}):
    """Assumes n is the range to check for curious numbers.
    generates curious numbers within n range."""
    for number in range(3, n):
            if sum(factorials[int(digit)] for digit in str(number)) == number:
                yield number
        except KeyError:
            for digit in str(number):
                factorials[int(digit)] = fact(int(digit))
            if sum(factorials[int(digit)] for digit in str(number)) == number:
                yield number

if __name__ == '__main__':
    start_time1 = time()
    print(f'Time: {time() - start_time1}')
  • 3
    \$\begingroup\$ Please tag all Python questions with python, if you only have python-3.x then your question is more likely to go unanswered. \$\endgroup\$
    – Peilonrayz
    Jul 21, 2019 at 6:49

1 Answer 1

  1. There is math.factorial function. So no need to reinvent it.
  2. Using try/except for control flow is a bad practice. It's better to explicitly check whether a list contains a value using the condition if int(digit) in factorials. It also will eliminate the code duplication in except branch.
  3. It's even better to pre-calculate all factorials for digits from 0 to 9. Anyway, you will reuse them all a lot of times.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.