第 5 回 何度も呼び出そう レポート課題 吉住 貴則 C1101980 英語 2 地域共創コース 1A、 私の名前をアルファベットで表すと YOSHIZUMI TAKANORI <16進数の場合> 0x79 … Y 0x6f … O 0x73 … S 0x68 … H 0x69 … I 0x7a … Z 0x75 … U 0x6d … M 0x69 … I 0x74 … T 0x61 … A 0x6b … K 0x61 … A 0x6e … N 0x6f … O 0x72 … R 0x69 … I <10進数に変換> (Y)0x79 = 121 16*7 = 112 1*9 = 9 112+9 = 121 (O)0x6f = 111 16*6 = 96 1*f(15) = 15 96+15 = 111 (S)0x73 = 115 16*7 = 112 1*3 = 3 112+3 =115 (H)0x68 = 104 16*6 = 96 1*8 = 8 96+8 = 104 (I)0x69 = 105 16*6 = 96 1*9 = 9 96+9 = 105 (Z)0x7a = 122 16*7 = 112 1*10 = 10 112+10 = 122 (U)0x75 = 117 16*7 = 112 1*5 = 5 112+5 = 117 (M)0x6d = 109 16*6 = 96 1*d(13) = 13 96+13 = 109 (I)0x69 = 105 16*6 = 96 1*9 = 9 96+9 = 105 (T)0x74 = 116 16*7 = 112 1*4 = 4 112+4 = 116 (A)0x61 = 97 16*6 = 96 1*1 = 1 96+1 = 97 (K)0x6b = 107 16*6 = 96 1*b(11) = 11 96+11 = 107 (A)0x61 = 97 16*6 = 96 1*1 = 1 96+1 = 97 (N)0x6e = 110 16*6 = 96 1*e(14) = 14 96+14 = 110 (O)0x6f = 111 16*6 = 96 1*f(15) = 15 96+15 = 111 (R)0x72 = 114 16*7 = 112 1*2 = 2 112+2 = 114 (I)0x69 = 105 16*6 = 96 1*9 = 9 96+9 = 105 <10進数で全てを足したとき> (Y)0x79 = 121 (O)0x6f = 111 (S)0x73 = 115 (H)0x68 = 104 (I)0x69 = 105 (Z)0x7a = 122 (U)0x75 = 117 (M)0x6d = 109 (I)0x69 = 105 (T)0x74 = 116 (A)0x61 = 97 (K)0x6b = 107 (A)0x61 = 97 (N)0x6e = 110 (O)0x6f = 111 (R)0x72 = 114 (I)0x69 = 105 + __________________ 1866 答え 0d 1866 (A) (考察) bc -l で計算してみた。 pan{c110198}% bc -l [~] 121(y)+111(o)+115(s)+104(h)+105(i)+122(z)+117(u)+109(m)+105(i) +116(t)+97(a)+107(k)+97(a)+110(n)+111(o)+114(r)+105(i) 1866 <答えを16進数に変換する> 16 ) 1866 10 … a ________ 16 ) 116 4 ________ 16 ) 7 7 ________ 0 * 変換した答えはしたから読んで 行かなければいけない 答え 0x 74a (B) (考察) 0x 74a を10進数に変換してみる。 16**2 16**1 16**0 __________________________ 256 16 1 ____*________*________*___ 7 4 a(10) __________________________ 1792 64 10 ========================== 1792 + 64 + 10 = 1866 答え 0d 1866 (C) bc -l で計算した結果 pan{c110198}% bc -l 256*7 1792 … 16の2乗に16進数の1桁目をかけた結果 16*4 64 … 16の1乗に16進数の2桁目をかけた結果 1*10 10 … 16の0乗に16進数の3桁目をかけた結果 1792+64+10 1866 … 合計 <結果> 以上の16進数を10進数に変換して答えを出した結果 (A) 0d 1866 10進数を16で割り、出した結果 (B) 0x 74a その出した答えを10進数に変換した結果 (C) 0d 1866 (A) 0d 1866 = (B) 0x 74a {(C) 0d 1866} となり、 どちらも一致していることになる。 (考察) 問題には、10、16進数だけで答えよと書かれていたが、 心配になったので2進数で計算してみた。 <2進数に変換> 0x79 … Y = 01111001 7 = 0111 、 9 = 1001 0x6f … O = 01101111 6 = 0110 、 f = 1111 0x73 … S = 01110011 7 = 0111 、 3 = 0011 0x68 … H = 01101000 6 = 0110 、 8 = 1000 0x69 … I = 01101001 6 = 0110 、 9 = 1001 0x7a … Z = 01111010 7 = 0111 、 a = 1010 0x75 … U = 01110101 7 = 0111 、 5 = 0101 0x6d … M = 01101101 6 = 0110 、 d = 1101 0x69 … I = 01101001 6 = 0110 、 9 = 1001 0x74 … T = 01110100 7 = 0111 、 4 = 0100 0x61 … A = 01100001 6 = 0110 、 1 = 0001 0x6b … K = 01101011 6 = 0110 、 b = 1011 0x61 … A = 01100001 6 = 0110 、 1 = 0001 0x6e … N = 01101110 6 = 0110 、 e = 1110 0x6f … O = 01101111 6 = 0110 、 f = 1111 0x72 … R = 01110010 7 = 0111 、 2 = 0010 0x69 … I = 01101001 6 = 0110 、 9 = 1001 <それぞれたして行く> 2進数の足し算は筆算で解くことができる (1) 0001 (3)+ 0011 … 1桁目に(1) が 1 、(3) が 1で ________ 足すと 2になる。2進数では 0100 2 になると繰り上がりをしなければ 行けないので、次の桁に 1 を足し それを覚えると10進数の計算と同じだ。 0x79 … Y = 01111001 0x6f … O = 01101111 ______________________ 11101000 0x73 … S = 01110011 0x68 … H = 01101000 ______________________ 11011011 0x69 … I = 01101001 0x7a … Z = 01111010 ______________________ 11100011 0x75 … U = 01110101 0x6d … M = 01101101 ______________________ 11100010 0x69 … I = 01101001 0x74 … T = 01110100 ______________________ 11011101 0x61 … A = 01100001 0x6b … K = 01101011 ______________________ 11001100 0x61 … A = 01100001 0x6e … N = 01101110 ______________________ 11001111 0x6f … O = 01101111 0x72 … R = 01110010 0x69 … I = 01101001 ______________________ 101001010 これらを全て足すと 11101001010 という結果が出た。 そしてこれを1桁目から4つずつ区切って行く 0111 / 0100 / 1010 となる。 この4つに区切った数字を表で合わせる。 <2進数> <16進数> ============================= 1 | 1 10 | 2 11 | 3 100 | 4 101 | 5 110 | 6 111 | 7 1000 | 8 1001 | 9 1010 | a 1011 | b 1100 | c . | . . | . . | . ============================= 0111 : 7 0100 : 4 1010 : a これを<結果>で表した(B)と合わせると (B) 0x 74a = 0x 74a : 今の結果 答えが合致した。 これにより今までに至る計算、答えは 全て正しいと言える。 1B、 <考えた設定> 毎朝学校へ行くときやどこかに必ず出掛ける時に 行うことを書きます。 def go(butudan,watch,aisatu) # go : 出掛けると言う意味で # butudan : 仏壇,watch : 時計,aisatu : 挨拶) butudan を拝む watch を身に付ける aisatu を家族にする me = butudan me = watch me = aisatu end # defにかかわるend。 me を関数に 返す。 let'sgo(1分,10秒,30秒) # 出掛けるときの習慣を呼び出す print("かあ、いってくっぞ") 2A、 1) 設定 私はよくカラオケ大会に出場することが多いのだが、 そこに出場するメンバーの中から何通りという選び方のうち 何人選ばれるのかが知りたくて作成することにした。 2) 作成したプログラム #!/usr/koeki/bin/ruby # ruby のお決まり # 1つ目 ここで基本になる定義を示す def karaoke(e) # 関数: karaoke 、仮引数:entry(出場者)の e とした。 if e == 1 # もし、e が 1であるとき ( == : イコール ) 1 # 1(数字)を返し、表示。 else # e == 1 の時以外の場合。 e * karaoke(e-1) # e に e より1少ないものをかける。 # これによって求められる数字が1になるまで # 求めよと言う意味になる。 end # if に対する end end # def に対する end # ここで1つ目の定義は終わり。 # 2つ目 ここには具体的な定義を書く def taikai(entry,prize) # 関数: taikai … 大会 、仮引数: entry … 出場者 # prize … 受賞 if entry == prize # もし、entry の人数と prize の人数 が同じとき 1 # 1(数字)を返し、表示。 else # 、entry の人数と prize の人数 が同じ時以外の場合。 karaoke(entry)/(karaoke(prize)*karaoke(entry-prize)) # 1つ目の定義に入力された数字を、nCr の数式に当てはめ計算する。 # n! # 例 : nCr = -------- # r!(n-r)! # n = entry が r = prize が 当てはまる end # if に対する end end # def に対する end # ここで2つ目の定義は終わり。 STDERR.print("出場者は何人いらっしゃいますか?\n") # STDERR.print … ディスプレイへ入力したものを表示する # また、文字列での入力を促す people = gets.to_i # people を整数に変換 STDERR.print("受賞者は何人いらっしゃいますか?\n") winner = gets.to_i # winner を整数に変換 if people < winner # winner の数が people の数より多いとき。 print("すみません。これでは計算が出来ません。正しい値を入力して下さい。") # エラーと言うことを表示 else # people の数が winner の数より多いとき。 printf("出場者: %d人 から 受賞者: %d人 を選ぶ組み合わせは : %d通りです。 \n", people,winner,taikai(people,winner)) # taikai(people,winner): taikai で作った定義に入力されたものを # 当てはめて計算している end # if に対する end 3) もとにしたプログラム 西村先生の講義ページの第5回目の階乗計算のところの 標題を参考に作成した。 もうすっかり、高校のときの数学を忘れていたため、 高校のときに使っていた、白チャートや教科書を 引っ張りだして組合せを見つけ出しました。 この部分では、やはり組合せの部分が一番難しかったです。 4) 実行結果 A、<エラーのとき> pan{c110198}% ./def_combination.rb [~/Ruby] 出場者は何人いらっしゃいますか? 3 受賞者は何人いらっしゃいますか? 5 すみません。これでは計算が出来ません。正しい値を入力して下さい。 B、 pan{c110198}% ./def_combination.rb [~/Ruby] 出場者は何人いらっしゃいますか? 15 受賞者は何人いらっしゃいますか? 5 出場者: 15人、受賞者: 5人を選ぶ組み合わせは: 3003通りです。 C、 pan{c110198}% ./def_combination.rb [~/Ruby] 出場者は何人いらっしゃいますか? 5 受賞者は何人いらっしゃいますか? 3 出場者: 5人、受賞者: 3人を選ぶ組み合わせは: 10通りです。 5)考察 実行結果で出した結果を bc -l で確かめ算をしてみる。 A、 A は、出場者より受賞者の方が多いため 計算結果が出ないと言う表示がなされていたのであっている。 B、出場者: 15人、受賞者: 5人を選ぶ組み合わせは: 3003通りです。 pan{c110198}% bc -l [~/Ruby] 5*4*3*2*1 # r! の部分を計算 120 # 結果 15-5 # (n-r) の部分の計算 10 # 結果 10*9*8*7*6*5*4*3*2*1 # (n-r)! の計算 3628800 # 結果 120*3628800 # r!(n-r)! の部分の計算 435456000 # 結果 15*14*13*12*11*10*9*8*7*6*5*4*3*2*1 # n! の計算 1307674368000 # 結果 1307674368000/435456000 # n! / r!(n-r)! の計算 3003.00000000000000000000 # 結果 よって、3003という結果が出たので Bの問題は合致している言える。 C、出場者: 5人、受賞者: 3人を選ぶ組み合わせは: 10通りです。 pan{c110198}% bc -l [~/Ruby] 3*2*1 # r! の部分を計算 6 # 結果 5-2 # (n-r) の部分の計算 3 # 結果 2*1 # (n-r)! の計算 2 # 結果 6*2 # r!(n-r)! の部分の計算 12 # 結果 5*4*3*2*1 # n! の計算 120 # 結果 120/12 # n! / r!(n-r)! の計算 10.00000000000000000000 # 結果 よって、10という結果が出たので Cの問題は合致していると言える。 A、B、C 以上の結果からこのプログラムは正常と言える。 2B、 1) 設定 前回の課題を引継作成した。 前回の課題の作成中から考えていたのが、 よく買い物にいくと ○個目から割り引きだよ!とかいう 言葉をめにしたり、聞いたりしていたのですが、 それをプログラムに表すと一体どんな風になるのかなと 考え始めたのでそのまま活かしました。 2) 作成したプログラム #!/usr/koeki/bin/ruby # : Rubyのお約束 def acd(a) # : acd が関数、 a が仮引数(acd = アルバムCD) if a >= 1 # もし a (= アルバムCDの枚数) が 1 より少ない場合。 a * 3000 # a に 3000 をかけて表示 else # それ以外のとき a * 2500 # a に 2500 をかけて表示 end # if の end # : 3000、2500 は アルバムの値 end # : defの終わり def scd(s) # : scd が関数、 s が仮引数(scd = シングルCD) s * 1200 # s = シングルCD の枚数に 1200 をかけて表示 end STDERR.print("お客様はアルバムを何枚お買い求めになりますか?\n") # : ディスプレイで入力された文字を出力するメソッド album = gets.chomp.to_i # : albumを整数と認識する STDERR.print("お客様はシングルを何枚お買い求めになりますか?\n") single = gets.chomp.to_i # : singleを整数と認識する printf("シングル %s枚の\nお買い上げありがとうございます。\n",single) # %s : 整数と認識する # , のあとの1つ目の album は アルバムの所の %s に対応する # , のあとの1つ目の single は シングルの所の %s に対応する total = acd(album) + scd(single) # acd という関数に album 変数を引数 # scd という関数に single 変数を引数 printf("お買い上げの合計は %s円です。\nありがとうございました。\n",total) # ded - end の間にある定義は関数を使うことで結果をだすことが出来る。 3) もとにしたプログラム 先程も書いた通り、前回のdef_twoparam.rbを利用したのですが、 それに if 関数を付けたして CD の枚数で値段を判別するように しました。先程の問題を解いていたので、よりよく理解しながら 作成出来ました。 あと、最後の合計を出すときにちょっととまどったのですが、 何回も間違いをしたため関数の働き方が自然とわかりました。 4) 実行結果 pan{c110198}% ./two_methods.rb [~/Ruby] お客様はアルバムを何枚お買い求めになりますか? 1 お客様はシングルを何枚お買い求めになりますか? 1 シングル 1枚の お買い上げありがとうございます。 お買い上げの合計は 4200円です。 ありがとうございました。 pan{c110198}% ./two_methods.rb [~/Ruby] お客様はアルバムを何枚お買い求めになりますか? 2 お客様はシングルを何枚お買い求めになりますか? 4 シングル 4枚の お買い上げありがとうございます。 お買い上げの合計は 9800円です。 ありがとうございました。 5) 考察 実行結果のをbc -l で計算してみる。 pan{c110198}% bc -l [~/Ruby] 1*3000 # アルバムCDが1枚で 3000円のとき 3000 # 合計 1*1200 # シングルCDが1枚のとき 1200 # 合計 3000+1200 # アルバム合計 + シングル合計の計算 4200 # 合計金額 pan{c110198}% bc -l [~/Ruby] 2*2500 # アルバムCDが2枚で 2500円のとき 5000 # 合計 1200*4 # シングルCDが4枚のとき 4800 # 合計 5000+4800 # アルバム合計 + シングル合計の計算 9800 # 合計金額 これらの結果から見て、実行結果と同じ結果の値が出たため このプログラムは正常だといえる。 3、感想 私は、学校へ電車出来ていて電車での出来事を思い浮かべた。 1、電車に乗るときに扉を開けるため、ドアの近くの ボタンを押す。 2、まもなくドアが開く 3、発車時間になると一斉に開いていたドアが閉まる 4、電車から降りるとき、またボタンを押す。 5、まもなくドアが開き、帰宅 ======================================================== 本当に久し振りに組合せとかいろいろと 高校時代を振り返ることになった。 やはり、数学の知識をしっかり叩き込んでおくんだったと 今とても反省しております。 このレポートで授業の3分の1が過ぎました。 これからも作成意欲を向上心を忘れないで頑張ります。 4、参考文献 WEBサイト :西村まどか 先生 ホームページ 2011 年度 基礎プログラミング II 講義ノート(シラバス) 第 5 回 「何度も呼び出そう」 (http://roy/~madoka/2011/r2/05/) ノート類 :自分のノートやプログラムのコメント覧 :高校時代の数学の直筆ノート 5、添付