素数を2乗,3乗,4乗した数の和についての問題です。
とりあえずfor(内包表記)を使ってやってみるかな、と思ってたらできちゃいました。
素数を2乗,3乗,4乗したものの上限以下のリストを作って、合計が上限以下になるように組み合わせます。
工夫といえば、
- a,b,cを2乗,3乗,4乗の順にしてしまうと、あふれてしまったので、逆順にした
- 複数の方法で表現できる数がある可能性を考慮した。(重複を考慮しない処理だと数が違うので、あるようです。)
ですかね。
最初に作ったのは、きたなくて、関数化されてませんでしたが、後で整形してます。
初めは、setのatomを使ってましたけど、使わなくてもできるかなと思って使わないバージョンも作りました。速度はほぼ一緒です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Problem 87 : 2012/07/25 | |
;; "Elapsed time: 14817.667785 msecs" | |
;; get-prime-list returns primes under 1e6 | |
(defn pe87 [lmt] | |
(let [res (atom #{}) | |
worked-prime (fn [f] (take-while #(< % lmt) (map f (get-prime-list))))] | |
(dorun | |
(for [a (worked-prime #(* % % % %)) | |
b (worked-prime #(* % % %)) | |
c (worked-prime #(* % %)) | |
:when (< b (- lmt a)) | |
:when (< c (- lmt a b))] | |
(swap! res conj (+ a b c) ))) | |
(count @res))) | |
(defn pe87-no-atom [lmt] | |
(let [worked-prime (fn [f] (take-while #(< % lmt) (map f (get-prime-list))))] | |
(->> (for [a (worked-prime #(* % % % %)) | |
b (worked-prime #(* % % %)) | |
c (worked-prime #(* % %)) | |
:when (< b (- lmt a)) | |
:when (< c (- lmt a b))] | |
(+ a b c)) | |
(flatten) | |
(distinct) | |
(count)))) |
・pe87
特に解説はしません。
・pe87-no-atom
atomを使わないバージョンです。
0 コメント:
コメントを投稿