Project Euler #001 – Fizz Buzz

In: Project Euler

11 11月 2009

Project 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)))

ほかに面白い書き方ってあるかな?

  • コメントありがとうございます。エントリ拝見しました。

    >この後は力技じゃないと解けない問題もあるのかもしれないけどね :-d

    中盤以降は力技では解けないものがほとんどになってきますね。
    ご提示いただいたようなアプローチは Problem #202 などでは必須です。
    計算量(オーダー)を工夫するのは楽しいですね。
  • 初めまして。こんな解き方をやってみました。良ければ参考まで。
    http://antares.sci.fukuoka-u.ac.jp/wiliki/wiliki.cgi?matsuoka::ProjectEuler::Problem1
blog comments powered by Disqus
Get Adobe Flash playerPlugin by wpburn.com wordpress themes

About this blog

私 manjilab のポータル的サイトになっております。日々気付いたこと、考えたこと、発表したいものを載せていきます。

Photostream

    Lisp indent 考察Lisp indent 考察Lisp indent 考察Lisp indent 考察Lisp indent 考察Tips to use Clojure(Lisp) with TextMateTips to use Clojure(Lisp) with TextMateTips to use Clojure(Lisp) with TextMate