1
\$\begingroup\$

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):
        try:
            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(sum(fact_curious(100000)))
    print(f'Time: {time() - start_time1}')
\$\endgroup\$
  • 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 at 6:49
2
\$\begingroup\$
  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.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.