楽しいRuby 第4版 Numericクラス
楽しいRubyで残しときたいメモが以外に多いので分ける。
わかったことと練習問題の回答を記す。
練習問題はできる限り自信の回答を記すが、うまく行かない場合、
回答を貼ることもあります。ネタバレ注意
クラス構成
Numeric << Integer(整数) << Fixnum(普通の整数), Bignum(大きな整数)
<< Float(浮動小数点数)
<< Rational(有理数)
<< Complex(複素数)
あんまりちゃんと把握できてなかったので改めて。
数え上げ
ary = [] 2.step(10, 3) do |i| ary << i end p ary #=> [2, 5, 8]
これはみたことがなかった数え上げだ。第一引数に到達するまで第二引数の増加分
を配列にしていく。2から始まって、3飛んだ、5とさらに3飛んだ8が配列として入る。
練習問題
摂氏を華氏にするメソッドを定義する
def cels2fahr # メソッド名は摂氏を華氏にというのをかっこよく定義 s = gets.to_i # 受け取る値を整数に変更 k = s * 9 / 5 + 32 # 摂氏から華氏を求める公式らしい p k #出力 end cels2fahr
これでいける。ということで実行してみるとなんとエラーが出ました。
dynamic constant assignment ??? 調べてみるとどうやら、メソッド内で変数であるsを定義していることが気にくわないらしい。だったら外にだす。
s = gets.to_i # 受け取る値を整数に変更 def cels2fahr # メソッド名は摂氏を華氏にというのをかっこよく定義 k = s * 9 / 5 + 32 # 摂氏から華氏を求める公式らしい p k #出力 end cels2fahr
これでいける。またまたエラー
undefined local variable or method `s' for main:Object ???
sがメソッドで受け取れないよ。という意味っぽい。よって
s = gets.to_i # 受け取る値を整数に変更 def cels2fahr(s) # メソッド名は摂氏を華氏にというのをかっこよく定義 k = s * 9 / 5 + 32 # 摂氏から華氏を求める公式らしい p k #出力 end cels2fahr(s)
メソッドの引数として受け取らせると通った。
多分これが回答。初歩の初歩で2回もつまずいた。
またそもそも回答によると、公式に当てはめるさいにIntegerをfloatに直しておく必要があるらしい。(数字の取り扱いを9.0、5.0、32.0にする必要がある。)
華氏を摂氏にするメソッドを定義するまた1度から100度に対応した華氏を表示する
華氏を摂氏にするのはさっきの公式を逆にしただけをメソッド定義にするだけだから割愛する。多分あってるだろう。後半のプログラムを書く。
def cels2fahr(i) #メソッド定義する k = i * 9 / 5 + 32 p "摂氏#{i}度は華氏#{k}度です" #わかりやすいようにpする文言をかく end for i in 1..100 do #イテレーター1から100まで上げていく cels2fahr(i) end
これで摂氏1から100まで算出された!が、回答を見ると
1.upto(100) do |i|
で数え上げていた。こちらが正答らしい。
サイコロの出目を返すメソッドを定義する
def dice p rand(1..6) end dice #=>実行するたびに1から6が出現する
これは楽しいRuby内に記述されたやり方とは違うやり方で書いた。
実際にはrand(6)とすると0から5までの乱数が返るので、rand(6) + 1をして、
1から6を返すようにするらしい。
10個のサイコロを降って出た目の合計を返すメソッドを定義する
def dice10 s = 0 # サイコロを降っていない状態の変数を定義 1.upto(10) do |i| #1回から10回までサイコロを降る s += rand(1..6) #sに結果を足していく end p s #足した結果を出力する end dice10 #=> rand(1..6)を10回やった結果がでる。
まぁまぁ書けているはずだが、答えはどうだ。先の回答で定義したメソッドを使って、回答を書いている。rand(1..6)の記述のところをdiceメソッドを使っている。
整数が素数かどうかを調べるメソッドを定義する
まず素数ってなんぞや。問題文によると「1とそれ以外で割れない数
で1桁の整数の場合素数は、2,3,5,7らしい。
num = gets.to_i #数字を受け取る def prime?(num) if num == 2 || num == 3 #2,3は素数だから puts "素数" elsif num == 1 #1は下の素数の条件に当てはまるが素数じゃないから例外的に puts "素数じゃない" elsif num % 1 == 0 && num % num == 0 && num % 2 != 0 && num % 3 != 0 #1で割り切れて、それ地震で割り切れて、2と3で割れないのが素数? puts "素数" else puts "素数じゃない" #それ以外は素数じゃない。 end end prime?(num) #=> 実際に出力する
相当スマートではないメソッドが定義できた。これは回答とはほど遠いだろう。
これはプログラミングの問題というより、素数を定義する問題っぽい。
素数を簡単に調べるためには1とその数以外で割ってみて割り切れる数があるかないかを調べるが、100以上まで桁数が上がるとしんどい。よって、その数の平方根までの値で割り切れるかを確認するらしい。例えば、103が素数かどうかは平方根である10までの全ての数で割り切れるかの確認をする。よって、プログラミングは、
def prime?(num) if num < 2 # 2と1は素数ではないからfalseを返す return false end 2.upto(Math.sqrt(num)) do |i| #2からその数の平方根までで、 if num % i == 0 #その数を割る割り切れたらfalse return false else return trues #2からその数の平方根までで割り切れなかったら、素数 end end end if prime?(5) puts "素数" end
なるほど、プログラミングの前に素数ってどうやって証明しますか?というのがわかっていないと解けない。