Skip to content

Instantly share code, notes, and snippets.

@emanon001
Created December 15, 2012 09:08
Show Gist options
  • Save emanon001/4292285 to your computer and use it in GitHub Desktop.
Save emanon001/4292285 to your computer and use it in GitHub Desktop.
Project Euler Problem 6 #mitori_clj
;;; Project Euler Problem 6
;;; 「二乗の和と和の二乗の差はいくつか?」
;;; http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%206
(use 'clojure.test)
(defn sum-of-squares
"与えられた数列についてその二乗の和を返します"
[nums]
(apply + (map #(* % %) nums)))
(defn square-of-sum
"与えられた数列についてその和の二乗を返します"
[nums]
(apply * (repeat 2 (apply + nums))))
(defn solve
"最初の n 個の自然数について、二乗の和と和の二乗の差を返します"
[n]
(->> (range 1 (inc n))
((juxt square-of-sum sum-of-squares))
(apply -)))
(is (= (solve 10) 2640))
(time (solve 100))
@kohyama
Copy link

kohyama commented Dec 21, 2012

重要な理由として DRY (Don't Repeat Yourself) 原則があります.
同じことをするコードを複数書いてしまうと, 実装を変更する時にそれら全てを更新しなければならないので良くありません.
#(* % %) の部分や (range 1 (inc n)) がもっと大きなコードであった場合を想定し, 一度しか書かないためのイディオムを演習しておくと良い. と思います.

その上で, 抽象化しようとしているものの性質

「シーケンスの各要素の計算が高コストなのでメモリを使ってでも二度は計算したくない」のか、 「(もしかしたらものすごく長い)繰り返しの抽象化として遅延シーケンスを使っているのか」

で扱いを変えたほうが良いというのは, なるほど. 確かにおっしゃる通りですね.
今後, 意識してみようと思います.

前者については, Problem 14 の方で話題にあがっている「メモ化」も参考になるかと思います.

@bouzuya
Copy link

bouzuya commented Jan 13, 2013

juxt は面白い関数なのですが、使うのにちょうど良い場面になかなか遭遇しない(ぼくが気づいていない)ですね。

うまく使えている例だと思います。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment