rubyでテスト駆動ProjectEuler:Problem2
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
さて、テストコード
require 'test/unit' require './euler2.rb' class Euler2 < Test::Unit::TestCase def test_euler2 assert_equal(euler2(10), 10) end end
テストコードの書き方もちゃんと知らないとだけど、とりあえずはrubyに慣れるのが目的
遅くて読みにくいコード
def fib(n) ans = 0 if n == 1 ans = 1 elsif n == 2 ans = 2 else ans = fib(n-1) + fib(n-2) end return ans end def even(num) if num % 2 == 0 return num else return 0 end end def euler2(num) sum = 2 i = 3 b = fib(i) while b < num do i = i + 1 sum = sum + even(b) b = fib(i) end return sum end
”りふぁくたりんぐ”をしてみる。
疑問符演算子を使う
evenの中身を書き換える。
if num % 2 == 0 return num else return 0 end
の部分を
return (num % 2 == 0) ? num : 0
に変える。
同じ要領で、fibのほうも書き換えられる。
変更後その1
def fib(n) return (n <= 2) ? n : (fib(n-1) + fib(n-2)) end def even(num) return (num % 2 == 0) ? num : 0 end def euler2(num) sum = 2 i = 3 b = fib(i) while b < num do i = i + 1 sum = sum + even(b) b = fib(i) end return sum end
even?メソッドを使う
そもそも自前で作る必要なんてないよね、ということで、even?メソッドを使う。
変更後その2
def fib(n) return (n <= 2) ? n : (fib(n-1) + fib(n-2)) end def euler2(num) sum = 2 i = 3 b = fib(i) while b < num do i = i + 1 sum = (b.even?) ? (sum + b) : sum b = fib(i) end return sum end
あとは末尾再帰に
見た目はすっきりしてきたので、あとは末尾再帰化を・・・というつもりだっt.あ
ところが、既に大分丁寧に解説されている記事を見つけてしまったので、
書かなくてもいいかな、と思っちゃいました。
ありがたく、こちらを見ましょう。
フィボナッチ数(2) ver.末尾再帰 - 名古屋で数学するプログラマ(仮)