狠狠撸

狠狠撸Share a Scribd company logo
新しくプログラミング言語を覚えたいときに
行うべき 10 の練習問題 を Ruby でやってみた



          うえっち (@uh_tomo )
自己紹介

● 名前 : 上田智昭 ( 通称 うえっち )

● 工学部 情報系 3 年
● 今回の LT 会の企画者
元ネタ

新しくプログラミング言語を覚えたいときに
行うべき 10 の練習問題

http://www.ideaxidea.com/archives/2008/02/10_7.html




                  ※ ちょっと変えたものを解きました
課題 01
● FizzBuzz 問題を解け


FizzBuzz 問題を知らない人 いますか?
※ FizzBuzz 問題 とは?

1 から順に数字を出力していく

ただし、
3 で割切れる場合は Fizz
5 で割切れる場合は Buzz
両方で割切れる場合は FizzBuzz を数字の代わりに表示

例:
1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14
FizzBuzz 16 ...
課題 01
● FizzBuzz 問題を解け
コード例 :
1 (1..100).each do |t|
2   str = ""
3   str += "Fizz" if t % 3 == 0   #   3 で割切れる場合
4   str += "Buzz" if t % 5 == 0   #   5 で割切れる場合
5   str = t.to_s if str == ""     #   3 でも 5 でも割り切れない場合
6   puts str                      #   出力
7 end

解説 :
(1..100).each do |t| ~ end は、 for 構文みたいな感じ
反復変数 t に 1 から 100 までの数値を代入しながら、繰り返す

2-5 行目では、 t を判定し、出力する文字列を決定する
6 行目で文字列を出力する
課題 01
   ● FizzBuzz 問題を解け
   ※ おまけ
   ○ ワンライナー編
(1..100).each{|t| puts t%15==0 ? "FizzBuzz" : t%3==0 ? "Fizz" : t%5==0 ? "Buzz": t }


  ○ Ruby での最短 (56 文字 )
   1.upto(?d){|i|i%3<1&&x=:Fizz;puts i%5<1?"#{x}Buzz":x||i}

     d の ASCII コード


                                  短絡評価?最小評価
課題 02
● 現在時刻に合わせて、やる気のでる文字列を表示
課題 02
● 現在時刻に合わせて、やる気のでる文字列を表示

◎ 方針 :
Time.now を使って、現在時刻を取得
適当に条件分岐させて、メッセージを表示させる


この問題は、時刻を利用することが目的
課題 02
● 現在時刻に合わせて、やる気のでる文字列を表示
コード例 :
 1 case Time.now.hour
 2 when 6..9
 3   puts " おはようございます。良い朝ですね "
    …
19 when 23..5
20   puts " そろそろ寝る時間だよー "
21 end

解説 :
case 式 when 値 ~ end は、 switch 構文みたいな感じ
式 == 値の場合、実行する ( break とか必要なし )
課題 03
● 数値を複数入力後、昇順に並び替える。
  それらの最大値と最小値を出力する。
課題 03
● 数値を複数入力後、昇順に並び替える。
  それらの最大値と最小値を出力する。

◎ 方針 :
1. 不定個数の入力を受け取り、配列に格納
2. 配列を昇順に並び替え、出力
3. 最大値と最小値も出力

この問題は、配列操作が目的
課題 03
● 数値を複数入力後、昇順に並び替える。
  それらの最大値と最小値を出力する。
コード例 :
 1   arr = Array.new                  # 入力を格納する配列を定義
 2   catch(:exit) {
 3     loop do                        # 無限ループ
 4       STDIN.gets()                 # 1 行の標準入力
 5       $_.split(" ").each do |t|    # 入力を < 空白スペース > で分ける
 6         throw :exit if t == "00"   # 00 が入力された場合は、入力終了
 7         arr << t.to_i              # 数値に変換して配列に格納
 8       end
 9     end
10   }
11   p arr.sort!                             # 配列をソートし出力
12   puts "max: #{arr.max}nmin: #{arr.min}" # 最大値と最小値を出力

解説 :
コメントのとおり
課題 04
● 簡易電卓の作成 (0 除算の場合を作り込む )
課題 04
● 簡易電卓の作成 (0 除算の場合を作り込む )
◎ 方針 :
1.[ 数字 演算子 数字 ] のような入力を受け取る
2. 0 除算の判定と処理
3. 計算結果の出力

この問題は、条件分岐が目的?
課題 04
● 簡易電卓の作成 (0 除算の場合を作り込む )
コード例 :
 1   STDIN.gets           # 標準入力
 2   tmp = $_.split(" ") # 入力を < 半角スペース > で分け、配列化
 3   # 不正な入力を防ぐ
 4   unless tmp[0] =~ /^d+$/ and tmp[1] =~ /^[+-*/]$/ and tmp[2] =~ /^d+$/
 5     puts "Num Ope Num の形で入力してください "
 6   end
 7   # 0 除算を防ぐ
 8   if tmp[1] == "/" and tmp[2].to_i == 0
 9     puts "0 除算とか迷惑です "
10   end
11   # 計算結果を出力
12   puts eval(tmp[0]+tmp[1]+tmp[2])    # できればいいんです

解説 :
1,2 行目で、入力を受取り、数字と演算子に分ける
4-6 行目で、不正入力の判定
8-10 行目で、 0 除算判定
12 行目で、計算し、結果表示
課題 05
● キーワードを入力して、 Yahoo の検索結果を表示
課題 05
● キーワードを入力して、 Yahoo の検索結果を表示
◎ 方針 :
1. キーワード入力
2. Yahoo で検索 (XML が返ってくる )
3. XML から必要なものを取り出し、出力

この問題は、 API の使用、 HTTP 通信、 XML 処理 が目的
課題 05
 ● キーワードを入力して、 Yahoo の検索結果を表示
 コード例 ( 通信部 ):
 1   uri     = "http://search.yahooapis.jp/WebSearchService/V2/webSearch"
 2   appid   = "iYknF3yxg67vgAWX01ygpiCbcdCpiBJCQx6G8j.OtP289nVkQDLBmMR.aTT7rLDDg4y0"
 3   results = "5"
 4   search_result = ""
 5
 6   puts " 検索ワードを入力してください "
 7   STDIN.gets()
 8   url = "#{uri}?appid=#{appid}&query=#{URI.escape($_.chomp)}&results=#{results}"
 9
10   loop do                               # 無限ループ
11     begin                               # 例外処理
12       search_result = open(url).read    # 検索結果の受け取り
13     rescue
14       next                              # エラーが発生したら、もう一回実行
15     end
16     break                               # エラーが発生しなければ、ループを抜ける
17   end

解説 :
コメントのとおり
課題 05
 ● キーワードを入力して、 Yahoo の検索結果を表示
 コード例 (XML 処理部 ):
18   count = 1                                       # カウンターの初期化
19   xml = REXML::Document.new(search_result)        # 検索結果を XML オブジェクトに
20   xml.elements.each("ResultSet/Result") do |elem| # ResultSet タグの Result タグ
21     puts "● #{count} 番目の検索結果 "                    # 検索順位を出力
22     count += 1
23     puts "Title: "+elem.elements["Title"].text    # ページのタイトルを出力
24     puts elem.elements["Summary"].text            # ページの概要を出力
25     puts                                          # 空行
26   end


解説 :
20 行目では、 XML の ResultSet タグの要素 Result タグの要素を
取り出し、反復変数 elem に代入している。
その後、 23 行目でタイトル、 24 行目で概要を出力している。
課題 06
● テキストを入力すると、語尾を変えて出力
課題 06
● テキストを入力すると、語尾を変えて出力
◎ 方針 :
1. テキスト入力
2. 語尾を置換し、出力


この問題は、正規表現と文字列置換 が目的
課題 06
● テキストを入力すると、語尾を変えて出力
コード例 :
1 STDIN.gets
2 print $_.sub(/ です $/, " でちゅわ“ )


解説 :
1 行目で入力
2 行目で置換したものを出力している

色々な組み合わせで遊べる感じ
課題 07
● メールを送る
課題 07
● メールを送る
◎ 方針 :
1. メールを送る



この問題は、メールを送ること が目的
課題 07
● メールを送る
コード例 :
 1   require 'net/smtp'
 2
 3   server_addr   =   "smtp.example.co.jp"
 4   port          =   25
 5   from_addr     =   "from@example.co.jp"
 6   to_addr       =   "to@example.co.jp"
 7   account       =   ""
 8   pass          =   ""
 9
10   message = <<EOF
11   From: queue <from@example.com>
12   To: iguiter <to@example.net>
13   Subject: Test Mail
14   Date: Sat, 23 Jan 2012 00:00:00 +0900
15
16   This is a test mail.
17   EOF
18
19   Net::SMTP.start(server_addr, port, from_addr, account, pass) do |smtp|
20     smtp.send_message(message, from_addr, to_addr)            # メール送信
21   end
課題 08
● 「 < 誰 > が < どこ > で < 何を > した」を表示する
課題 08
● 「 < 誰 > が < どこ > で < 何を > した」を表示する
◎ 方針 :
1. 各要素を配列に格納
2. 乱数を発生させ、適当に表示させる


この問題は、文字列処理と乱数 が目的
課題 08
● 「 < 誰 > が < どこ > で < 何を > した」を表示する
コード例 :
1   who   = [" たろー "," じろー "," さぶろー "," しろー "," ごろー "]
2   where = [" 家 "," 海上 "," ノート PC の上 "," うどん屋 "," 玄関 "]
3   doing = [" 踊った "," 女装した "," 寝てた "," 「えっ」 "," にゃー "]
4
5   puts who[i]+" が "+where[rand(5)]+" で "+doing[rand(5)]

解説 :
1,2,3 行目で、各要素を定義
5 行目で乱数を発生させて、出力
課題 09
● 入力された URL のはてブ数を出力
課題 09
● 入力された URL のはてブ数を出力
◎ 方針 :
1. URL 入力
2. はてブ API を利用し、結果を取得する


この問題は、 API の使用、エスケープ、 xmlrpc の利用? が目的
課題 09
● 入力された URL のはてブ数を出力
コード例 :
 1   require 'xmlrpc/client'
 2   client = XMLRPC::Client.new("b.hatena.ne.jp", "/xmlrpc")
 3
 4   puts "URL を入力してください ( 例 : http://www.google.com)"
 5   print " 検索 URL: "
 6   STDIN.gets
 7
 8   search_result = client.call("bookmark.getCount",URI.escape($_.chomp))
 9
10   print "#{$_.chomp} のはてブ数は #{search_result[$_.chomp]} です "

解説 :
 2 行目で、 API を使用する準備
 6 行目で、 URL 入力
 8 行目で、はてブ数を取得
10 行目で、結果出力
課題 10
● 2 つの名前を入力して、 10 段階の相性診断を行う
課題 10
● 2 つの名前を入力して、 10 段階の相性診断を行う
◎ 方針 :
1. 名前の入力
2. 名前の数値化
3. 適当に条件分岐

この問題は、アルゴリズム考察? と 文字列処理 が目的
課題 10
● 2 つの名前を入力して、 10 段階の相性診断を行う
コード例 :
1   print " 名前 1: "
2   name1 = STDIN.gets().chomp
3
4   arr1 = name1.unpack('U*')
5
6   sum1 = arr1.inject(0) do |sum1, i|
7     sum1 + i
8   end

解説 :
ある 1 つの文字列を数値化するコードである
2 行目で、 name1 に入力を行う
4 行目で、 name1 の各文字を UTF-8 の文字コードに変換
6 行目で、各数値の合計 sum1 を計算
課題 10
● 2 つの名前を入力して、 10 段階の相性診断を行う
コード例 :
1   match_table = [[1,2,3,4],[0,5,6,7,],[0,0,8,9],[0,0,0,10]]
2   arr = [sum1%4, sum2%4]
3
4   result = match_table[arr.min][arr.max]
5   result = 10 if sum1 == sum2
6
7   unless result == 0
8     puts " 二人の相性は #{result} です "
9   end


解説 :
10 段階に判定する必要があるため、各名前を数値化したものの
4 の除数を計算し、その組み合わせから相性判定を行う

0-0,0-1,0-2,0-3,1-1,1-2,1-3,2-2,2-3,3-3 の 10 パターン
おわり

長々と失礼しました

最後に、ちょっと宣伝を???
宣伝

Kadai.rb ハッカソン やります。
たぶん、 1,2 月あたりに???


色々と決まったら、 ATND 立てます。
ぜひ、参加してください。


                    GoogleSite のページ
                             ↓
https://sites.google.com/site/kagawarb/kadai-rb/hackathon02

More Related Content

新しくプログラミング言语???搁耻产测でやってみた

  • 2. 自己紹介 ● 名前 : 上田智昭 ( 通称 うえっち ) ● 工学部 情報系 3 年 ● 今回の LT 会の企画者
  • 4. 課題 01 ● FizzBuzz 問題を解け FizzBuzz 問題を知らない人 いますか?
  • 5. ※ FizzBuzz 問題 とは? 1 から順に数字を出力していく ただし、 3 で割切れる場合は Fizz 5 で割切れる場合は Buzz 両方で割切れる場合は FizzBuzz を数字の代わりに表示 例: 1 2 Fizz 4 Buzz Fizz 7 8 Fizz Buzz 11 Fizz 13 14 FizzBuzz 16 ...
  • 6. 課題 01 ● FizzBuzz 問題を解け コード例 : 1 (1..100).each do |t| 2 str = "" 3 str += "Fizz" if t % 3 == 0 # 3 で割切れる場合 4 str += "Buzz" if t % 5 == 0 # 5 で割切れる場合 5 str = t.to_s if str == "" # 3 でも 5 でも割り切れない場合 6 puts str # 出力 7 end 解説 : (1..100).each do |t| ~ end は、 for 構文みたいな感じ 反復変数 t に 1 から 100 までの数値を代入しながら、繰り返す 2-5 行目では、 t を判定し、出力する文字列を決定する 6 行目で文字列を出力する
  • 7. 課題 01 ● FizzBuzz 問題を解け ※ おまけ ○ ワンライナー編 (1..100).each{|t| puts t%15==0 ? "FizzBuzz" : t%3==0 ? "Fizz" : t%5==0 ? "Buzz": t } ○ Ruby での最短 (56 文字 ) 1.upto(?d){|i|i%3<1&&x=:Fizz;puts i%5<1?"#{x}Buzz":x||i} d の ASCII コード 短絡評価?最小評価
  • 9. 課題 02 ● 現在時刻に合わせて、やる気のでる文字列を表示 ◎ 方針 : Time.now を使って、現在時刻を取得 適当に条件分岐させて、メッセージを表示させる この問題は、時刻を利用することが目的
  • 10. 課題 02 ● 現在時刻に合わせて、やる気のでる文字列を表示 コード例 : 1 case Time.now.hour 2 when 6..9 3 puts " おはようございます。良い朝ですね " … 19 when 23..5 20 puts " そろそろ寝る時間だよー " 21 end 解説 : case 式 when 値 ~ end は、 switch 構文みたいな感じ 式 == 値の場合、実行する ( break とか必要なし )
  • 11. 課題 03 ● 数値を複数入力後、昇順に並び替える。 それらの最大値と最小値を出力する。
  • 12. 課題 03 ● 数値を複数入力後、昇順に並び替える。 それらの最大値と最小値を出力する。 ◎ 方針 : 1. 不定個数の入力を受け取り、配列に格納 2. 配列を昇順に並び替え、出力 3. 最大値と最小値も出力 この問題は、配列操作が目的
  • 13. 課題 03 ● 数値を複数入力後、昇順に並び替える。 それらの最大値と最小値を出力する。 コード例 : 1 arr = Array.new # 入力を格納する配列を定義 2 catch(:exit) { 3 loop do # 無限ループ 4 STDIN.gets() # 1 行の標準入力 5 $_.split(" ").each do |t| # 入力を < 空白スペース > で分ける 6 throw :exit if t == "00" # 00 が入力された場合は、入力終了 7 arr << t.to_i # 数値に変換して配列に格納 8 end 9 end 10 } 11 p arr.sort! # 配列をソートし出力 12 puts "max: #{arr.max}nmin: #{arr.min}" # 最大値と最小値を出力 解説 : コメントのとおり
  • 14. 課題 04 ● 簡易電卓の作成 (0 除算の場合を作り込む )
  • 15. 課題 04 ● 簡易電卓の作成 (0 除算の場合を作り込む ) ◎ 方針 : 1.[ 数字 演算子 数字 ] のような入力を受け取る 2. 0 除算の判定と処理 3. 計算結果の出力 この問題は、条件分岐が目的?
  • 16. 課題 04 ● 簡易電卓の作成 (0 除算の場合を作り込む ) コード例 : 1 STDIN.gets # 標準入力 2 tmp = $_.split(" ") # 入力を < 半角スペース > で分け、配列化 3 # 不正な入力を防ぐ 4 unless tmp[0] =~ /^d+$/ and tmp[1] =~ /^[+-*/]$/ and tmp[2] =~ /^d+$/ 5 puts "Num Ope Num の形で入力してください " 6 end 7 # 0 除算を防ぐ 8 if tmp[1] == "/" and tmp[2].to_i == 0 9 puts "0 除算とか迷惑です " 10 end 11 # 計算結果を出力 12 puts eval(tmp[0]+tmp[1]+tmp[2]) # できればいいんです 解説 : 1,2 行目で、入力を受取り、数字と演算子に分ける 4-6 行目で、不正入力の判定 8-10 行目で、 0 除算判定 12 行目で、計算し、結果表示
  • 17. 課題 05 ● キーワードを入力して、 Yahoo の検索結果を表示
  • 18. 課題 05 ● キーワードを入力して、 Yahoo の検索結果を表示 ◎ 方針 : 1. キーワード入力 2. Yahoo で検索 (XML が返ってくる ) 3. XML から必要なものを取り出し、出力 この問題は、 API の使用、 HTTP 通信、 XML 処理 が目的
  • 19. 課題 05 ● キーワードを入力して、 Yahoo の検索結果を表示 コード例 ( 通信部 ): 1 uri = "http://search.yahooapis.jp/WebSearchService/V2/webSearch" 2 appid = "iYknF3yxg67vgAWX01ygpiCbcdCpiBJCQx6G8j.OtP289nVkQDLBmMR.aTT7rLDDg4y0" 3 results = "5" 4 search_result = "" 5 6 puts " 検索ワードを入力してください " 7 STDIN.gets() 8 url = "#{uri}?appid=#{appid}&query=#{URI.escape($_.chomp)}&results=#{results}" 9 10 loop do # 無限ループ 11 begin # 例外処理 12 search_result = open(url).read # 検索結果の受け取り 13 rescue 14 next # エラーが発生したら、もう一回実行 15 end 16 break # エラーが発生しなければ、ループを抜ける 17 end 解説 : コメントのとおり
  • 20. 課題 05 ● キーワードを入力して、 Yahoo の検索結果を表示 コード例 (XML 処理部 ): 18 count = 1 # カウンターの初期化 19 xml = REXML::Document.new(search_result) # 検索結果を XML オブジェクトに 20 xml.elements.each("ResultSet/Result") do |elem| # ResultSet タグの Result タグ 21 puts "● #{count} 番目の検索結果 " # 検索順位を出力 22 count += 1 23 puts "Title: "+elem.elements["Title"].text # ページのタイトルを出力 24 puts elem.elements["Summary"].text # ページの概要を出力 25 puts # 空行 26 end 解説 : 20 行目では、 XML の ResultSet タグの要素 Result タグの要素を 取り出し、反復変数 elem に代入している。 その後、 23 行目でタイトル、 24 行目で概要を出力している。
  • 22. 課題 06 ● テキストを入力すると、語尾を変えて出力 ◎ 方針 : 1. テキスト入力 2. 語尾を置換し、出力 この問題は、正規表現と文字列置換 が目的
  • 23. 課題 06 ● テキストを入力すると、語尾を変えて出力 コード例 : 1 STDIN.gets 2 print $_.sub(/ です $/, " でちゅわ“ ) 解説 : 1 行目で入力 2 行目で置換したものを出力している 色々な組み合わせで遊べる感じ
  • 25. 課題 07 ● メールを送る ◎ 方針 : 1. メールを送る この問題は、メールを送ること が目的
  • 26. 課題 07 ● メールを送る コード例 : 1 require 'net/smtp' 2 3 server_addr = "smtp.example.co.jp" 4 port = 25 5 from_addr = "from@example.co.jp" 6 to_addr = "to@example.co.jp" 7 account = "" 8 pass = "" 9 10 message = <<EOF 11 From: queue <from@example.com> 12 To: iguiter <to@example.net> 13 Subject: Test Mail 14 Date: Sat, 23 Jan 2012 00:00:00 +0900 15 16 This is a test mail. 17 EOF 18 19 Net::SMTP.start(server_addr, port, from_addr, account, pass) do |smtp| 20 smtp.send_message(message, from_addr, to_addr) # メール送信 21 end
  • 27. 課題 08 ● 「 < 誰 > が < どこ > で < 何を > した」を表示する
  • 28. 課題 08 ● 「 < 誰 > が < どこ > で < 何を > した」を表示する ◎ 方針 : 1. 各要素を配列に格納 2. 乱数を発生させ、適当に表示させる この問題は、文字列処理と乱数 が目的
  • 29. 課題 08 ● 「 < 誰 > が < どこ > で < 何を > した」を表示する コード例 : 1 who = [" たろー "," じろー "," さぶろー "," しろー "," ごろー "] 2 where = [" 家 "," 海上 "," ノート PC の上 "," うどん屋 "," 玄関 "] 3 doing = [" 踊った "," 女装した "," 寝てた "," 「えっ」 "," にゃー "] 4 5 puts who[i]+" が "+where[rand(5)]+" で "+doing[rand(5)] 解説 : 1,2,3 行目で、各要素を定義 5 行目で乱数を発生させて、出力
  • 30. 課題 09 ● 入力された URL のはてブ数を出力
  • 31. 課題 09 ● 入力された URL のはてブ数を出力 ◎ 方針 : 1. URL 入力 2. はてブ API を利用し、結果を取得する この問題は、 API の使用、エスケープ、 xmlrpc の利用? が目的
  • 32. 課題 09 ● 入力された URL のはてブ数を出力 コード例 : 1 require 'xmlrpc/client' 2 client = XMLRPC::Client.new("b.hatena.ne.jp", "/xmlrpc") 3 4 puts "URL を入力してください ( 例 : http://www.google.com)" 5 print " 検索 URL: " 6 STDIN.gets 7 8 search_result = client.call("bookmark.getCount",URI.escape($_.chomp)) 9 10 print "#{$_.chomp} のはてブ数は #{search_result[$_.chomp]} です " 解説 : 2 行目で、 API を使用する準備 6 行目で、 URL 入力 8 行目で、はてブ数を取得 10 行目で、結果出力
  • 33. 課題 10 ● 2 つの名前を入力して、 10 段階の相性診断を行う
  • 34. 課題 10 ● 2 つの名前を入力して、 10 段階の相性診断を行う ◎ 方針 : 1. 名前の入力 2. 名前の数値化 3. 適当に条件分岐 この問題は、アルゴリズム考察? と 文字列処理 が目的
  • 35. 課題 10 ● 2 つの名前を入力して、 10 段階の相性診断を行う コード例 : 1 print " 名前 1: " 2 name1 = STDIN.gets().chomp 3 4 arr1 = name1.unpack('U*') 5 6 sum1 = arr1.inject(0) do |sum1, i| 7 sum1 + i 8 end 解説 : ある 1 つの文字列を数値化するコードである 2 行目で、 name1 に入力を行う 4 行目で、 name1 の各文字を UTF-8 の文字コードに変換 6 行目で、各数値の合計 sum1 を計算
  • 36. 課題 10 ● 2 つの名前を入力して、 10 段階の相性診断を行う コード例 : 1 match_table = [[1,2,3,4],[0,5,6,7,],[0,0,8,9],[0,0,0,10]] 2 arr = [sum1%4, sum2%4] 3 4 result = match_table[arr.min][arr.max] 5 result = 10 if sum1 == sum2 6 7 unless result == 0 8 puts " 二人の相性は #{result} です " 9 end 解説 : 10 段階に判定する必要があるため、各名前を数値化したものの 4 の除数を計算し、その組み合わせから相性判定を行う 0-0,0-1,0-2,0-3,1-1,1-2,1-3,2-2,2-3,3-3 の 10 パターン
  • 38. 宣伝 Kadai.rb ハッカソン やります。 たぶん、 1,2 月あたりに??? 色々と決まったら、 ATND 立てます。 ぜひ、参加してください。 GoogleSite のページ ↓ https://sites.google.com/site/kagawarb/kadai-rb/hackathon02