10進数を2進数と16進数に変換する
"%b" % num "%x" % num
ってな具合に、フォーマットを指定すればすごい簡単なのだけど、
それじゃつまらないのでそれ以外の方法でやってみた。
2進数はまあこれで大丈夫。
でも16進数はうまくいってない・・・。
hex << 'F' で hex の末尾に 'F' が追加されるはずなのに、
なぜか '15' が追加されている。。
なんで・・・。
class Fixnum def to_b num = self bin = "" while num > 0 bin << (num % 2).to_s num /= 2 end bin.reverse end def to_x num = self hex = "" while num > 0 temp = (num % 16).to_s case temp when 10 hex << 'A' when 11 hex << 'B' when 12 hex << 'C' when 13 hex << 'D' when 14 hex << 'E' when 15 hex << 'F' else hex << temp.to_s end num /= 16 end hex.reverse end end while line = gets line.chomp! next unless /\d+/ =~ line num = line.to_i puts num.to_b puts num.to_x puts end
追記
このエントリを書いてから、
貼り付けたソースを見てみたらすぐに何が原因か分かった。
ぐあーなんておれは馬鹿なんだーーっ!
class Fixnum def to_b num = self bin = "" while num > 0 bin << (num % 2).to_s num /= 2 end bin.reverse end def to_x num = self hex = "" while num > 0 temp = (num % 16) #.to_s ← ここで .to_s してるのが問題だった!! case temp when 10 hex << 'A' when 11 hex << 'B' when 12 hex << 'C' when 13 hex << 'D' when 14 hex << 'E' when 15 hex << 'F' else hex << temp.to_s end num /= 16 end hex.reverse end end while line = gets line.chomp! next unless /\d+/ =~ line num = line.to_i puts num.to_b puts num.to_x puts end
追記の追記
コメントから、進数の変換にはInteger#to_sが使えることを知った。
以下はマニュアルからコピペしたもの。
色々とやり方はあるもんだなぁー。TIMTOWTDI!
p 10.to_s(2) # => "1010" p 10.to_s(8) # => "12" p 10.to_s(16) # => "a" p 35.to_s(36) # => "z"
ヒットアンドブローのスクリプトができた
でもひどいコードかも。。
ヒットアンドブローは、コンピュータの用意した数字の並びを当てるゲーム。
コンピュータは、こちらが考えた数字の並びと自分のものを比較して、
次の2つのヒントをくれる。
- HIT: 数字も場所も合っているものの数
- BLOW: 数字は合っているが場所は合っていないものの数
例えば、コンピュータの用意した数字の並びが4278で、
プレイヤーが考えた数字が4321だったときは、HIT:1 BLOW:1となる。
全部をHITにできれば勝ち。
また、今回は同じ数字を使ってもいいようにしてみた。
(そのせいで手こずった・・・。)
=begin ヒットアンドブロー <概要> コンピュータの用意した数字の並びと同じ数字の並びをつくれば勝ち HIT: 数字も場所も合っている BLOW: 数字は合っているが場所は合っていない <usage> > ruby hit-and-blow.rb [size] [size]でいくつの数字の並びなのかを指定できる(デフォルトは4) =end # 複数の数字の管理をする class Numbers def initialize(size = 4) @size = size.to_i @numbers = Array.new # コンピュータの用意する数字の並び @size.times{ @numbers << rand(10) } end # カードの表示 def disp puts "com> #{@numbers}" end # コンピュータの用意した数字の並びとプレイヤーの数字の並びを比較する def compare(ply) # コンピュータとプレイヤーの用意した各数字の間にリンクを考える # 対応する数字同士はリンクする links = Array.new @size.times{ link = Hash.new link['to'] = nil link['type'] = nil links << link } @size.times{|c| @size.times{|p| # toがpで、typeがhitのLinkが存在する場合はply[p]をパス next if links.detect{|l| l['to'] == p and l['type'] == 'hit'} if @numbers[c] == ply[p].to_i links[c]['to'] = p if c == p if l = links.detect{|l| l['to'] == p and l['type'] == 'blow'} l['to'] = l['type'] = nil end links[c]['type'] = 'hit' break # 'hit'が分かったら、そのcom[c]の処理は終了 else links[c]['type'] = 'blow' end end } } hit = blow = 0 links.each{|l| hit += 1 if l['type'] == 'hit' blow += 1 if l['type'] == 'blow' } puts " HIT:#{hit} BLOW:#{blow}" if hit == @size puts "Congratution!!" exit end end end size = ARGV.shift || 4 com = Numbers.new(size) puts "#{size}つのランダムな数字の並びを当ててください。" loop{ print "ply> " line = gets line.chomp! exit if /^e/ =~ line com.disp if /^d/ =~ line com = Numbers.new if /^r/ =~ line unless /^\d{#{size}}$/ =~ line puts "#{size}つの数字を指定してください。" next end ply = line.split(//) # プレイヤーの用意する数字の並び # 比較のために配列にする必要がある com.compare(ply) }
今回、僕は自分で思っているよりもプログラムが書けないことに気づいた。
もっと色々自分で考えて書いてみないとダメだと思った。
だからもっと色々自分で考えて書いてみようと思う。
今月のカレンダーを出力
わりとキレイに書けたような気がする。
たのしいRubyの練習問題にも似たようなのあったなぁ。
require "date" def calendar today = Date.today fday = Date.new(today.year, today.month, 1) lday = Date.new(today.year, today.month, -1) # Date#wday は週の何日目かを表す。日曜が0。月曜を0にしたいので-1する。 wday = fday.wday - 1 # 日曜日の場合は-1なので6に変更する。 wday = 6 if wday == -1 puts today.strftime("%Y %B").center(20) puts "--------------------" puts "Mo Tu We Th Fr Sa Su" print " " * (wday) fday.day.upto(lday.day){|d| print "%2d " % d wday += 1 if wday == 7 puts wday = 0 end } end calendar
実行結果はこんな感じ。
2007 June -------------------- Mo Tu We Th Fr Sa Su 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
RSSをHTMLに変換
指定されたRSSのitemのtitleをcheckbox付きのHTLで出力する。
HTMLが整形されてないのが気になるけど、
とりあえずこれはこれでほぼ完成。
連携するCGIの方は、まだ何もできていないので完成したとは言えない。
require 'rss' require 'kconv' def print_items(rss) html = "" html << %Q(<form method="GET" action="hoge.cgi">\n) item_num = 0 rss.items.each{|item| html << %Q(<input type="checkbox" name="item" value="#{item_num += 1}">) html << %Q(#{item.title}<br />\n) } html << %Q(<input type="submit"><br />\n) html << %Q(</form>\n) html ## 標準出力用 # rss.items.each{|item| # puts "#{item.title}: #{item.description}".tosjis # } end def output_file(filename, rss) html = "" html << "<html><body>\n" html << "<ul>\n" html << print_items(rss) html << "</ul>\n" html << "</body></html>" html = html.tosjis open(filename, 'w'){|f| f.print(html) } print html end rss_src = ARGV[0] || 'http://b.hatena.ne.jp/hotentry?mode=rss' # 第二引数にtrueを与えると、バリデーション付きでパースする。 rss = RSS::Parser.parse(rss_src, true) filename = __FILE__.sub(/\.rb$/, '.html') print_items(rss) output_file(filename, rss)
Sign up | Tumblrを使って何かしようとしてるのは内緒。
読み方はたんぶらー?たんぶるる?
僕はたんぶらーと読みたい。