"Numbers like 145 are called [factorions](https://en.wikipedia.org/wiki/Factorion).\n",
"\n",
"We can use similar logic as [problem 30](https://projecteuler.net/problem=30) to produce an upper bound for how many numbers to brute force. Let $f(n)$ be the sum of the factorials of the digits of $n$, and consider the largest seven digit number, 9999999. $f(9999999) = 7 \\times 9! = 2540160$. If we replaced any digits in 9999999, they would have to be smaller than 9, so the sum of the factorials of the digits would be smaller than 2540160. Therefore, for any $n \\leq 9999999$, $f(n) \\leq 2540160$, so for $n$ to *equal* $f(n)$, $n$ must be less than or equal to 2540160, as well.\n",
"\n",
"We can write a simple recursive function for calculating the sum of the factorials of the digits:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "06bc38a2",
"metadata": {},
"outputs": [],
"source": [
"from functools import cache\n",
"from math import factorial\n",
"\n",
"@cache\n",
"def sfd(n):\n",
" q = n // 10\n",
" if q == 0:\n",
" return factorial(n)\n",
" \n",
" return factorial(n % 10) + sfd(q)"
]
},
{
"cell_type": "markdown",
"id": "c6c47e17",
"metadata": {},
"source": [
"Now we just iterate over all the numbers less than our upper bound."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "b4642720",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{145, 40585}"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"factorions = {n for n in range(3, 2540161) if sfd(n) == n}\n",
"This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International license](https://creativecommons.org/licenses/by-sa/4.0/) and the [BSD Zero Clause license](https://spdx.org/licenses/0BSD.html)."