Fibonacci数列を作ろう！



# 目次

このページではFibonacci数列をTDDの手順を踏んで作成する．今回は以下の順で説明する．

-   [Fibonacci数列とは](#fibonacci数列とは)
-   [今回の手法の説明](#今回の手法の説明)
-   [初項の作成](#初項の作成)
-   [第二項の作成](#第二項の作成)
-   [第三項の作成](#第三項の作成)
-   [第四項以降の作成](#第四項以降の作成)


# Fibonacci数列とは

Fibonacci数列とは

    0 1 1 2 3 5 8 13 21 ...

という数列だ，これは一般的に，

    fib(n) = fib(n-1) + fib(n-2)

と表すことができる．今回はこれを再帰を用いて表すプログラムを作成する．

[目次へ](#目次)


# 今回の手法の説明

今回はテスト駆動開発(TDD)の手順，red, green, refactoringを意識して作成する．

red　-> やりたいことをとりあえず書いてテストしてみてエラーを確認する

green -> エラーを削除してひとまず動くものを作成する

refactoring -> きれいに意味のあるコードにする

ということらしい．とりあえず動くものを作ってからコードをきれいにする方が効率がいいとかなんとか．

[目次へ](#目次)


# 初項の作成

初項，第二項は一般的に表すことができないので先に作っておく．

Fibonacci数列の初項は0である．

**red** : fibというメソッドを作成しFibonacci数列を作成する．まずは以下のようにテスト．

```ruby:fibo.rb
p fib(0)
```

このように書いてテストをするが，何も書いていないため動くわけがない．

だがこれでいい．このエラーを取り除いていく．

また，前回作成したassert\_equal.rbを呼び出しテストできる環境を用意しておく．

```ruby:fibo.rb
require './assert_equal'
puts assert_equal(0, fib(0))
```

**green** : 「n = 0 の場合は値が0である」ことを表すメソッドを作成する

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    if n == 0
	    return 0
    end
end

puts assert_equal(0, fib(0))
```

こうすることでひとまず初項を表示することができた．次はこれをきれいにしていく．

**refactoring** : 

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n == 0
end

puts assert_equal(0, fib(0))
```

こうすることで二行短くなった．英語の文法のようでみやすいし．

[目次へ](#目次)


# 第二項の作成

**red** : 次は第二項を作成する．

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n == 0
end

puts assert_equal(0, fib(0))
puts assert_equal(1, fib(1))
```

**green** : 先程と同様にすればいい，

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n == 0
    if n == 1
	return 1
    end
end

puts assert_equal(0, fib(0))
puts assert_equal(1, fib(1))
```

**refactoring** : こちらも同様に．

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n == 0
    return 1 if n == 1
end

puts assert_equal(0, fib(0))
puts assert_equal(1, fib(1))
```

assert\_equalの部分が増えてきたのでここもrefactoringする．

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n == 0
    return 1 if n == 1
end

[[0,0],[1,1]].each do |pair|
    puts assert_equal(pair[0], fib(pair[1]))
end
```

[目次へ](#目次)


# 第三項の作成

**red** : まずはテスト．テスト部分だけ下に表示する．

```ruby:fibo.rb
require './assert_equal'

[[0,0],[1,1],[2,1]].each do |pair|
    puts assert_equal(pair[0], fib(pair[1]))
end
```

**green** : 

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n == 0
    return 1 if n == 1
    return 1
end

[[0,0],[1,1],[2,1]].each do |pair|
    puts assert_equal(pair[0], fib(pair[1]))
end
```

これでも最後がエラーになる，なぜならassert\_equalは(予想，結果)と受け取るからである．なので逆にしてみると．．．

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n == 0
    return 1 if n == 1
    return 1
end

[[0,0],[1,1],[2,1]].each do |pair|
    puts assert_equal(pair[1], fib(pair[0]))
end
```

**refactoring** : 

先程のエラーが起こらないようわかりやすく単語で表記する．

```ruby:fibo.rb

[[0,0],[1,1],[2,1]].each do |index, expected|
    puts assert_equal(expected, fib(index))
end
```

こうすることで後で見やすくなる．

[目次へ](#目次)


# 第四項以降の作成

最後に上記を基に一般的な動作を表す．

**red** : 

```ruby:fibo.rb

require './assert_equal'
[[0,0],[1,1],[2,1],[3,2],[4,3],
[5,5],[6,8],[7,13],[8,21]].each do |index, expected|
  puts assert_equal(expected, fib(index))
end
```

これを動くようにする，

**green** : 

連続した二項を足したものが次の項になるので

    fib(n) = fib(n-1) + fib(n-2)

となる．これを実装すると，

```ruby:fibo.rb
require './assert_equal'

def fib(n)
    return 0 if n==0
    return 1 if n==1
    return fib(n-1) + fib(n-2)
end

[[0,0],[1,1],[2,1],[3,2],[4,3],
[5,5],[6,8],[7,13],[8,21]].each do |index, expected|
puts assert_equal(expected, fib(index))
end

```

[目次へ](#目次)


# まとめ

今回は再帰を利用してFibonacci数列を表示した．



------
 - **source** ~/prog/github/grad_members_20f/members/miyanagi/post/fibo.org