Code Golf: Seven Segments

2019-01-30 08:36发布

The challenge

The shortest code by character count to generate seven segment display representation of a given hex number.

Input

Input is made out of digits [0-9] and hex characters in both lower and upper case [a-fA-F] only. There is no need to handle special cases.

Output

Output will be the seven segment representation of the input, using those ASCII faces:

  _       _   _       _   _   _   _   _   _       _       _   _  
 | |   |  _|  _| |_| |_  |_    | |_| |_| |_| |_  |    _| |_  |_  
 |_|   | |_   _|   |  _| |_|   | |_|  _| | | |_| |_  |_| |_  | 

Restrictions

The use of the following is forbidden: eval, exec, system, figlet, toilet and external libraries.

Test cases:

Input:
    deadbeef

Output:
        _  _        _  _  _ 
     _||_ |_| _||_ |_ |_ |_ 
    |_||_ | ||_||_||_ |_ |  


Input:
    4F790D59

Output:
        _  _  _  _     _  _ 
    |_||_   ||_|| | _||_ |_|
      ||    | _||_||_| _| _|

Code count includes input/output (i.e full program).

26条回答
女痞
2楼-- · 2019-01-30 09:11

Man... can't beat the perl. Here's some py3k at 163 chars.

i=input()
[print(''.join('     | _  _||  | ||_ |_|'[(7&(d>>l))*3:][:3]for d
in[255&0xb4b61fa637bdbbbf89b7b3399b9e09af>>int(x,16)*8 for x in i]))for
l in[6,3,0]]

Explanation. First here's what it looked like completely unoptimized:

# segment positions, easily understandable as octal.  first digit is top row
# last digit is bottom row.  high bit is first column, low bit last.

a=[0o257, 0o011, 0o236, 0o233,
   0o071, 0o263, 0o267, 0o211,
   0o277, 0o273, 0o275, 0o067,
   0o246, 0o037, 0o266, 0o264]

# and the corresponding segments:
#   421    421    421    421    421    421    421    421  
b=['   ', '  |', ' _ ', ' _|', '|  ', '| |', '|_ ', '|_|']

# function to look for the proper segment for a decoded digit:
def lookup(digit, line):
    return b[ 7& (digit>>(6-line*3))]

#function to encode an ascii hex string into coded form suitible for
#above function
def code(i):
    return [a[int(x,16)] for x in i]

def fmt(i):
    return '\n'.join(''.join(lookup(d,l) for d in code(i)) for l in [0,1,2])

i = input()
print(fmt(i))

Then i go about finding ways to pack the data. First I can transform a into a big, long integer, last element first, 8 bits at a time. That produces, in octal: 0o2645541764615736673577046675463463347404657. written in hex, that's 0xb4b61fa637bdbbbf89b7b3399b9e09af, 90 chars shorter than the list of octals. To use it you have to rewrite code, of course. That looks like

def code_a_8(i):
    return [255&a_8>>int(x,16)*8 for x in i]

b can be concatenated, ''.join(b) is 26 chars, including the quotes. the lookup function must also change to support this.

def lookup_b_cat(d, l):
    return b_cat[(7&(d>>6-l*3))*3:][:3]

Next I just eliminate all unneeded syntax by folding functions and constants into the expression, and that's pretty much it.

It's possible to tighten up the printing a bit, too. Instead of joining the lines, just print them immediately. this results in a modified fmt():

def fmt_print(i):
    [print(''.join(lookup(d,l) for d in code(i))) for l in [0,1,2]]
查看更多
可以哭但决不认输i
3楼-- · 2019-01-30 09:12

Ruby: 175

d="3yy0nxcoypnk4185nbr3k9ddjlhe".to_i 36
s=gets.chomp
o=''
for i in 0..2
s.each_char{|c|q=d>>c.to_i(16)*3
"|_|".each_char{|z|o<<(q&1>0?z:' ')
q>>=1}}
d>>=48
o<<"\n"
end
puts o

And when a bit more readable...

d="3yy0nxcoypnk4185nbr3k9ddjlhe".to_i 36
s=gets.chomp
o=''
for i in 0..2
  s.each_char { |c|
    q = d >> c.to_i(16) * 3
    "|_|".each_char { |z|
      o << (q & 1 > 0 ? z : ' ')
      q >>= 1
    }
  }
  d >>= 48
  o << "\n"
end
puts o
查看更多
登录 后发表回答