いわゆる卍研究所。
In: Project Euler
11 11月 2009Project EulerをClojureでおさらい。
さっそく Problem 1 から。
オリジナルはこちら
(2001年10月5日公開って・・・そんなに昔からやってたのね。)
日本語訳:
10未満の自然数で3もしくは5の倍数であるものは 3,5,6,9 となり、合計すると23となる。
同様にして1000未満の場合の合計を求めよ。
いわゆる Fizz Buzz ですな。
Clojure で基本的な語意だけで書いてみる。
; Clojure (reduce + (concat (range 0 1000 3) (range 0 1000 5) (range 0 -1000 -15)))
(0 3 6 9 12 15 … 999) (0 5 10 15 20 … 995) (0 -15 -30 -45 …. -990) という数列をconcatで合体して、reduceを使って各要素を + で結合するイメージ。
数列を集合として和をとると、distinctを使って
; Clojure (reduce + (distinct (concat (range 3 1000 3) (range 5 1000 5))))
と書ける。
ちなみに以前Rubyで解いたときはこう書いた。
# Ruby (1...1000).select{|x| (x % 3 == 0) || (x % 5 == 0) }.inject(0){|s,x| s+x }
同様のやり方をClojureで書くと
; Clojure (reduce + (filter #(or (zero? (rem % 3)) (zero? (rem % 5))) (range 1000)))
とかける。 意味を壊さない程度に圧縮してみるとこのくらい。
# Ruby (1...1000).select{|x|(x%3==0)||(x%5==0)}.inject(0){|s,x|s+x}
; Clojure (apply +(filter #(zero?(min(rem% 3)(rem% 5)))(range 1000)))
ほかに面白い書き方ってあるかな?
私 manjilab のポータル的サイトになっております。日々気付いたこと、考えたこと、発表したいものを載せていきます。