0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Ruby】今日書いたコードの振り返り(繰り返し)#8

Last updated at Posted at 2024-12-19

はじめに

こんにちは!アメリカで独学でソフトウェアエンジニアを目指しているものです。
今回はフィボナッチ数列を計算するプログラムを題材に、コードの改善方法や学んだことを共有します。

問題の内容

整数 n を受け取り、フィボナッチ数列の最初の n 個を表示してください。
フィボナッチ数列は以下のように定義されます:

  • F(0) = 0
  • F(1) = 1
  • F(n) = F(n-1) + F(n-2) (n >= 2)
    例えば、n = 10 の場合は以下を出力します
0
1
1
2
3
5
8
13
21
34

私の解答

def generate_pattern(n)
  f_b = 0
  f = 1
  f_a = 0
  (1..n).each do |i|
    case i
    when 1
      puts f_b
    when 2
      puts f
    else
      f_a = f + f_b
      puts f_a
      f_b = f
      f = f_a
    end
  end
end

generate_pattern(10)

このコードでも正しくフィボナッチ数列を出力できますが、case 文を用いて i の値を判定しているため、やや冗長に感じます。
i == 1 の場合は0、i == 2 の場合は1、それ以降はフィボナッチ数列を計算しています。

上記のコードの改善

case文を使わず、最初の2つの値を条件分岐で単純に出力し、その後 3..n のループで残りの値を生成する方法に改善します。

def generate_pattern(n)
  f_b = 0
  f = 1

  # nが1以上なら、最初の値0を表示
  puts f_b if n >= 1
  # nが2以上なら、次の値1を表示
  puts f if n >= 2

  # 3番目以降の値は繰り返しで計算
  (3..n).each do
    f_a = f + f_b
    puts f_a
    f_b = f
    f = f_a
  end
end

generate_pattern(10)

もしnが3より小さいと範囲が空(3以上の数が存在しない)となり、ループは一度も実行されません。

さらにシンプルな解法

この解き方もChatgptを使用して出力してもらいました。
この例では配列を使っています

def generate_fibonacci(n)
  # 初期値を設定
  fib = [0, 1]

  # nが2より大きい場合は、3番目以降の要素を追加
  (2...n).each do
    fib << fib[-1] + fib[-2]
  end

  # 最初のn個を表示
  fib.first(n).each { |num| puts num }
end

generate_fibonacci(10)

このコードでは、fib配列の末尾から2つの要素を足して次の要素を生成していくため、計算ロジックが明確で、if や条件分岐がほとんど必要ありません。
(2...n) という範囲を用いることで、最初の2つの値(0と1)はすでに決まっているため、ループは3番目の値から計算を始めます。
fib.each { |num| puts num }ではなく、fib.first(n).each { |num| puts num }であるのは、n が 1 の場合でも 0 と 1 の2つの要素を出力してしまい、要件である「最初の n 個」を正しく満たしていません。

なぜ配列を使うと簡潔なのか

  • 最初の2つの値を [0,1] として確定しておくことで、if 文を使わずにすべてをループで処理できます。
  • fib[-1]fib[-2] など、配列末尾の要素を簡単に参照できるため、計算がシンプルです。

学んだこと

  • 重複や冗長な条件分岐を避ける
    最初の2つの値だけ特別扱いするためにifcase文を多用すると、コードが読みづらくなります。
    最初から [0, 1] を配列に設定し、後続の値をループで計算する方法の方が直感的でスッキリ書けます。

まとめ

最初のコードは機能は正しかったものの、case 文で条件分岐するなど、やや冗長でした。
初見で思い浮かぶほどの演習はできていないのでこれからもアウトプットと復習を継続してコーディング力をあげていきたいです

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?