论坛首页 Ruby版 ruby

Ruby每周一测 - 液晶屏数字

浏览 881 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
时间:2008-04-02
Ruby每周一测 - Ruby Quiz 是Ruby Talk邮件列表上的一个持续了很长时间活动,每周有一个小题目被提出来,然后大家进行解答讨论。Amazon上还有相关的书: Best of Ruby Quiz。我尝试挑选其中的一些题目进行翻译,做一个每周一测系列,欢迎大家参与讨论。

-----题目分割线-----

我们会在很多地方看到液晶屏样式显示的数字,比方说DVD/微波炉显示时间,常见的实现是利用7个发光二极管来做的:


这周的题目就是完成下面这个class,调用display方法进行液晶数字显示:
class LCD
	def initialize(scale=1)
		
	end

	def display(digits)	
	
	end
end


输出举例:
> lcd = Lcd.new
> puts lcd.display(86)
 -  -
| ||
 -  -
| || |
 -  -


这里采用"-", "|" 和空格进行输出, 并且scale参数能够指定输出样式的大小,在上面的例子中如果指定scale为2,输出结果就会变成:
> lcd = Lcd.new(2)
> puts lcd.display(86)
 --  --
|  ||
|  ||
 --  -- 
|  ||  |
|  ||  |
 --  -- 



-----解答分割线-----
原题和一些解法在这里:http://rubyquiz.com/quiz14.html
  • 634529e7-0055-3f42-bd7c-6a39f61587c8-thumb
  • 描述:
  • 大小: 2.3 KB
  • 查看次数: 365
   
时间:2008-04-02
查表法,比较暴力

class LCD  
  def initialize(scale=1)
    @number_map={"0"=>[1,1,1,0,1,1,1],
	"1"=>[0,0,1,0,0,1,0],
	"2"=>[1,0,1,1,1,0,1],
	"3"=>[1,0,1,1,0,1,1],
	"4"=>[0,1,1,1,0,1,0],
	"5"=>[1,1,0,1,0,1,1],
	"6"=>[1,1,0,1,1,1,1],
	"7"=>[1,0,1,0,0,1,0],
	"8"=>[1,1,1,1,1,1,1],
	"9"=>[1,1,1,1,0,1,1]}
    @width=scale+2
    @height=2*scale+3

    light=[[2..2+scale-1,1..1],
	[1..1,2..2+scale-1],
	[scale+2..scale+2,2..2+scale-1],
	[2..2+scale-1,scale+2..scale+2],
	[1..1,scale+3..scale*2+2],
	[scale+2..scale+2,scale+3..scale*2+2],
	[2..2+scale-1,scale*2+3..scale*2+3]]

    @light_map={}
    7.times do |i|
      light[i][0].each do |x|
        light[i][1].each do |y|
          @light_map["#{x},#{y}"]=i
        end
      end
    end
  end

  def display(digits)
    digits=digits.to_s
    str=""
    @height.times do |y|
      (digits.length*@width).times do |x|
        if x%@width==0 or x%@width==@width-1
          c="|"
        else
          c="-"
        end
        if @light_map["#{x%@width+1},#{y+1}"]
          if @number_map[digits[x/@width..x/@width]][@light_map["#{x%@width+1},#{y+1}"]]==1
            str<<c
          else
            str<<" "
          end
        else
          str<<" "
        end
      end
      str<<"\n"
    end
    return str
  end  
end

lcd = LCD.new(2)  
puts lcd.display("0024")
   
请登录后投票
时间:2008-04-02
class LCD
  NUMS = [[1,2,0,2,1],[0,1,0,1,0],[1,1,1,0,1],[1,1,1,1,1],[0,2,1,1,0],[1,0,1,1,1],[1,0,1,2,1],[1,1,0,1,0],[1,2,1,2,1],[1,2,1,1,1]]

  def initialize(scale = 1)
    @draw = [[' '+' '*scale+'  ', ' '+'-'*scale+'  '],
             ['|'+' '*scale+'  ', ' '+' '*scale+'| ', '|'+' '*scale+'| ']]
    @sc = scale
  end

  def display(num)
    rs = ''
    number = num.to_s
    0.upto(4) do |i|
      line = ''
      0.upto(number.length - 1) {|n| line << @draw[i%2][NUMS[number[n, 1].to_i][i]] }
      if i%2==1
        @sc.times { rs << line + "\n" }
      else
        rs << line + "\n"
      end
    end
    rs
  end
end

lcd = LCD.new(6)
puts lcd.display('009312376')
   
请登录后投票
时间:2008-04-03
其实查表法是一个很好的方法,很多真实的嵌入式系统就是用查表法实现的,即省CPU时间,又简单容易测试
   
请登录后投票
时间:2008-04-04
我也写一个
class LED
	Led = [' -     -  -     -  -  -  -  -    ',
		   '| |  |  |  || ||  |    || || |   ',
		   '       -  -  -  -  -     -  -    ',
		   '| |  ||    |  |  || |  || |  |   ',
		   ' -     -  -     -  -     -  -   .']
    Num = '0123456789.'
    
     def initialize(scale=1)  
        @scale = scale
     end  
   
     def display(digits)
		digits = digits.to_s
		@draw = ""
		0.upto(4) do |i|
			if i % 2 == 0
				digits.each_byte {|b| draw_line(i,b)}
			else
				@scale.times do
					digits.each_byte {|b| draw_line(i,b)} 
					@draw << "\n"
				end
			end
			@draw << "\n"
		end
		@draw
     end 
	 
	 protected
	 def draw_line(i, b)
		j = Num.index(b) * 3
		@draw << Led[i][j] << Led[i][j + 1 .. j + 1] * @scale << Led[i][j + 2]
	 end
end

led = LED.new(7)
puts led.display(5.8)
   
请登录后投票
时间:2008-04-04
to:caryl

你这个很不错,很直观。
   
请登录后投票
论坛首页 Ruby版 ruby

跳转论坛:
JavaEye推荐
    快速回复 引用上一条消息 (Alt+S)