30代でジョブチェンジ

30代中盤、社会人経験約10年の男性です。転職をしてすぐに退職勧奨を受けて無職をしながらIT関連の学習をしていました。現在は業界で就労中です。

楽しい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

なるほど、プログラミングの前に素数ってどうやって証明しますか?というのがわかっていないと解けない。