Hatena::Grouprubyist

bongoleのRubyを楽しむ日記 このページをアンテナに追加 RSSフィード

Rubyを楽しむ日記

2006-05-30

[][][]続・解答 00:57 続・解答 - bongoleのRubyを楽しむ日記 を含むブックマーク

昨日の続き。

3つめの解答。コードはcode/lcd_number/states.rb。

この解答はちょっと変わっていて、縦棒のある行と横棒のある行にそれぞれ以下のような状態をもたせる。

縦棒のある行

  • 0 縦棒なし
  • 1 右側にだけ縦棒がある
  • 2 左側にだけ縦棒がある
  • 3 両側に縦棒がある

横棒のある行

  • 0 横棒なし
  • 1 横棒あり

でこれらの状態を使って図形を配列で表すと

LCD_DISPLAY_DATA = {
#0だけわかりやすく書いてみる
"0" => [1, #  -  横棒がある
         3, # | | 縦棒が両側にある
         0, #     横棒がない
         3, # | | 縦棒が両側にある
         1  #  -  横棒がある
        ],
"1" => [ 0, 1, 0, 1, 0 ],
"2" => [ 1, 1, 1, 2, 1 ],
"3" => [ 1, 1, 1, 1, 1 ],
"4" => [ 0, 3, 1, 1, 0 ],
"5" => [ 1, 2, 1, 1, 1 ],
"6" => [ 1, 2, 1, 3, 1 ],
"7" => [ 1, 1, 0, 1, 0 ],
"8" => [ 1, 3, 1, 3, 1 ],
"9" => [ 1, 3, 1, 1, 1 ]
}

であとは以下のコードのように

横棒のある行、縦棒のある行の状態に対する処理を書き

横棒のある行→縦棒のある行→横棒のある行→縦棒のある行→横棒のある行の順番に処理をしていけば最終的な結果を得られる。

  LCD_STATES = [
    "HORIZONTAL",
    "VERTICAL",
    "HORIZONTAL",
    "VERTICAL",
    "HORIZONTAL",
    "DONE"
  ]

  def display( digits )
    states = LCD_STATES.reverse
    0.upto(LCD_STATES.length) do |i|
      case states.pop
      when "HORIZONTAL" #横棒のある行に対する処理
        line = ""
        digits.each_byte do |b|
          line += horizontal_segment( LCD_DISPLAY_DATA[b.chr][i] )
        end
        print line + "\n"
      when "VERTICAL" #縦棒のある行にたいする処理
        1.upto(@size) do |j|
          line = ""
          digits.each_byte do |b|
            line += vertical_segment( LCD_DISPLAY_DATA[b.chr][i] )
          end
          print line + "\n"
        end
      when "DONE"
        break
      end
    end
  end

この解答のすごいところは、行列を入れ替えたり配列を結合したりしなくても画面で見える1行分の結果が1度に作れるのでメモリを食わないということみたい。

かに、前2つの解答では入力が多くなればなるだけ巨大な配列の確保と操作をしなければならないがこの解答では繰り返しの回数が多くなるだけで消費するメモリは少なくて済む。

いやいや、今回の問題はrubyというよりも考え方が勉強になりました。

明日は、いよいよ次の問題をやろうと思う。

つづく