新しくプログラミング言語を覚えたいときに行うべき10の練習問題をRubyで
出来たのから投稿していく
1:なんらかのカウントアップメッセージを1から100まで出すけど、3のときだけアホになる!(例:1万円!2万円!しゃ〜ん万円!とか)
一つ目
loop{puts '俺って天才!'}
二つ目
(1..100).each do |i| if i == 3 print 'しゃ〜ん' else print i.to_s end puts '万円!' end
無限ループが危険って何が危険なんだろう。よく分からない。
2:現在時刻にあわせてやる気のでるメッセージを出力(例:もうすぐランチ!がんばれ!)。
一つ目
messages = [ "0時台だよ!頑張れ!", "1時台だよ!頑張れ!", "2時台だよ!頑張れ!", "3時台だよ!頑張れ!", "4時台だよ!頑張れ!", "5時台だよ!頑張れ!", "6時台だよ!頑張れ!", "7時台だよ!頑張れ!", "8時台だよ!頑張れ!", "9時台だよ!頑張れ!", "10時台だよ!頑張れ!", "もうすぐランチ!がんばれ!", "12時台だよ!頑張れ!", "13時台だよ!頑張れ!", "14時台だよ!頑張れ!", "15時台だよ!頑張れ!", "16時台だよ!頑張れ!", "17時台だよ!頑張れ!", "18時台だよ!頑張れ!", "19時台だよ!頑張れ!", "20時台だよ!頑張れ!", "21時台だよ!頑張れ!", "22時台だよ!頑張れ!", "23時台だよ!頑張れ!", ] puts messages[Time.now.hour]
二つ目
case Time.now.hour when 0..2 puts '遅くまで頑張るね' when 3..4 puts 'もうすぐ朝です' when 5..7 puts 'おはよう' when 8..10 puts '今日も元気に頑張ろう' when 11 puts 'もうすぐお昼' when 12 puts '眠くなっても頑張ろう' when 13..15 puts 'おやつまで頑張ろう' when 16..18 puts '夕飯目指して頑張ろう' when 19..20 puts '残業頑張ろう' when 21..22 puts 'もう夜です' when 23 puts 'そろそろ寝ましょう' end
3:複数の数値を入力させ、昇順に並び替え、最大値と最小値を出す(例:同僚の体重を入力して計算)。
a = gets(nil).map{|v|v.to_i}.sort puts "最小値:#{a.min}" puts "最大値:#{a.max}" # ↓ソートしたことをいかすなら、こう puts "最小値:#{a.first}" puts "最大値:#{a.last}"
4:簡易電卓。0で割ったときの処理を自分なりに作りこむ。
# カッコも演算子の優先順位もないよ token_defs = [ [:space, /\s+/], [:numeric, /-?[0-9]+(?:\.[0-9]+)?/], [:operator, /[+\-*\/]/], ] input = gets.chomp tokens = [] i = 0 while input[i] find = nil token_defs.each do |token_def| find = ( /\A#{token_def[1]}/ =~ input[i..-1] ) if find tokens << [token_def[0], $&] unless token_def[0] == :space i += find + $&.size break end end raise unless find end raise unless tokens[0] raise unless tokens[0][0] == :numeric result = tokens[0][1].to_f (1...tokens.size).step(2) do |i| raise unless tokens[i][0] == :operator operator = tokens[i][1] raise unless tokens[i+1] raise unless tokens[i+1][0] == :numeric num = tokens[i+1][1].to_f case operator when '+' result += num when '-' result -= num when '*' result *= num when '/' result /= num else raise end end puts result
ゼロ割の処理を作りこめって何をすればいいの?FloatのNaNやInfinityじゃだめなのか?
ちゃんと、カッコが使えたり、演算子の優先度があるものも作りました。演算子の優先度できたよ! - fujidigの雑記
5:キーワードを入れてYahoo!の検索結果を出力。
正規表現でスクレイピング。APIはアプリケーションIDが必要らしい。
require 'kconv' require 'cgi' require 'open-uri' query = gets.chomp response = nil open("http://search.yahoo.co.jp/search?fr=yjdnqp&ei=UTF-8&p=#{CGI.escape(query.toutf8)}") do |f| response = f.read end response = response.kconv( Kconv::SJIS, Kconv::EUC ) response.gsub( /<a class="yschttl" href=".+?\*-(.+?)">(.+?)<\/a>/ ) do url = $1 title = $2 url = CGI.unescapeHTML( url.sub( /\Ahttp%3A\/\//, 'http://' ) ) title = CGI.unescapeHTML( title.gsub( /<\/?b>/, '' ) ) puts "#{url}:#{title}" end
参考:http://developer.yahoo.co.jp/query_parameters/websearch.html
6:テキストを入れると語尾が赤ちゃん言葉に(例:ですよ→でちゅよ)。
print gets(nil).gsub( 'ですよ', 'でちゅよ' )
7:メールアドレスを入れるとあらかじめ用意されたテンプレートファイルにそのメアドを埋め込んだ上でメール送信(スパムはダメだよ!)。
SMTPとか扱ったことねー後で
8:「(名前)が、(場所)で、(アクション)した」がランダムに組み合わされて出てくるプログラム。
list = { :who => %w(A君 Bさん C先生 校長先生), :where => %w(教室 廊下 トイレ グラウンド), :what => %w(踊った 笛を吹いた ジャンプした) } select = {} list.each{|k,v| select[k] = v[rand(v.size)] } who = select[:who] where = select[:where] what = select[:what] puts "#{who}が#{where}で#{what}"
9:URLを入れるとそのページのはてなブックマーク数が出てくるプログラム。
一つ目
require 'rexml/document' #require 'stringio' require 'net/http' print 'ブクマ数を表示するURI:' uri = gets.chomp request_xml = REXML::Document.new request_xml << REXML::XMLDecl.new( '1.0', 'UTF-8' ) methodCall = request_xml.add_element( 'methodCall' ) methodCall.add_element( 'methodName' ).add_text( 'bookmark.getCount' ) methodCall.add_element( 'params' ). add_element( 'param' ).add_element( 'value' ).add_element( 'string' ). add_text( uri ) ## StringIO を使わずに文字列で取得する方法ないの? #request_io = StringIO.new #request_xml.write request_io #request_io.pos = 0 #request = request_io.read # REXML::Document#to_sでいいみたいですね! request = request_xml.to_s Net::HTTP.version_1_2 response = nil Net::HTTP.start('b.hatena.ne.jp', 80) do |http| response = http.post( '/xmlrpc', request ).body end response_xml = REXML::Document.new( response ) count = response_xml.elements['/methodResponse/params/param/value/struct/member/value/int'].text.to_i puts "ブックマーク数:#{count}"
二つ目
require 'xmlrpc/client' print 'ブクマ数を表示するURI:' uri = gets.chomp client = XMLRPC::Client.new2("http://b.hatena.ne.jp/xmlrpc") count = client.call( 'bookmark.getCount', uri ).values[0] puts "ブックマーク数:#{count}"
XMLRPC++
10:ある名前とある名前を入れると相性診断を10段階で出してくれるプログラム。診断結果は適当でもいいけど、同じ組み合わせだったら同じ数値が必ずでないといけないように。
二人の名前の配列をソートしたハッシュ値を乱数のシード値に利用
N = 2 names = [] N.times do |i| print "#{i+1}人目の名前:" names << gets.chomp end affinity_list = [ '相性は最高です!', '相性は超いいです!', '相性はかなりいいです!', '相性は結構いいよ!', '相性はまあまあいいよ!', '相性は普通かな。', '相性はあまり良くないみたい。', '相性は悪いです。', '相性は超悪いです!', '相性は最悪です!', ] srand names.sort.hash affinity = affinity_list[rand(affinity_list.size)] puts affinity