Подтвердить что ты не робот

Code Golf: Семь сегментов

Задача

Самый короткий код по количеству символов, чтобы генерировать семисегментное представление отображения заданного шестнадцатеричного числа.

Ввод

Ввод производится из цифр [0-9] и шестнадцатеричных символов только в нижнем и верхнем регистре [a-fA-F]. Нет необходимости обрабатывать специальные случаи.

Выход

Выход будет семисегментным представлением ввода, используя эти грани ASCII:

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

Ограничения

Запрещается использовать следующее: eval, exec, system, figlet, туалет и внешние библиотеки.

Тестовые примеры:

Input:
    deadbeef

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


Input:
    4F790D59

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

Количество кодов включает ввод/вывод (т.е. полную программу).

4b9b3361

Ответ 1

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 - это сдвиг в зависимости от строки, а $_ - это то, печатаем ли я 1-го, 2-го или 3-го символов в строке. Если правый бит в записи таблицы поиска является ложным, он печатает пробел; иначе он печатает "|" по бокам или "_" посередине.

Ответ 2

C89 (181 символ, args)

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. */
}

Ответ 3

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

Edit:

Проблема 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

Благодаря многообещающе для пары настроек!

Ответ 4

x86 (146 bytes; args)

Вдохновленный Jonas Gulle в Code Golf: Волна. Обычно я пишу 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 deadbeef
    _  _        _  _  _ 
 _||_ |_| _||_ |_ |_ |_ 
|_||_ | ||_||_||_ |_ |  

Это просто по буквам печатает первую строку, вторую строку и т.д., используя 3 байта для хранения 9 бит данных для каждого символа. Очевидно, что комната для улучшения и hellip; (Это мой первый раз, используя NASM синтаксис, я больше привык к газ, но я не мог убедить его в выводе необработанного двоичного файла.)

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

Ответ 5

Человек... не может победить perl. Здесь несколько py3k на 163 символах.

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

Ответ 6

Ну, это сложно побить специализированный язык, такой как Perl. Однако здесь версия Python на 160 байт:

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

Ответ 7

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

И когда немного читаем...

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

Ответ 8

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?:[email protected]"[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?:[email protected]"[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" или "off". Если сегмент "on", выводится либо '|', либо '_', в зависимости от позиции. Если он выключен, выдается пробел. Массив символов - это массив бит, который определяет, включен или выключен каждый сегмент. Подробнее об этом после кода:

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?:[email protected]"[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 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 '|' или '_', в зависимости от позиции), а 0 означает, что сегмент "выключен" ".

В массиве требуется три символа для описания всей сетки для двух входных символов. Самые младшие три бита каждого символа в массиве, бит 0-2, описывают одну строку для четного входного символа этих двух. Следующие три бита, бит 3-5, описывают одну строку для нечетного входного символа этих двух. Биты 6 и 7 не используются. Эта компоновка со смещением +33 позволяет печатать каждый символ в массиве без escape-кодов или символов, отличных от ASCII.

Я играл с несколькими различными кодировками, включая посылку битов для всех 7 сегментов входного символа в один символ в массиве, но нашел, что это будет самым коротким. Хотя для этой схемы требуется 24 символа в массиве, чтобы представлять сегменты только из 16 входных символов, другие кодировки, требуемые с использованием символов, отличных от ASCII (что неудивительно вызвало проблемы, когда я использовал это в моем Морзе Code golf answer), много кодов выхода и/или сложный код декодирования. Код декодирования для этой схемы на удивление прост, хотя он в полной мере использует преимущество оператора C, чтобы избежать необходимости добавлять любые круглые скобки.

Позвольте разбить его на маленькие шаги, чтобы понять это.

"##3#3133X=W.<X/`^_G0?:[email protected]"

Это закодированный массив. Позвольте захватить соответствующий символ для декодирования.

[i*8

Первые 8 символов описывают верхнюю строку сегментов, а следующие 8 описывают среднюю строку сегментов, а последние 8 описывают нижнюю строку сегментов.

 +c/2]

Помните, что к этому моменту c содержит значение от 0 до 15, что соответствует вводу ABCDEF0123456789 и что массив кодирует два входных символа для кодированного символа. Таким образом, первый символ в массиве '#' содержит биты для верхней строки 'A' и 'B', второй символ, также '#', кодирует верхнюю строку 'C' и 'D', и т.д.

-33

Кодирование приводит к нескольким значениям, которые ниже 32, что потребует escape-кодов. Это смещение выводит каждый кодированный символ в диапазон печатных, неэкранированных символов.

>>

Оператор правого сдвига имеет более низкий приоритет, чем арифметические операторы, поэтому этот сдвиг выполняется для символа после вычитания смещения.

c%2*3

c%2 оценивается равным нулю для четных чисел, а для одного - для нечетных чисел, поэтому мы сдвигаем вправо на три для нечетных символов, чтобы получить бит 3-5, а не сдвигаться вообще для четных символов, предоставляя доступ к битам 0-2. Хотя я бы предпочел использовать c&1 для четной/нечетной проверки, и это то, что я использую везде, оператор & имеет слишком низкий приоритет для использования здесь без добавления скобок. Оператор % имеет только правильный приоритет.

+j

Сдвиньте дополнительные биты j, чтобы получить правильный бит для текущей выходной позиции.

&1

Побитовое и оператор имеет более низкий приоритет, чем как арифметические операторы, так и операторы сдвига, поэтому это будет проверять, установлен ли бит 0 после смещения, доведя соответствующий бит до нуля.

?

Если установлен бит 0...

"|_"

... вывести один из этих символов, выбранный...

[j&1]

... является ли наша переменная горизонтальной петли четной или нечетной.

:32

В противном случае (бит 0 не установлен), вывод 32 (символ пробела).


Я не думаю, что я могу урезать это намного больше, если таковое имеется, и, конечно, недостаточно, чтобы выполнить запись hobbs perl.

Ответ 9

Golfscript - 116 символов

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

Обязательно сохраните без дополнительной строки в конце, или строка ввода будет напечатана в конце.

{32:^|}%:
{^' _':[email protected]'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)

Ответ 10

Мой первый гольф для гольфа. 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')

Ответ 11

BrainF ***, 920 906 885 868 863 860 858 символов для цифровых часов

Я начал с этого (теперь закрытого) цифрового кода с тактовым кодом, поэтому: также поддерживается. Todo: обрабатывать строчные буквы.

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

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

Это сильно зависит от того, что платформа является 8-разрядной.

Ответ 12

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)

Ответ 13

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

Вывод:

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

Ответ 14

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();}}}

Ответ 15

С++, 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)
}}

И unobfuscated:

#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') - где n(x) означает x - '0'. Это предполагает как минимум 32-битные целые числа, так как в таблице ASCII имеется небольшой промежуток между '9' и 'A'.

Оба кода были отредактированы в последнее время: используйте одномерный массив вместо двумерного (d), собственный безошибочный "toupper" вместо включения cctype, переместил все в основной, другой способ перебора команды линейные аргументы, более сжатые объявления переменных, магические значения вместо констант char и несколько других незначительных изменений.

Ответ 16

Мина не короткая, но было весело:

~ 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 и не будет выводить более 26 символов на 80 столбцах.

PS Я бы хотел, чтобы больше людей показывали свои результаты.

Ответ 17

С# - 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);}}

Ответ 18

Haskell, 259 символов.

Неужели Хаскелл плохо для гольфа или это я (мой первый гольф)?

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)

(разделение основного на строки для удобочитаемости)

Ответ 19

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"));

Ответ 20

dc - 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), затем извлекает 7-битные данные кодирования (80r^lKr/80%), затем берет соответствующую часть для конкретной строки (lr/8%) загружает строку и печатает ее (;aP), то он перебирает все цифры (d0<L)

Последняя строка делает то же самое для строк 2 и 3. на дисплее.

Ответ 21

Scala, 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 - массив строк

Ответ 22

Windows PowerShell, 157

$i=[char[]]"$input"
'☺ ☺☺ ☺☺☺☺☺☺ ☺ ☺☺','♠☻♥♥♦♣♣☻♦♦♦♣•♥♣♣','♦☻♣♥☻♥♦☻♦♥♠♦♣♦♣•'|%{$c=$_
""+($i|%{('···0·_·0··|0·_|0|_|0|_·0|·|0|··'-split0)[$c[("0x$_"|iex)]]})}

Ответ 23

Компилирует с -Wall и может быть понят; не очень короткий (~ 400 символов). В серьезной реализации я вытащил индекс char → из выходной части (и сохранил индексы в буфере, а не в символах). Глобальный r инициализируется равным 0, что не будет, если оно будет локальным в основном.

#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;
}

Ответ 24

Однострочный 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

Ответ 25

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

Ответ 26

JavaScript, 309 304 байта.

Требуется, чтобы никакие функции-прототипы не добавлены в String/Array.

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");

" _     _  _     _  _  _  _  _  _     _     _  _ 
| |  | _| _||_||_ |_   ||_||_||_||_ |   _||_ |_ 
|_|  ||_  _|  | _||_|  ||_| _|| ||_||_ |_||_ |  "