Post date: Jul 29, 2014 1:1:50 AM
"Find all numbers above 2 that are equal to the sum of the factorials of their digits. Sum them."
We know that we only need to calculate factorials up up to 7 digit numbers, because the max you can get out of 8 digits is 2903040, which is only 7 digits.
CREATE TABLE #Factorials (i NUMERIC(38,0) PRIMARY KEY NOT NULL, factorial NUMERIC(38,0) NOT NULL)
INSERT INTO #Factorials VALUES (0, 1)
-- Rather than repeatedly recalculate factorials, I'll do it once, store it in a table, and then do a simple lookup.
; WITH Integers (i) AS
(
SELECT 0
UNION ALL
SELECT i + 1
FROM Integers
WHERE i < 9
)
INSERT INTO #Factorials
SELECT i1.i, EXP(SUM(LOG(CONVERT(NUMERIC(38,18),i2.i))))
FROM Integers i1
INNER JOIN Integers i2
ON i2.i <= i1.i
AND i2.i > 0
WHERE i1.i > 0
GROUP BY i1.i
-- Return the results.
; WITH Results AS
(
SELECT 1000000 * g.i + 100000 * k100.i + 10000 * k10.i + 1000 * k.i + 100 * h.i + 10 * t.i + o.i AS i
, o.factorial AS o
, t.factorial AS t
, h.factorial AS h
, k.factorial AS k
, k10.factorial AS k10
, k100.factorial AS k100
, g.factorial AS g
FROM #Factorials g
CROSS JOIN #Factorials k100
CROSS JOIN #Factorials k10
CROSS JOIN #Factorials k
CROSS JOIN #Factorials h
CROSS JOIN #Factorials t
CROSS JOIN #Factorials o
WHERE 1000000 * g.i + 100000 * k100.i + 10000 * k10.i + 1000 * k.i + 100 * h.i + 10 * t.i + o.i > 9
)
SELECT SUM(i)
FROM Results
WHERE i = o + t +
-- The fact that 0! is 1 causes us problems, because these results are all padded with zero on the left.
-- We can't just pull data from the table. We need to handle the digits over the second.
CASE WHEN i < 100 THEN 0 ELSE h END +
CASE WHEN i < 1000 THEN 0 ELSE k END +
CASE WHEN i < 10000 THEN 0 ELSE k10 END +
CASE WHEN i < 100000 THEN 0 ELSE k100 END +
CASE WHEN i < 1000000 THEN 0 ELSE g END
DROP TABLE #Factorials