36

挑战

按字符计数的最短代码生成七段显示给定十六进制数的表示形式。

输入

输入仅由数字 [0-9] 和小写和大写的十六进制字符 [a-fA-F] 组成。没有必要处理特殊情况。

输出

输出将是输入的七段表示,使用这些ASCII面:

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

限制

禁止使用以下内容:eval、exec、system、figlet、toilet 和外部库。

测试用例:

Input:
    deadbeef

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


Input:
    4F790D59

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

代码计数包括输入/​​输出(即完整程序)。

4

26 回答 26

30

C89(181 个字符;参数)

char*q,a=3;p(l){putchar(*q?"|#]u&rzc~vn:X=ZJ"[*q-(*q&64?55:48
)&15]+1>>l&1?"|_||_|_"[l]:32:10);}main(r,v)char**v;{for(;a--
;p())for(q=v[1];*q;++q)for(r=3;r--;)p(a-2?5-r-a*3:r-1?7:6);}

C89(192 个字符;stdin

char*q,b[9],gets(char*),a=3;p(l){putchar(*q?"|#]u&rzc~vn:X=ZJ"[*
q-(*q&64?55:48)&15]+1>>l&1?"|_||_|_"[l]:32:10);}main(r){for(gets
(b);a--;p())for(q=b;*q;++q)for(r=3;r--;)p(a-2?5-r-a*3:r-1?7:6);}

解释:

char*q,b[9],gets(char*),a=3;
p(l){
    putchar(*q?
        /*
         * Each element of the magic string is decremented so 0x7F is
         * '~' (0x7E).  Each bit before the decrement represents
         * a segment (thus "8" is 0x7F (0x7E), i.e. all 7 bits on).
         * Bit 7 is always cleared so p(7) always prints a space.
         */
        "|#]u&rzc~vn:X=ZJ"
        [*q-(*q&64?55:48)&15]+1 /* d[ascii2hex(*q)] + 1 */
        >>l&1                   /* Is bit 'l' set? */
            ?"|_||_|_"[l]       /* Yes; choose _ or | by position. */
            :32                 /* No; enter a space. */
    :10);                       /* End of line. */
}
main(r){
    for(gets(b);a--;p())                /* Grab input and loop through each of 3 lines (a = 2, 1, 0). */
        for(q=b;*q;++q)                 /* Iterate across input. */
            for(r=3;r--;)               /* For each of three characters across... */
                p(a-2?5-r-a*3:r-1?7:6); /* Print the segment, mapping position to the bit. */
}
于 2009-09-10T20:29:58.523 回答
30

Perl,134 个字符

可以删除所有换行符。

@s=unpack"C*",~"P\xdbLI\xc3a`[\@AB\xe0t\xc8df";
$_=<>;for$s(6,3,0){print map$s[hex$&]&1<<$_+$s?$_%2?"_":"|":" ",
0..2while/./g;print$/}

解释

@s存储每个段的位。条目按从 0 到 F 的顺序排列(感谢hex()),位按以下顺序映射到段:

6 7 x
3 4 5
0 1 2

0作为LSB 。(位 6 未使用)。这些值存储在按位反转的字符串中,因此有更多的可打印字符;运算符~翻转位并解包给我数字(perl 的按位运算符在字符串方面要笨拙得多)。

有了手中的数据,我读取了输入并继续循环三遍;三个循环之间的唯一区别是所需的位掩码。对于输入的每个字符,都会打印三个输出字符。要打印的字符是

$s[ hex $& ] & (1 << ($_ + $s) )
? ($_ % 2 ? "_" : "|" )
: " "

@s查找表在哪里$s,效果取决于行的变化,以及$_我们是否打印行中的第一个、第二个或第三个字符。如果查找表条目中的正确位为假,则打印一个空格;否则打印一个“|” 在两侧或中间的“_”。

于 2009-09-11T00:28:22.923 回答
14

COM 可执行文件:102 字节

使用A86组装以下内容(这是原始的更大版本):

dd 0801E8Ah,0BD80C380h,03B50154h,0D789D58Ah,0B20082BEh,077F33B03h,0C048A29h,0149F0420h
dd 020AD431h,088C402C4h,01468BC1h,0F8C1E0D3h,046220Fh,0AA036E8Dh,0DD75CAFEh,04609ED83h
dd 0C583D1EBh,0D0AB809h,075CDFEABh,0AA24B0C3h,021CD09B4h,05F0000C3h,020B7EBh,8EFB7C00h
dd 07C3EF75Fh,0BF7CF9E4h,0B6DE5FA2h
dw 0F47Ch
db 0DFh

编辑:

DosBox 问题可能是程序在启动时假定寄存器值的方式。无论如何,这是组装到 102 字节的修改后的源代码,应该可以与 DosBox 一起使用:

    mov bp,d1
    mov ch,3
    mov dx,ds ; if you want to use dos box, put "mov dx,08000h" here instead, it might fix the problem
    mov di,dx
l4: mov si,082h
l3: mov bl,3
    cmp byte ptr [si],0dh
    je l5
    mov cl,[si]
    cmp cl,40h
    jle l2
    add cl,9
l2: and cl,0fh
l1: mov ax,word ptr [bp+1]
    shl ax,cl
    sar ax,15
    and al,byte ptr [bp]
    add bp,3
    stosb
    dec bl
    jnz l1
    sub bp,9
    inc si
    jmp l3
l5: add bp,9
    mov ax,0d0ah
    stosw
    dec ch
    jnz l4
    mov al,'$'
    stosb
    mov ah,9
    int 21h
d1: ret
    dw 0
    db '_'
    dw 01011011111101011xb
    db ' '
    dw 0
    db '|'
    dw 01000111011111011xb
    db '_'
    dw 00011111011110111xb
    db '|'
    dw 01111100111100100xb
    db '|'
    dw 01010001010111111xb
    db '_'
    dw 01011011011011110xb
    db '|'
    dw 01101111111110100xb

感谢 ehemient 的一些调整!

于 2009-09-11T14:25:54.100 回答
13

x86(146 字节;参数)

受到乔纳斯·古勒 ( Jonas Gulle ) 在Code Golf: The wave中的启发。通常我会写一个 32 位的 Linux ELF,但一个 16 位的 DOS COM 小得多(指令更短,零开销)。

46 条指令和 24 个未执行字。(它们在最后确实很明显,不是吗?)没有什么比将代码重用为数据更棘手的了。无论如何,它可能不会节省超过 10 个字节。

C:\>od -xAn ss.com
 c930 82be ac00 0d3c 3e74 403c 027e 0904
 0f24 0198 bbc8 0162 c301 0eb4 078a 0424
 0474 7cb0 02eb 20b0 10cd 078a 0224 0474
 5FB0 02EB 20B0 10CD 078A 0124 0474 7CB0
 02eb 20b0 10cd bdeb f980 7420 b014 cd0d
 b010 cd0a 6610 c381 0010 0000 c180 eb10
 c3a1 0002 0202 0200 0202 0202 0002 0002
 0202 0105 0303 0607 0106 0707 0607 0304
 0606 0107 0306 0301 0107 0307 0705 0706
 0406
C:\>ss 死牛
    _ _ _ _ _
 _||_ |_| _||_ |_ |_ |_
|_||_ | ||_||_||_ |_ |  

这只是逐个字母地打印第一行,然后是第二行,等等。使用 3 个字节来存储每个字符的 9 位数据。显然还有改进的空间……(这是我第一次使用NASM语法;我更习惯于gas,但我无法说服它输出原始二进制文件。)

org 0x100

; initialize registers
    xor cl,cl

; reset ds:[si] to start of arguments
start:
    mov si,0x82

; load one character of arguments
read:
    lodsb
    cmp al,0xd
    je next

; transform [0-9A-Fa-f] to [\x00-\x0f]
    cmp al,0x40
    jle skipa
    add al,0x9
skipa:
    and al,0xf

; load font definition
    cbw
    add ax,cx
    mov bx,letters
    add bx,ax
    mov ah,0xe

; print first char
    mov al,[bx]
    and al,0x4
    jz s1
    mov al,0x7c
    jmp short w1
s1:
    mov al,0x20
w1:
    int 0x10

; print second char
    mov al,[bx]
    and al,0x2
    jz s2
    mov al,0x5f
    jmp short w2
s2:
    mov al,0x20
w2:
    int 0x10

; print third char
    mov al,[bx]
    and al,0x1
    jz s3
    mov al,0x7c
    jmp short w3
s3:
    mov al,0x20
w3:
    int 0x10

; next character
    jmp short read

; print newline
next:
    cmp cl,0x20
    je end
    mov al,0xd
    int 0x10
    mov al,0xa
    int 0x10
    add ebx,0x10
    add cl,0x10
    jmp short start

end:
    ret

letters:
    db 2,0,2,2,0,2,2,2,2,2,2,0,2,0,2,2
    db 5,1,3,3,7,6,6,1,7,7,7,6,4,3,6,6
    db 7,1,6,3,1,3,7,1,7,3,5,7,6,7,6,4
于 2009-09-12T05:21:45.723 回答
6

男人...无法击败perl。这是一些 163 个字符的 py3k。

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]]

解释。首先是它看起来完全未优化的样子:

# 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))

然后我开始寻找打包数据的方法。首先,我可以转换a成一个大的长整数,最后一个元素在前,一次 8 位。这会产生八进制:0o2645541764615736673577046675463463347404657. 用十六进制编写,即0xb4b61fa637bdbbbf89b7b3399b9e09af比八进制列表短 90 个字符。当然,要使用它,您必须重写代码。看起来像

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

b可以连接,''.join(b)是 26 个字符,包括引号。查找功能也必须改变以支持这一点。

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

接下来,我只是通过将函数和常量折叠到表达式中来消除所有不需要的语法,仅此而已。

也可以稍微收紧打印。不要加入这些行,只需立即打印它们。这导致修改fmt()

def fmt_print(i):
    [print(''.join(lookup(d,l) for d in code(i))) for l in [0,1,2]]
于 2009-09-11T05:19:25.627 回答
6

好吧,很难击败像 Perl 这样的专业语言。但是,这是160 字节的Python版本:

i=input().lower()
for x in[' #_ 14bd# ','| 1237d#_ 017c#| 56bcef','| 134579#_ 147af#| 2cef']: print(' '.join(''.join(y[j in y]for y in x.split('#'))for j in i))

未打高尔夫球的版本:

input_ = input().lower()

for magic in [' #_ 14bd# ',
          '| 1237d#_ 017c#| 56bcef',
          '| 134579#_ 147af#| 2cef',
         ]:
    # We have three lines, so x iterates over 3 magic strings.
    print(' '.join(
                # This is the cycle iterating over digits.
                ''.join(
                    # For each line and digit we need to print several
                    # letters. To do this, we break a magic string into
                    # 3 chunks. A chunk usually contains digits that
                    # *don't* have an element there. 
                    chunk[digit in chunk]
                    # For example, lower right chunk y="| 2cef". For digits
                    # 2, c, e, f, there should be " ", for all others there
                    # should be "|". So for digits 2, c, e, f, `j in y` returns
                    # False and indexes y[0], for other digits it indexes y[1]. 
                for chunk in magic.split('#'))
          for digit in input_)) 
于 2009-09-14T19:30:58.847 回答
5

红宝石: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

当更具可读性时...

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
于 2009-09-11T00:16:49.600 回答
5

C(170 个字符)

i,j;main(c,s){char**r=s,*p=*++r;for(;i<3;)j--?putchar(!p[-1]?p=*r,++i,j=0,10:
"##3#3133X=W.<X/`^_G0?:0@"[i*8+c/2]-33>>c%2*3+j&1?"|_"[j&1]:32):(j=3,c=*p++&31,
c-=c>6?10:1);}

这将输入字符串作为命令行参数。转换为使用 stdin 将是另一个字符:

i,j;main(c){char s[99],*p=s;for(gets(s+1);i<3;)j--?putchar(!*p?p=s,++i,j=0,10:
"##3#3133X=W.<X/`^_G0?:0@"[i*8+c/2]-33>>c%2*3+j&1?"|_"[j&1]:32):(j=3,c=*++p&31,
c-=c>6?10:1);}

stdin 版本最多可以接受 98 个输入字符。当然,任何超过floor(terminalWidth / 3)都会导致令人困惑的换行。

每个字符的输出被视为 3x3 网格,其中每行中的单元格是段。段是“开”或“关”。如果段为“on”,则输出 a'|'或 a '_',具体取决于位置。如果它关闭,则输出一个空格。字符数组是一个位数组,用于确定每个段是打开还是关闭。更多关于代码后的内容:

i,j; /* Loop variables. As globals, they'll be initialized to zero. */
main(c,s){
    /* The signature for main is
     *
     *     main(int argc, char **argv)
     *
     * Rather than add more characters for properly declaring the parameters,
     * I'm leaving them without type specifiers, allowing them to default to
     * int.  On almost all modern platforms, a pointer is the same size as
     * an int, so we can get away with the next line, which assigns the int
     * value s to the char** variable r.
     */

    char**r=s,*p=*++r;
    /* After coercing the int s to a char** r, offset it by 1 to get the
     * value of argv[1], which is the command-line argument.  (argv[0] would
     * be the name of the executable.)
     */

    for(;i<3;) /* loop until we're done with 3 lines */

        j--?
         /* j is our horizontal loop variable.  If we haven't finished a
          * character, then ... */

            putchar(  /* ...we will output something */
                !p[-1]? /* if the previous char was a terminating null ... */

                    p=*r,++i,j=0,10
                    /* ... reset for the next row.  We need to:
                     *
                     * - reinitialize p to the start of the input
                     * - increment our vertical loop variable, i
                     * - set j to zero, since we're finished with this
                     *   "character" (real characters take 3 iterations of
                     *   the j loop to finish, but we need to short-circuit
                     *   for end-of-string, since we need to output only one
                     *   character, the newline)
                     * - finally, send 10 to putchar to output the newline. */

                    :"##3#3133X=W.<X/`^_G0?:0@"[i*8+c/2]-33>>c%2*3+j&1?
                    /* If we haven't reached the terminating null, then
                     * check whether the current segment should be "on" or
                     * "off".  This bit of voodoo is explained after the
                     * code. */

                        "|_"[j&1]:32
                        /* if the segment is on, output either '|' or '_',
                         * depending on position (value of j), otherwise,
                         * output a space (ASCII 32) */
            )/* end of putchar call */

            :(j=3,c=*p++&31,c-=c>6?10:1);
            /* this is the else condition for j--? above.  If j was zero,
             * then we need to reset for the next character:
             *
             * - set j to 3, since there are three cells across in the grid
             * - increment p to the next input character with p++
             * - convert the next character to a value in the range 0–15.
             *   The characters we're interested in, 0–9, A–F, and a–f, are
             *   unique in the bottom four bits, except the upper- and
             *   lowercase letters, which is what we want.  So after anding
             *   with 15, the digits will be in the range 16–25, and the
             *   letters will be in the range 1–6.  So we subtract 10 if
             *   it's above 6, or 1 otherwise.  Therefore, input letters
             *   'A'–'F', or 'a'–'f' map to values of c between 0 and 5,
             *   and input numbers '0'–'9' map to values of c between
             *   6 and 15.  The fact that this is not the same as the
             *   characters' actual hex values is not important, and I've
             *   simply rearranged the data array to match this order.
             */
}

字符数组描述字符网格。数组中的每个字符描述了两个输入字符的输出网格的一个水平行。网格中的每个单元格由一位表示,其中1表示该段为“on”(因此输出 a'|'或 a '_',具体取决于位置),并0表示该段为“off”。

它需要数组中的三个字符来描述两个输入字符的整个网格。数组中每个字符的最低三位,即 0-2 位,描述了这两个字符中偶数输入字符的一行。接下来的三位,即位 3-5,描述了两位中奇数输入字符的一行。第 6 位和第 7 位未使用。这种排列,偏移量为 +33,允许数组中的每个字符都是可打印的,没有转义码或非 ASCII 字符。

我玩弄了几种不同的编码,包括将输入字符的所有 7 个段的位放入数组中的一个字符中,但发现这个是整体最短的。虽然此方案需要数组中的 24 个字符来表示仅 16 个输入字符的段,但其他编码要么需要使用非 ASCII 字符(当我在我的摩尔斯电码高尔夫答案中使用它时,不出所料会导致问题),很多转义码, 和/或复杂的解码代码。这个方案的解码代码非常简单,尽管它确实充分利用了 C 的运算符优先级来避免添加任何括号。

让我们把它分解成小步骤来理解它。

"##3#3133X=W.<X/`^_G0?:0@"

这是编码数组。让我们抓取适当的字符进行解码。

[i*8

前 8 个字符描述顶行段,接下来的 8 个描述中间行段,最后 8 个描述底行段。

 +c/2]

请记住,此时,c 包含一个从 0 到 15 的值,它对应于 ABCDEF0123456789 的输入,并且该数组对每个编码字符编码两个输入字符。因此,数组中的第一个字符'#'保存了“A”和“B”的顶行的位,第二个字符也'#'编码了“C”和“D”的顶行,依此类推。

-33

编码会产生几个小于 32 的值,这需要转义码。这个偏移量将每个编码字符带入可打印的非转义字符范围。

>>

右移运算符的优先级低于算术运算符,因此此移位是在减去偏移量后对字符进行的。

c%2*3

c%2对偶数计算为零,对奇数计算为一,因此我们将对奇数字符右移 3,得到第 3-5 位,对偶数字符完全不移动,提供对第 0-2 位的访问. 虽然我更喜欢使用c&1偶数/奇数检查,这也是我在其他地方使用的,但&运算符的优先级太低,无法在此处使用而不添加括号。%运算符具有正确的优先级。

+j

移动额外的j位以获得当前输出位置的正确位。

&1

按位和运算符的优先级低于算术运算符和移位运算符,因此这将测试在移位使相关位变为位零之后是否设置了位零。

?

如果位零设置...

"|_"

...输出这些字符之一,由...选择

[j&1]

...我们的水平循环变量是偶数还是奇数。

:32

否则(未设置位零),输出 32(空格字符)。


如果有的话,我不认为我可以将其进一步精简,当然也不足以击败hobbs 的 perl entry

于 2009-09-11T14:14:35.630 回答
5

Golfscript - 116 个字符

$ echo -n deadbeef | ./golfscript.rb  led.gs 
    _  _        _  _  _ 
 _||_ |_| _||_ |_ |_ |_ 
|_||_ | ||_||_||_ |_ | 

确保保存末尾没有额外的换行符,否则将在末尾打印输入字符串。

{32:^|}%:
{^' _':$@'14bd'{?~!=}:&~^}%n
{:x' |':|\'1237d'&$x'017c'&|x'56bcef'&}%n
{:x|\'134579'&$x'147af'&|x'2cef'&}%

这个怎么运作

请注意,在 0-F 范围内,打开的段多于关闭的段。列出每个段的例外情况(关闭段的数字)。

#Python version of the algorithm above
s=raw_input().lower()
J=''.join()
print J(' '+'_ '[c in'14bd']+' 'for c in s)
print J('| '[c in'1237d']+'_ '[c in'017c']+'| '[c in'56bcef']for c in s)
print J('| '[c in'134579']+'_ '[c in'147af']+'| '[c in'2cef']for c in s)
于 2009-11-10T01:03:29.543 回答
4

我的第一个代码高尔夫。279 个非空白字符,433 个包括空格。我敢肯定它在 Python 中可能会更短。

Python

import sys
w = sys.stdout.write
i = raw_input()
d = [111,9,94,91,57,115,119,73,127,123,125,55,102,31,118,116]
p = [' _ ','|','_','|','|','_','|']
j = 0
for r in range(3):
    for c in i.lower():
        for n in range(3 if r else 1):
            s = p[j+n]
            if (1<<6-j-n) & d[ord(c)-(ord('0') if c.isdigit() else ord('a')+6)]:
                w(s)
            else:
                w(' '*len(s))
    j += n+1
    w('\n')
于 2009-09-10T20:54:04.237 回答
4

BrainF***, 920 906 885 868 863 860 858 个数字时钟字符

我从(现已关闭的)数字时钟代码高尔夫开始,所以 : 也受支持。Todo:处理小写。

-[>+<-----]->----[>,]<[<]>>[[->]<+[-<+]->]<+>-[>]+++[[<]>>[[>]>[>]+[<]<[<]+[>]>[
>]+[-<+]->[[>]>[>]<+[<]<[<]>+[>]+[-<+]->-]->]<[<]>+[-[>]+[-<+]+<[<]>[[>]+[-<+]->
+<[<]>-]>+]+[-->]+[->]-[>-<-----]>+++>-->->----<<<[>>+++>+++++>-[+++<]>]-<+[>]-[
<]>>>+[-<<+[->+]<<-[-[++>->>[>]>>+++++>>+++++>>>>>+++++>>>+++++++>>>>>>+++++>>>+
++++>>+[<+]<[<]<]>[-<++>>>[>]<--->+>+>->++++++>+>-->>>>>>>+++>-->-->>+>+>-->->->
>+++++>+[<++++]<[<]]<]>[-<+>>>[>]<--->++++++>+>-->+>-->+++++>>>>>>>+++>->-->>-->
->>->+>>-->+[<++++]<[<]]<+>-[[>]>[>]<[-]<[<]<[<]>-]>[>]>[>]+<-[-[-[-[-[-[-[-[-[[
<]<<.>...>>[>]<-]>[<+[<]<<.>.<.>.>>[>]<->]<]>[<+[<]<..>>[>]<->]<]>[<+[<]<<<<.>>>
.>>[>]<->]<]>[<+[<]<....>>[>]<->]<]>[<+[<]<<.<.>>..>>[>]<->]<]>[<+[<]<..<.>.>>[>
]<->]<]>[<+[<]<.<<.>.>.>>[>]<->]<]>[<+[<]<<.<.>.>.>>[>]<->]<]>[<+[<]<.<<.>>..>>[
>]<->]<<[[-]<]-[<]>>>+]++++++++++.[>]<[[-]<]+[-<+]-[>]<-]

$ echo 01:23456789DEADBEEF | beef clock.b 
 _         _   _       _   _   _   _   _       _   _           _   _   _  
| |   | .  _|  _| |_| |_  |_    | |_| |_|  _| |_  |_|  _| |_  |_  |_  |_  
|_|   | . |_   _|   |  _| |_|   | |_|  _| |_| |_  | | |_| |_| |_  |_  |   

这在很大程度上取决于 8 位平台。

于 2010-07-25T22:48:12.400 回答
3

Python,总共 188 个字符

我没有过多地研究其他解决方案,但我确信仍有很大的改进空间。

n=int(raw_input(),16)
O=[""]*3
while n:O=["".join(" |_"[(m>>n%16*3+i&1)*(i%2+1)]for i in[2,1,0])+o
for o,m in zip(O,[0x482092490482,0xd9cdff3b76cd,0x9bef5f3d978f])];n>>=4
print"\n".join(O)
于 2009-09-10T23:14:12.490 回答
3

F#,294 个字符

我没有做任何聪明的事,但仍然获得了可观的分数。

let rec G s=for r in[" _     _  _     _  _  _  _  _  _     _     _  _ ";"| |  | _| _||_||_ |_   ||_||_||_||_ |   _||_ |_ ";"|_|  ||_  _|  | _||_|  ||_| _|| ||_||_ |_||_ |  "]do Seq.iter(printf"%s"<<S r)s;printfn""
and S a h=a.Substring(3*(int h-if h<'A'then 48 elif h<'a'then 55 else 87),3)

为了清楚起见,使用空格:

let rec G s=
    for r in[" _     _  _     _  _  _  _  _  _     _     _  _ ";
             "| |  | _| _||_||_ |_   ||_||_||_||_ |   _||_ |_ ";
             "|_|  ||_  _|  | _||_|  ||_| _|| ||_||_ |_||_ |  "] do 
        Seq.iter (printf "%s" << S r) s;
        printfn""
and S a h=
    a.Substring(3*(int h - if h<'A'
                           then 48 
                           elif h<'a'
                           then 55 
                           else 87),3)

样本:

G("abcdefFEDCBA9876543210")

输出:

 _     _     _  _  _  _     _     _  _  _  _  _  _     _  _     _
|_||_ |   _||_ |_ |_ |_  _||  |_ |_||_||_|  ||_ |_ |_| _| _|  || |
| ||_||_ |_||_ |  |  |_ |_||_ |_|| | _||_|  ||_| _|  | _||_   ||_|
于 2009-09-11T08:22:39.663 回答
2

Java 1.5 - 272 个字符,删除了不必要的空格

使用 JRL 的一些想法,比早期版本短得多。可以通过使用命令行参数来缩短,但这违反了规范。

class D{public static void main(String[]a){char[]q=new java.util.Scanner
(System.in).nextLine().toCharArray();int j=0,k;for(;j<9;j+=3){for(int c:
q){for(k=j;k<j+3;k++){System.out.print(("{H=mNgwI\177o_v3|7\027".charAt(
"0123456789abcdef".indexOf(c|32))&"\0\1\0\2\4\10\20 @".charAt(k))>0?
" _ |_||_|".charAt(k):32);}}System.out.println();}}}
于 2009-09-10T20:59:05.833 回答
2

C++,286 字节

呵呵,大家想出了更简洁的方式来表示数据。

无论如何,这样就不会完全浪费时间(从命令行输入):

#include<cstdio>
#define P(x)putchar(x);
int main(int,char**v){int i,j,d[]={0,6947821,0,7209841,7734140,1180575,8257861,
3933037,1442811};char*p,c[]="|_|";for(++v;*v;++v){for(i=0;i<9;i+=3){for(p=*v;*p;
++p){for(j=0;j<3;++j)P(1<<((*p>96?*p-32:*p)-48)&d[i+j]?c[j]:32)P(32)}P(10)}P(10)
}}

并且没有混淆:

#include <cstdio>

void out(const char* s)
{
    int i, j;
    const char* c = "|_|";
    unsigned d[9] = {0, 6947821, 0, 7209841, 7734140, 1180575, 8257861, 3933037, 1442811};
    for (i = 0; i < 9; i += 3) {
        for (const char* p = s; *p; ++p) {
            for (j = 0; j != 3; ++j)
                putchar(1 << ((*p > 96 ? *p - 32 : *p) - '0') & d[j + i] ? c[j] : ' ');
            putchar(' ');
        }
        putchar('\n');
    }
}

int main(int, char** argv)
{
    for (++argv;*argv;) {
        out(*argv++);
        putchar('\n');
    }
}

幻数指的是哪些字符有 _ 或 | 在特定的位置。例如,如果 0、3、5 和 'A' 都有 | 某处,数字将是1 << n('0') | 1 << n('3') | 1 << n('5') | 1 << n('A')- wheren(x)表示x - '0'。这假定至少 32 位整数,因为ASCII 图表之间'9'和之间有一个小的差距。'A'

最近编辑了这两个代码:使用一维数组而不是二维 (d),拥有非防错“ toupper”而不是包括 cctype,将所有内容移至 main,另一种循环命令行参数的方式,更精简的变量声明,魔术值而不是 char 常量和其他一些小的更改。

于 2009-09-10T21:31:02.743 回答
1

我的并不短,但这样做很有趣:

~ dlamblin$ ./7seg 31337aAbcdeF
 _     _  _  _  _  _     _     _  _ 
 _|  | _| _|  ||_||_||_ |   _||_ |_ 
 _|  | _| _|  || || ||_||_ |_||_ |  

#include <stdio.h>
#define P(x) fputs(x,stdout)
#define Z "\33[3D\33[B"
#define a "   " Z
#define s " _ " Z
#define d "  |" Z
#define f " _|" Z
#define g "|  " Z
#define h "| |" Z
#define j "|_ " Z
#define k "|_|" Z
int main(int argc, char** argv){
char m=0,n,*b[]={s h k,a d d,s f j,s f f,a k d,s j f,s j k,s d d,s k k,s k d,
"","","","","","","",
s k h,a j k,s g j,a f k,s j j,s j g};
P("\n\n\n\33[3A");
while (argc>1&&0!=(n=argv[1][m++])){
P(b[n>96?n-80:n-48]);P("\33[3A\33[3C");
}
P("\n\n\n");
}

您可以通过删除一些换行符来保存几个字符,但我不在乎。那是 500 个字符,如果去掉换行符,则为 482 个字符argc>1&&

需要 VT100 转义码支持,并且不会在 80 列终端上输出超过 26 个字符。

PS我希望看到更多的人展示他们的输出。

于 2009-09-10T23:09:45.363 回答
1

C# - 576 个字符(无换行符)

可能有更好的方法来做到这一点,但这是我的解决方案:

using C=System.Console;class Z{static void Main(){new Z();}int L=0;Z(){
try{var s=C.ReadLine().ToUpper();C.Clear();foreach(var c in s){int n=(
int)c;var p=(n==48?"_ ;| |;|_|":n==49?";  |;  |":n==50?"_; _|;|_":n==51
?"_; _|; _|":n==52?";|_|;  |":n==53?"_;|_; _|":n==54?"_;|_;|_|":n==55?
"_;  |;  |":n==56?"_;|_|;|_|":n==57?"_;|_|; _|":n==65?"_;|_|;| |":n==66
?";|_;|_|":n==67?"_;|;|_":n==68?"; _|;|_|":n==69?"_;|_;|_":n==70?"_;|_;|"
:";;").Split(';');P(0);C.Write(" "+p[0]);P(1);C.Write(p[1]);P(2);C.Write
(p[2]);L+=4;}C.WriteLine();}catch{}}void P(int t){C.SetCursorPosition(L,t);}}
于 2009-09-11T06:15:20.560 回答
1

Haskell,259 个字符。

Haskell 不适合打高尔夫球还是我(我的第一次打高尔夫球)?

import Char
i=iterate
d b=map(`mod`b).i(`div`b)
z _ 0=' '
z a 1=a
r=take 3
main=
  getLine>>=
  putStr.unlines.foldl1(zipWith(++)).
  map(r.map r.i(drop 3).take 9.zipWith z(cycle"|_|").(0:).d 2.
    (d 256(0xddfd91edcd9cd97990f5*2^384+0x2d6df865ecbd*(2^520+2^776))!!).ord)

(为了便于阅读,将主要内容分成几行)

于 2009-09-11T13:11:36.280 回答
1

打包时的 Javascript 333 个字符

s=" ";
function r(p)
{
if(t[p]=="0")
return s;
return "_|_||_|".split("")[p];
}
function g(w){
a="";b=a;c=a;
z=[];
for(x=0;x<w.length;x++){
t=("000"+parseInt("6F095E5B397377497F7B7D37661F7674".substr(parseInt(w.substr(x,1),16)*2,2),16).toString(2)).slice(-7).split("");
a+=s+r(0)+s+s;
b+=r(1)+r(2)+r(3)+s;
c+=r(4)+r(5)+r(6)+s;
}
return a+"\n"+b+"\n"+c;
}

alert(g("0123456789deadbeef"));
于 2009-10-13T15:00:15.433 回答
1

直流 - 172 个字符

有点晚了dc,但几乎符合规范:它只接受大写数字,即 [0-9A-F] 并且可能在开头打印额外的 0。无论如何,这里是:

16iD9B4FE55FFBDFFA5BF5BAB774977sK
[   ][ _ ][  |][ _|][|  ][|_ ][| |][|_|]8[1-ds_:al_d0<L]dsLx
?dsNZdsZ
40sr[[1-dlNr10r^/10%80r^lKr/80%lr/8%;aPd0<L]dsLxAP]dsAx
lZ8srlAxlZ1srlAx

一点解释(不需要换行):

常量 0xD9B4FE55FFBDFFA5BF5BAB774977 将每个数字编码为 7 位,例如数字 '4' 编码为 0 111 010,这意味着使用字符串 '0' 表示顶部(' '),字符串 7 表示中间(' |_|')和字符串 2对于底部(' |')。

第二行定义字符串并将它们存储在数组'a'中

第三行处理输入并检查数字的长度。

第四行进行计算。它创建了“子程序” A 并在第一行执行它。子程序1-dlNr10r^/10提取适当80r^lKr/80%的数字lr/8%;aPd0<L

最后一行对显示的第 2 行和第 3 行执行相同的操作。

于 2010-03-23T21:37:28.397 回答
1

斯卡拉,234 字节

val a=Seq("|_|"," _ ","  |","| |"," _|","|  ","|_ ","   ")
val m=argv(0).toLowerCase.map(_-'0').map(i=>if(i<10)i else i-39)
for(s<-Seq(0,16,32))
println(m.map(i=>a("171171111117171132440662000654660264240204306065"(i+s)-'0')).mkString)

代码非常简单:所有 9 个可能的段都打包到数组中,并在十六进制数和位置之间进行映射。也许,它可以包装得更好。

计算幻数的代码:

val s = " _     _ *all numbers in one line here* |_||_ |  "
val gl = (0 to s.size / 3-1).map(c => s.substring(c*3, c*3+3 ))
// gl now contains flat list of string of 3 chars each

val arr=gl.toSet.toArray   // remove duplicates

// for each segment string find corresponding packed index
val n = gl.map( arr indexOf _).mkString

结果,n 是幻数,arr 是字符串数组

于 2010-07-25T19:46:33.190 回答
1

Windows PowerShell,157

$i=[char[]]"$input"
'☺ ☺☺ ☺☺☺☺☺☺ ☺ ☺☺','♠☻♥♥♦♣♣☻♦♦♦♣•♥♣♣','♦☻♣♥☻♥♦☻♦♥♠♦♣♦♣•'|%{$c=$_
""+($i|%{('···0·_·0··|0·_|0|_|0|_·0|·|0|··'-split0)[$c[("0x$_"|iex)]]})}
于 2011-02-18T06:14:51.137 回答
0

用-Wall编译,可以看懂;不是很短(约 400 个字符)。在一个严肃的实现中,我会将 char->index 从输出部分中提取出来(并将索引存储在缓冲区而不是字符中)。全局 r 被初始化为 0,如果它是 main 中的局部变量则不会。

#include <stdio.h>
typedef char const* R;
R _=" _ ",S="   ",I="  |",J=" _|",L="|_ ",U="|_|",N="| |",C="|  ";
R s[][16]={
    {_,S,_,_,S,_,_,_,_,_,_,S,_,S,_,_},
    {N,I,J,J,U,L,L,I,U,U,U,L,C,J,L,L},
    {U,I,L,J,I,J,U,I,U,J,N,U,L,U,L,C}};
int r,c,i;
int main(){
    char b[999];
    scanf("%s",b);
    for(;r<3;++r)
        for(c=0;;) {
            i=b[c++]-'0';
            if (i>16) i-=7;
            if (i>15) i-=32;
            if (i<0||i>15){putchar('\n');break;}
            printf("%s",s[r][i]);
        }
    return 0;
}
于 2009-09-10T21:20:34.990 回答
0

Python 单行(322 个字符)

print(lambda l:(lambda s:'\n'.join([' '.join(x) for x in zip(*[l[c].split('\n')
for c in s])])))(dict(zip('0123456789abcdef', 'eJxdjrEBwDAIw3au0Ac9iUd0fJM2DTQD'
'g5ExJgkxTOMKYIzPDDUYORlNsZ3zppwuXsqt/pmmjVmZ\nH6M+9BTXZvU8Umg9fd03SOgvPw=='
.decode('base64').decode('zlib').split('\n/\n'))))(__import__('sys').argv[-1]
.lower())

大部分长度是由于我懒惰并使用 zlib 和 base64 内置函数来查找表。从命令行运行它,如下所示:

$ python golf.py fedcba9876543210
于 2009-09-11T00:55:10.270 回答
0

PHP,232 个字符

$d=str_split('    _ | ||_ |_| _|  ||  124066153155046135134166144145142034173054133137',3);
foreach(str_split(strtolower($s))as$c){
    $c=hexdec($c)+8;$r[0].=$d[$d[$c][0]];$r[1].=$d[$d[$c][1]];$r[2].=$d[$d[$c][2]];i
}
echo implode("\n",$r);

解释

# Array containing possible lines
$d=array(
    0 => '   ',
    1 => ' _ ',
    2 => '| |',
    3 => '|_ ',
    4 => '|_|',
    5 => ' _|',
    6 => '  |',
    7 => '|  '
);

# Array mapping characters to 3 lines
$m=array(
    0 => '124', # i.e. The character '0' is represented by $d[1], $d[2] and $d[4]
    1 => '066',
    2 => '153',
    3 => '155',
    4 => '046',
    5 => '135',
    6 => '134',
    7 => '166',
    8 => '144',
    9 => '145',
    a => '142',
    b => '034',
    c => '173',
    d => '054',
    e => '133',
    f => '137',
);

# traverse $s and append to array $r
foreach (str_split(strtolower($s)) as $c) {
    $r[0].=$d[$m[$c][0]];
    $r[1].=$d[$m[$c][1]];
    $r[2].=$d[$m[$c][2]];
}

# echo $r
echo implode("\n",$r);

优化:

  • 数组是使用动态生成的str_split()
  • 两个数组合并为一个
  • 字符使用数字映射hexdec()
于 2009-09-14T23:06:52.133 回答
0

JavaScript,309 304 字节。

要求不向字符串/数组添加原型函数。

function d(b){r="";o='î$º¶tÖÞ¤þöü^Ê>ÚØ'.split("");p=b.split(r);a=[" 0 ",
"132","465"];c="036";for(k in a){for(var e in p)for(var f in a[k])r+=(U=
a[k][f])==" "?" ":(y=((Q=o[parseInt(p[e],16)].charCodeAt().toString(2))
.length==6?"00"+Q:Q.length==7?0+Q:Q)[U])==0?" ":c.indexOf(U)>-1?"_":"|";
r+="\n"}return r}

测试用例(由于首先"标记字符串而格式化:

d("0123456789abcdef");

" _     _  _     _  _  _  _  _  _     _     _  _ 
| |  | _| _||_||_ |_   ||_||_||_||_ |   _||_ |_ 
|_|  ||_  _|  | _||_|  ||_| _|| ||_||_ |_||_ |  "
于 2011-03-19T18:59:44.970 回答