「プログラミング入門 - Rubyを使って -」の練習問題をやってみる
id:heydaysさんのエントリを見て興味がでたので自分もやってみる。
方針:
- チュートリアルの進度とか無視して全力でやってみる
- 変態的な方法も試してみる
- へたれなので原文でなく邦訳を見る
0-6章の練習問題
以下うるう年とか知らない。
Q. 1年は何時間でしょうか?
p 1 * 365 * 24 #=> 8760
Q. 10年間は何分でしょうか?
p 10 * 365 * 24 * 60 #=> 5256000
Q. あなたが生まれてから今日まで何秒たっているでしょうか?
x = 20 #仮 p x * 365 * 24 * 60 * 60 #=> 630720000
Q. あなたは一生のうちいくつのチョコレートを食べたいですか?
注:この計算には多少時間がかかるかもしれません。
Thread.start{ self.how_many_want :chocolate }
Q. 私が生まれてから10億200万秒 たっているとしたら、私は今何歳でしょう?
sec = Integer("1,002,000,000".gsub(/,/, "")) p sec / 60 / 60 / 24 / 365 #=> 31
Q. 最初に姓、次に名前を聞いて、最後にフルネームに対してあいさつをするようなプログラムを書いてみましょう。
def question(subject) puts "あなたの #{subject} は? " gets.strip end name = question("氏名") family = question("姓名") puts "こんにちは, #{name} #{family} !"
Q. 好きな数を入力してもらい、それに1を加えて、その結果を ベターな数字として薦めるプログラムを書きましょう。 (機転の利いたサジェスチョンに努めましょう。)
puts "お好きな数字は? " puts "#{Integer(gets).succ} もいかがですか?"
Q.「怒ったボス」のプログラムを書いてみましょう。 まず、無作法に何が望みか聞いてきます。 で、何を答えようと「怒ったボス」はそれを叫び返して、あなたを首にします。たとえば、もし給料上げてくださいとタイプしたとすると なにぃ? "給料上げてください" だとー!! おまえは首だ!! と、叫び返してきます。
puts "気に食わない目つきをしやがって。お前、何が望みだ?" wish = gets.strip puts "なにぃ? \"#{wish}\" だとー!! おまえは首だ!!" puts puts " ま さ に 外 道"
Q. center, ljust, そして rjust を使ってもう少し何かやってみましょう。こんな感じの「目次」を表示する プログラムを書いてみてください。
目 次 1章: 数 p. 1 2章: 文字 p. 72 3章: 変数 p. 118
def item(nsection, title, page) left = "#{nsection}章: #{title}".ljust(34) right = "p. #{page}".rjust(8) "#{left} #{right}" end puts "目 次".center(44) puts puts item(1, "数", 1) puts item(2, "文字", 72) puts item(3, "変数", 118)
Q. "99本のビールが壁に..." 遠足などでよく歌われる古典的な童謡の歌詞、"99 Bottles of Beer on the Wall" を 出力するプログラムを書いてみましょう。
def beer(n) <<EOS #{n} Bottles of beer on the wall #{n} Bottles of beer Take one down and pass it around #{n - 1} Bottles of beer on the wall EOS end puts (1..99).map{|x| beer x }.reverse.join("\n")
Q. 耳の遠いおばあちゃんのプログラムを書いてみましょう。 おばあちゃんに何を言っても(何をタイプしても)、叫ばない限り (つまり、全部大文字でタイプしない限り)、 は?! もっと大きな声で話しておくれ、坊や! と返事をします。もし叫んだときは、彼女はあなたの言葉を聞いて (少なくとも聞いた気がして)、 いやー、1938年以来ないねー! と大声で返事をします。 プログラムにちょっと真実味 を持たせるため、 1930年から1950年のランダムな数字で毎回違う年を叫ぶようにしましょう。 (この部分はオプションです。メソッドの 章で、Rubyの乱数発生法の節を読んでいたら簡単でしょう。) あなたはBYEと叫ぶまでおばあちゃんとの会話から逃れられません。
loop do print "呼びかけ >" puts case gets.strip when "BYE" then exit when /\A[A-Z]+\Z/ then "いやー、19#{rand(21) + 30}年以来ないねー!" else "は?! もっと大きな声で話しておくれ、坊や!" end end
Q. 上で作った、「耳の遠いおばあちゃんのプログラム」を拡張しましょう。 おばあちゃんはあなたに行って欲しくないのです。 あなたがBYEと叫んでもおばあちゃんは聞こえないふりをします。 BYEを3回連続で 叫ばないといけないように変更してみてください。
def counting_bye(n) raise ArgumentError if n < 0 cnt = 0 loop do nobye = catch(:bye) do yield true end nobye ? cnt = 0 : cnt += 1 break if cnt == n end end def say_bye throw :bye, false end counting_bye(3) do print "呼びかけ >" case gets.strip when "BYE" then say_bye when /\A[A-Z]+\Z/ then puts "いやー、19#{rand(21) + 30}年以来ないねー!" else puts "は?! もっと大きな声で話しておくれ、坊や!" end end
ここでうるう年のことを思い出す。
Q. うるう年。 開始の年と終わりの年を聞いて、その間にあるすべてのうるう年を (もし開始や終了の年がうるう年だったらそれも含めて)表示するプログラムを書きましょう。 うるう年は(1984年とか2004年のように)4で割り切れる数の年です。ただし、100で割り切れる年は うるう年ではなくて (たとえば1800年や1900年)、さらに、それは 400で割り切れない限り です。(つまり、1600年や2000年はうるう年です。)
# うるう年診断チャート chart = { # 4 で割り切れるか? true => { # 100 で割り切れるか? true => { # 400 で割り切れるか? true => true, false => false }, false => Hash.new(true) #4で割り切れて100で割り切れないから後はとにかく真 }, false => Hash.new(Hash.new(false)) #4で割り切れないから後はとにかく偽 } def chart.check(year) x, y, z = [4, 100, 400].map{|d| (year % d).zero? } self[x][y][z] end fst, last = ["開始の年 ? ", "終わりの年 ? "].map{|prompt| print prompt Integer(gets.strip) } fst.upto(last) do |y| puts y if chart.check(y) end