problem 30

Problem 30 - Project Euler

各桁の数字を5乗したものの和がもとの数と等しくなる数の合計を求めるという問題です。

ループを使わずに fold, map, filter などの高階関数のみで解いてみました。

(list 1 10 100 1000 10000 100000 1000000)

で済むところを

(map (lambda (x) (expt 10 x)) (list 0 1 2 3 4 5 6))

としてるのはちょっと無駄ですが、見た目のスッキリさをとりました。

(use srfi-1)

(define (sum-of-fifth-power n)
  (apply + 
        (map (lambda (x) (expt (modulo
                                 (quotient n (expt 10 x))
                                 10)  ; 各桁の数字のリスト
                               5))    ; を 5 乗した数を fold で足す
             (list 0 1 2 3 4 5 6))))

(define (p30)
  (apply +
        (filter (lambda (x) (= x (sum-of-fifth-power x)))
                (iota 1000000 2 1))))

(display (p30))

9^5*5 が 295245 なので 1000000 までやっておけば充分かなと。正解したのでよし。

わかったこと

  • iota というリスト構築子が便利
  • map と filter, map と fold はナイスコンビ

2008/07/07 01:00 修正

(fold + 0 ...)

(apply + ...)

に修正しました。間違ってるわけじゃないですが、apply の方がすっきりします。