LCD Number 解法极致扩展

LCD Number 具体介绍参见
http://www.iteye.com/topic/178880
原题和一些解法在这里:http://rubyquiz.com/quiz14.html

LCD Numbers感觉是一个比较经典的问题.涉及到编码,数据结构选择.研究了不少解法,希望有个即精炼,又好懂,扩展性又好的办法.一般解法三种类型:模版法(TEMPLATE),开关位,状态机(STATE MACHINE).这其中最好的是状态机法.用3横2竖这样5个笔划来表达一个LCD 字符,表达最精炼,扩展性也很好.
我专门研究了 电话接线器上的LCD屏,除了0-9数字外,还尽可能多的把字母也表示出来.A-F,HLNOPQU- 这些都可以处理,甚至S-5,T-7,1-I有时是相互替代的.
研究了几天,终于把电话接线器上的LCD显示完全实现了.显示的时候为了增加效果,采取一行行输出,最后看到整个LCD 显示.同时尽量做了全面的参数检测处理,如果有输入的字符不在能显示的LCD表中,将他们显示出来反馈给用户.自我感觉尽量做到完美了.
class LCD   

     #ALL LCD DIGIT CAN DIVIDE INTO 3 Horizon and 2 vertical line
     #order :h v h v h, 
     #horizon 2 type:  0:   ;1: - ;
     #vertical 4 type: 0:|  ;1:  |;2:| |;3   
     # change LCD_SYM to hash for flexible
      LCD_SYM = {"0"=>[1,2,0,2,1],
	      "1"=>[0,1,0,1,0],
	      "2"=>[1,1,1,0,1],
	      "3"=>[1,1,1,1,1],
	      "4"=>[0,2,1,1,0],
	      "5"=>[1,0,1,1,1],
	      "6"=>[1,0,1,2,1],
	      "7"=>[1,1,0,1,0],
	      "8"=>[1,2,1,2,1],
	      "9"=>[1,2,1,1,1],
              "A"=>[1,2,1,2,0], #for hex display
	      "B"=>[0,0,1,2,1],
	      "C"=>[1,0,0,0,1],
	      "D"=>[0,1,1,2,1],
	      "E"=>[1,0,1,0,1],
	      "F"=>[1,0,1,0,0],
	      "H"=>[0,2,1,2,0], 
	      "L"=>[0,0,0,0,1],
	      "N"=>[0,3,1,2,0], 	
	      "O"=>[0,3,1,2,1],
	      "P"=>[1,2,1,0,0],
	      "Q"=>[1,2,1,1,0],
	      "U"=>[0,2,0,2,1],
	      "-"=>[0,3,1,3,0]
             }   
  
  def initialize(scale = 1)   
    @draw = [[' '+' '*scale+'  ', # h0 
	     ' '+'-'*scale+'  '], # h1 
             ['|'+' '*scale+'  ', # v0 
              ' '+' '*scale+'| ', # v1
	      '|'+' '*scale+'| ', # v2
              ' '+' '*scale+'  ']] # v3, for 'no-' output  
    @sc = scale   
  end  
  
  def display(num)   
    number = num.to_s   
    0.upto(4) do |i|   
      line = ''  
      number.each_byte {|b| line << @draw[i%2][LCD_SYM[b.chr.upcase][i]] }   #LCD_SYM hash now 
      if i%2==1 # vertical line 
        @sc.times {puts line + "\n";sleep 0.8} # output line by line,not a whole
      else      # horizon line 
        puts  line + "\n"  
	sleep 0.8 #sleep 0.8 sec,enhance line by line effect
      end  
    end  
  end  
end  

def print_usage
  print "\nUsage: #{$0} [-s <size>] <symbols>\n",
        "    -s        scale size (positive integer), default is 2\n",
        "    symbols    symbols to display as lcd\n"
  exit 1
end
  
# ================================================================
# main
# ================================================================

if __FILE__ == $0
# get arguments and error checking on parameters
require 'getoptlong'

  print_usage & exit if ARGV.empty?	
  
  size = 2 # default scale
  opts = GetoptLong.new(
	 [ '--help', '-h', GetoptLong::NO_ARGUMENT ], 
	 [ "--size", "-s", GetoptLong::OPTIONAL_ARGUMENT] )
  opts.each do |opt, arg|
   case opt
     when '--help'
      puts "\nShow this message.\n"
      print_usage
      exit
     when  '--size'
      if arg.to_i.to_s != arg
       puts 'Error: size param is not a number'
       exit
      end
      size = arg.to_i
    end
   end

  print_usage & exit if ARGV.empty?
  
  disp_str = ARGV[0]

  reg =/[^0-9a-fA-FHhLlNno-qO-QUu-]/
 begin

  matches = disp_str.scan(reg)
  if not matches.empty?
     puts "u have input some chars not in LCD SYMBOL:" +matches.join
     puts "\n LCD SYMBOL:[0-9a-fA-FHhLlNno-qO-QUu-]\n"
     exit
  end

  lcd = LCD.new(size)   
  lcd.display(disp_str)  #display line by line,not a whole
 rescue NoMethodError
   puts "input some chars not include in LCD_SYMBOL"
 rescue =>err
   puts err	 
 end
end

你可能感兴趣的:(数据结构,F#,Ruby)