Project Euler Problem 34 Solution

Question

145 is a curious number, as 1!+4!+5!=1+24+120=1451! + 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!=11! = 1 and 2!=22! = 2 are not sums they are not included.

Clojure

#!/usr/bin/env clojure
(defn factorial [n]
  (if (or (= n 1) (= n 0)) 
    1 
    (* n (factorial (- n 1)))))

(defn digits [number]
  (map #(- (int %) 48) (str number))) 

(defn curious? [number]
  (and (= (apply + (map factorial (digits number))) number)
       (> (count (digits number)) 1)))

(println (reduce + (filter curious? (range 50000))))
$ time clojure curious.clj
real   0m0.846s
user   0m1.576s
sys    0m0.096s

Haskell

factorial :: Int -> Int
factorial n = product [1..n]

digits :: Int -> [Int]
digits 0 = []
digits n = r : digits q
    where (q, r) = quotRem n 10

curious :: Int -> Bool
curious n = n == sum (map factorial (digits n))

main :: IO ()
main = print $ sum $ filter curious [10..50000]
$ ghc -O2 -o curious curious.hs
$ time ./curious
real   0m0.011s
user   0m0.008s
sys    0m0.000s

Ruby

#!/usr/bin/env ruby
puts (0..50000).select { |i|
  i.to_s.length > 1 && i == i.to_s.each_char.map { |d| (1..d.to_i).reduce(1, :*) }.reduce(:+)
}.reduce(:+)
$ time ruby curious.rb
real   0m0.292s
user   0m0.280s
sys    0m0.008s

Scheme

(define (factorial n)
  (apply * (iota n 1)))

(define (digits n)
  (if (zero? n)
    '()
    (cons (remainder n 10) (digits (quotient n 10)))))

(define (curious? n)
  (and (= (apply + (map factorial (digits n))) n)
       (> (length (digits n)) 1)))

(display (apply + (filter curious? (iota 50000))))
(newline)
$ time mit-scheme-native --quiet < curious.scm
real   0m0.431s
user   0m0.400s
sys    0m0.028s