Created
January 9, 2013 14:18
-
-
Save ponkore/4493455 to your computer and use it in GitHub Desktop.
Project Euler Problem 25
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
(ns projecteuler.problem-25 | |
(:require [clojure.string :as str] | |
[clojure.math.numeric-tower :as math]) | |
(:use clojure.test)) | |
(defn fib-gen | |
"フィボナッチ数を generate する関数。初期値[1 1]から iterate する前提。" | |
[[a b]] [b (+' a b)]) | |
(def fib-seq | |
"フィボナッチ数とその項を返す。" | |
(->> (iterate fib-gen [1 1]) | |
(map first) | |
(map-indexed (fn [idx itm] [(inc idx) itm])))) | |
(defn find-min-fibs | |
"lower 以上で最小のフィボナッチ数とそのindexを返す。" | |
[lower] | |
(first (drop-while #(<= (second %) lower) fib-seq))) | |
(defn problem-25 | |
"Project Euler Problem 25" | |
([] (problem-25 (math/expt 10 999))) | |
([lower] (first (find-min-fibs lower)))) | |
;;(time (problem-25)) | |
;;=> "Elapsed time: 5.387 msecs" | |
;; test | |
(is (= (find-min-fibs 100) [12 144])) | |
(is (= (problem-25 100) 12)) |
👍 読みやすいです.
doc-string と解説, とても分かりやすいです.
解法も順当で何の問題も無いと思います.
さしたる別解も思い浮かばないので, 本当に些細な点で,
- fib-seq がインデクス付きシーケンスを返すことを doc-string に明記するだけでなく, 関数名にも反映 (indexed-fibs とか) するというのは如何でしょう.
- インデクスが 1から始まるのはプログラマから見れば特殊なので, doc-string に明記するか, map-indexed が付けてくれたインデクスを毎回 inc しているのがもったいないので, fib-seq が返すシーケンスのインデクスは 0から始めておいて, 解答を作るときに inc する. というのはどうでしょう.
tnoda さん、kohyama さん
- コメントありがとうございます。
- indexed-fibs 、命名としてはこちらのほうがいいですね。いつも命名の仕方で迷います(結果失敗することも...)。
- インデックスを毎回 inc するのは、確かにもったいないですね。ご指摘ありがとうございます。
- Problem2、以前見たよりコメントが伸びてた...。この週末にでもみなさんの解答をもう一度おさらいしておきたいです(なかなか追いつかないので困ったもんです)。
Problem2、以前見たよりコメントが伸びてた...。この週末にでもみなさんの解答をもう一度おさらいしておきたいです(なかなか追いつかないので困ったもんです)。
他の問題もかなり伸びているので,ぜひ,もう一度見てコメントを追加してみてください.
コードにあえてコメントするとすれば、fib-seqがフィボナッチ数列の生成と、インデクシングをいっしょにしているのに違和感があります。 別にしたほうがきれいだと思います。
変数や関数の命名は僕もたいてい失敗します。
googleのlispのコーディング規約 にあるように、「中身(content)ではなく目的(intent)によって命名すべき」というのは頭にあってもつい xxx-list とかになってしまう。
take-while
にして、 count
するのもいいかと思いました。
(defn fibs [] (map first (iterate (fn [[x0 x1]] [x1 (+ x0 x1)])
[1N 1N])))
(defn solve [limit-exclusive]
(inc (count (take-while #(< % limit-exclusive) (fibs)))))
(solve (. (java.math.BigInteger. "10") pow 999))
この方法でやると、インデックスをプログラムからなくせます。
+'
の存在、初めて知りました。勉強になります。
いや、ほんのちょびっとしか翻訳していないんです...偉そうにリンク出してしまったのですが、なんだか申し訳ない(暇できたらまたやります!!)。
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
考え方とか感想とか
map-indexed
でフィボナッチ数の項(index)を当て込んでいます。drop-while
し、最終的にはその項(index) を答えとして返します。clojure.math.numeric-tower/expt
を使いました([org.clojure/math.numeric-tower "0.0.2"]
)。