36 votes

Code De Golf: Sept Segments

Le défi

Le code plus court en nombre de caractères pour générer des sept segments d'affichage de la représentation d'un nombre hexadécimal.

Entrée

L'entrée est faite de chiffres [0-9] hexagonale et des caractères en minuscules et en majuscules [a-fA-F] seulement. Il n'est pas nécessaire de gérer des cas particuliers.

Sortie

La sortie sera le segment sept représentation de l'entrée, à l'aide de ces ASCII visages:

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

Restrictions

L'utilisation de ce qui suit est interdit: eval, exec, système de figlet, des toilettes et des bibliothèques externes.

Des cas de Test:

Input:
    deadbeef

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


Input:
    4F790D59

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

Code de comptage d'entrée/de sortie (j'.e programme complet).

30voto

strager Points 41713

C89 (181 caractères; 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 caractères; 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);}

Explication:

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

30voto

hobbs Points 71946

Perl, 134 caractères

Tous les retours à la ligne (peut être supprimé.

@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$/}

Explication

@s stocke les bits pour chaque segment. Les entrées sont dans l'ordre de 0 à F (grâce à l' hex()) et les bits de la carte de segments dans cet ordre:

6 7 x
3 4 5
0 1 2

avec 0 étant le bit de poids faible. (Bit 6 est inutilisée). Les valeurs sont stockées emballé dans la chaîne de bit inversé de sorte il ya beaucoup plus de caractères imprimables; l' ~ opérateur retourne les bits et les décompresser me donne les numéros (perl opérateurs au niveau du bit sont beaucoup plus maladroit quand il s'agit de chaînes de caractères).

Avec les données en main, j'ai lu la saisie et passer à la boucle de plus de trois fois; la seule différence entre les trois boucles est le masque de bits requis. Pour chaque caractère de l'entrée de trois caractères de sortie sont imprimés. Le caractère à imprimer est

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

@s est la table de recherche, $s le décalage en effet en fonction de la ligne, $_ est de savoir si nous sommes d'impression de la 1ère, 2ème, ou 3ème caractère de la ligne. Si le droit de bits dans la table de recherche d'entrée est faux, il imprime un espace; autrement, il imprime un "|" sur les côtés ou un "_" dans le milieu.

14voto

Skizz Points 30682

COM Exécutable: 102 octets

Assembler les éléments suivants à l'aide de l'A86 (c'est la version originale, la version plus grande):

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:

La DosBox question est sans doute la façon dont le programme suppose que les valeurs d'un registre au démarrage. De toute façon, voici la source modifié qui monte à 102 octets et devrait fonctionner avec 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

Grâce à ephemient pour un couple de réglages!

13voto

ephemient Points 87003

x86 (146 octets; args)

Inspiré par Jonas Gulle plus dans le Code de Golf: La vague. Habituellement, j'aurais écrit un Linux 32 bits ELFE, mais un DOS 16 bits COM est beaucoup plus courte instructions, zéro frais généraux).

46 instructions et 24 non exécutée mots. (Ils se détachent bien évidemment à la fin, n'est-ce pas?) Rien de difficile comme la réutilisation de code de données; il ne serait probablement pas enregistrer plus de 10 octets de toute façon.

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


La lettre-par-lettre de l'impression de la première ligne, puis la deuxième ligne, etc. à l'aide de 3 octets pour stocker les 9 bits de données pour chaque personnage. Évidemment il y a de la place pour l'amélioration... (C'est ma première fois à l'aide de MSNA de la syntaxe; je suis plus habitué à gaz , mais je n'arrivais pas à le convaincre pour une sortie binaire brut.)

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

6voto

IfLoop Points 59461

L'homme... ne pouvez pas battre le perl. Voici quelques py3k à 163 caractères.

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

L'explication. D'abord, voici à quoi il ressemblait complètement 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))

Puis-je aller sur la recherche de moyens pour emballer les données. D'abord je peux transformer a en un grand, entier long, dernier élément premier, 8 bits à la fois. Qui produit, en octal: 0o2645541764615736673577046675463463347404657. écrit en hexadécimal, c'est 0xb4b61fa637bdbbbf89b7b3399b9e09af, 90 caractères plus courte que la liste des octals. Pour l'utiliser vous devez réécrire le code, bien sûr. Qui ressemble à

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

b peuvent être concaténés, ''.join(b) est de 26 caractères, y compris les guillemets. la fonction de recherche doit également changer à l'appui de cette.

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

Ensuite, j'ai simplement éliminer tous les inutiles de la syntaxe par le pliage des fonctions et des constantes dans l'expression, et c'est assez bien.

Il est possible de serrer l'impression un peu, pas trop. Au lieu de rejoindre les lignes, il suffit d'imprimer immédiatement. il en résulte une modification de l' fmt():

def fmt_print(i):
    [print(''.join(lookup(d,l) for d in code(i))) for l in [0,1,2]]

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X