11/14 関数から「計算」へ


前回の感想,質問より

Q.
rbファイルの最後にスペースを入れてしまうとrubyファイルと認識されなく、loadができないということもありました。
A.
はい.ファイル名は完全に一致していないとロードできません.
Q.
sphereの定義の最後のimageの意味がわからない。
A(関根さん).
Ruby の関数は、「最後に書いた式の値を関数の値として返す」という決まりがあります。 最後の image の前の行までで image という配列を用意しているのですが、 それを呼出元に返すためには最後に image と書かなければならない訳です。
A.
Rubyでは関数の値として返すために,
 return image
のように明示的に書く書き方もありますが,この教科書では 「最後に書いた式の値を関数の値として返す」書き方に統一しています.解答を作成する際は,returnを使っても構いません.
Q.
def divisible(x,y)
 if x % y==0
 1
 else
 0
 end
 end
で、xがyで割り切れるなら1を返して、割り切れないなら0を返してくれるはずです。
A.
この定義自体は説明通りの動作をしますが,
 if divisible(9,2)
  30
 else
  20
 end
のように使うと 30 という答えになり,意図とは違う答えになります.多くのプログラミング言語では,if の条件式の値が0の時は,falseと同じ意味になるのですが,rubyではtrueと同じになります.
 def divisible(x,y)
  if x % y==0
   true
  else
   false
  end
 end
のように書けば直りますが,そもそも,スライドにあるように
 def divisible(x,y)
  x % y==0
 end
と書くのがすっきりしています.
Q(一部の関数名を伏字にしています).
クラッツ問題を解こうとしたプログラム
XXXXX(58967893978978950534089046859078906876)
=> 1
XXXXX(444444444444444444444444444444444444444444444444444444444444444444444444444
4444444444444444444444444444444444444444444)
=> 1
かなり大きな値まで瞬時に計算する様は芸術に値した。 macの限界を知るべく大きな数字の計算をやらせたが、平然と返す様はめげずに生きる勇気を与えてくれた。

今日はTAにfrac関数を教えてもらった。階乗を計算するプログラムだが、その限界はn=2830であった。 無限操作のプログラムでnに代入すべきところをもとの関数に代入していたことが誤りであることを知れたのが今 日の収穫

これからもガッツで乗り越えたい

A(関根さん).
コラッツ問題」(Collatz problem) です。

C言語等で計算できる整数値は32ビット(約40億)或いは64ビット(約1844京)等の上限値が あるのですが、Ruby は標準で無限長演算がサポートされているのが特徴の一つです。

実は書き方を工夫すればもっと大きな入力に対しても正しい計算を行わせることができます。 (今回の授業の範囲までの知識でできます) 興味があったら試してみましょう。

頑張ってください。 それと、関数名の付け方はもうちょっと気を遣ってください。


Q.
教科書40P3行目の太字直後スペース必要だと思います。51Pの1行目正しくは『組み合わせ』では
A.
その通りですね.正誤表に載っていないようなので,著者の増原先生に連絡しておきます.
Q.
【2次方程式の解の個数を求めるプログラム】
def solutions(a,b,c)
  if a != 0
    if b**2 - 4*a*c > 0
      2
    else 
      if b**2 - 4*a*c = 0
        1
      else
        0
      end
    end
  else
    1
  end
end
solutions(2,0,1)を実行すると本来は0のはずなのに1が返されました。 どうしてでしょうか?
A(滝瀬さん).
if b**2 - 4*a*c = 0
は,正しくは
if b**2 - 4*a*c == 0
です. 「=」は左辺に右辺を代入をしていて,「==」は両辺が等しいかどうかを比較しています. 今回の場合は判別式が0かどうか比較をしたいので「==」でないといけません. これはとても間違いやすく,自分で気付きにくいので気をつけましょう.
Q.
def sum_loop(n)
 s=0
 for i in 1..n
  s=s+i
 end
 s
end
この定義の意味がよくわかりませんでした。
A(関根さん).
わからなかったのはどの部分でしょうか?

例えば

for i in 1..n
  s = s + i
end
の部分は、

i = 1, 2, ..., n と置いて for … end の間(この場合は s = s + i)を繰り返しなさい という意味を表しています。
つまり、

s = s + 1
s = s + 2
 (中略)
s = s + n
という意味です。
Q.
def solutions(a,b,c) 
 D=b**2-4*a*c
 (省略)
end
A(関根さん).
D=b**2-4*a*c
アルファベット大文字で始まる識別子は「定数」という特別な種類の値として扱われます。 このような場合は小文字で始まるもの(D ではなく d など)を使いましょう。

前回の課題について


投票システム

vote.rbをダウンロードして,ホームディレクトリに保存してください.ドックからターミナルを起動して,
ruby vote.rb 選択肢番号
のように使います.

今日の練習,投票

関連リンク


教科書の補足


今日の課題