Pergunta

O desafio

O código mais curto por contagem de caracteres para desenhar uma representação ASCII de um código de barras Código 39.

Artigo da Wikipedia sobre o código 39: http://en.wikipedia.org/wiki/code_39

Entrada

A entrada será uma sequência de caracteres legais para os códigos de barras do Código 39. Isso significa que 43 caracteres são válidos: 0-9 A-Z (espaço) e -.$/+%. o * O caractere não aparecerá na entrada, pois é usado como caracteres iniciantes e parados.

Resultado

Cada caractere codificado nos códigos de barras do código 39 tem nove elementos, cinco barras e quatro espaços. Barras serão representadas com # Personagens e espaços serão representados com o personagem espacial. Três dos nove elementos serão amplos. Os elementos estreitos terão um personagem largo e os elementos largos terão três caracteres de largura. Um espaço entre caracteres de um único espaço deve ser adicionado entre cada padrão de caractere. O padrão deve ser repetido para que a altura do código de barras tenha oito caracteres de altura.

O personagem de início/parada * (BWBWBWBWB) seria representado assim:

                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       ^ ^ ^^ ^ ^ ^ ^^^
                       | | || | | | |||
           narrow bar -+ | || | | | |||
           wide space ---+ || | | | |||
           narrow bar -----+| | | | |||
         narrow space ------+ | | | |||
             wide bar --------+ | | |||
         narrow space ----------+ | |||
             wide bar ------------+ |||
         narrow space --------------+||
           narrow bar ---------------+|
inter-character space ----------------+
  • O caráter de início e parada * precisará ser emitido no início e no final do código de barras.
  • Nenhum espaço tranquilo precisará ser incluído antes ou depois do código de barras.
  • Nenhum dígito de verificação precisará ser calculado.
  • A codificação completa do Code39 ASCII não é necessária, apenas os 43 caracteres padrão.
  • Nenhum texto precisa ser impresso abaixo da representação do código de barras ASCII para identificar o conteúdo da saída.
  • O personagem # pode ser substituído por outro caráter de densidade mais alta, se desejada. O uso do caractere de bloco completo U+2588 permitiria que o código de barras realmente digitalize quando impresso.

Casos de teste

Input:
ABC
Output:
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 
#   # ### ### # ### # #   # ### # ### #   # ### ### ### #   # # #   # ### ### # 

Input:
1/3
Output:
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 
#   # ### ### # ### #   # # ### #   #   # #   # ### ###   # # # #   # ### ### # 

Input:
- $     (minus space dollar)
Output:
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 
#   # ### ### # #   # # ### ### #   ### # ### # #   #   #   # # #   # ### ### # 

A contagem de códigos inclui entrada/saída (programa completo).

Foi útil?

Solução

J, 102 caracteres

8#,:' #'{~,0,.~#:(3 u:'䝝啕啕啕䑅儑啕啕啕啕䗝䔑啕䕷煝䑑凝瑗屗眕凗瑵屵具瑝屝啕啕啕啕啕啕啕甗崗睅圗病巅呷甝崝圝畇嵇睑均痑巑嗇畱嵱坱煗䝗燕䗗煵䝵'){~32-~a.i.'*'(,,[)

Explicação. Leia de baixo para cima:

8#,:         NB. Copy 8 times
' #'{~       NB. Turn binary 0 and 1 into space and #
,            NB. Link the array into a list
0,.~         NB. Append a 0 to the end of each row of the array.
#:           NB. Turn the list of numbers into a binary array where each row is the base-2 representation of the corresponding number
(3 u:'䝝啕啕啕䑅儑啕啕啕啕䗝䔑啕䕷煝䑑凝瑗屗眕凗瑵屵具瑝屝啕啕啕啕啕啕啕甗崗睅圗病巅呷甝崝圝畇嵇睑均痑巑嗇畱嵱坱煗䝗燕䗗煵䝵') NB. Turn this wchar string into a list of ints in range 0-65535.
{~           NB. Select numbers from the string-list whose indices are...
32-~         NB. ... 32 less than ...
a.i.         NB. ... the ascii values of ...
'*'(,,[)     NB. ... the input string with a '*' on either side!

Outras dicas

Ruby (1.9) - 121 132 141 166 170 289 295

Hats-off para David

puts"*#{$_}*
".tr(" --9*$+%A-Z","䝝䕷煝䑑凝瑗屗眕凗瑵屵具瑝屝䗝䑅䔑儑甗崗睅圗病巅呷甝崝圝畇嵇睑均痑巑嗇畱嵱坱煗䝗燕䗗煵䝵").gsub(/./){|c|c.ord.to_s(2).tr"01"," #"}*8


echo "ABC" | ruby -ne 'puts"*#{$_}*
".tr(" --9*$+%A-Z","䝝䕷煝䑑凝瑗屗眕凗瑵屵具瑝屝䗝䑅䔑儑甗崗睅圗病巅呷甝崝圝畇嵇睑均痑巑嗇畱嵱坱煗䝗燕䗗煵䝵").gsub(/./){|c|c.ord.to_s(2).tr"01"," #"}*8'

Apenas armazena os 44 caracteres necessários e usa a função de transliteração de Ruby para mapear esses

<space>
<-> to <9>
<*>
<$>
<+>
<%>
<A> to <Z>

para os valores codificados.

Python, 304 caracteres

Sem compactação de unicode sofisticada. O único truque é reordenar os caracteres para maximizar a sobreposição. Meu primeiro programa Python.

b="BWbwbwBwbWBwbwbwBWbwBwbwbWBwbwBwbWbwBwbwBWbwbwBWBwbwbwbWBwBwbwbWbwBwBwbWbwbwBwBWbwbwbwBWBwbWbWbWbwbWbWbWb"
s=t=""
for x in"*"+raw_input()+"*":
 i=".NI5VRD9YLH4 OB8XSE2?J6WKG0ZMA7*PC1-TF3UQ????$/+%".find(x)*2
 s+=b[i:i+9]+"w"
for x in s:t+=["#"," ","###","   "]["bwBW".find(x)]
for k in b[-8:]:print(t)

Assembler

Reúna para 220 bytes.

    mov di,ds
    mov al,42
    call a3
    mov dh,[80h]
    mov si,82h
 a1:lodsb
    call a3
    dec dh
    jnz a1
    mov al,42
    call a3
    mov ax,2573
    stosw
    mov al,36
    stosb
    mov cl,8
 a2:mov dx,ds
    mov ah,9
    int 21h
    loop a2
 a3:sub al,97
    cmp al,26
    ja a4
    sub al,32
 a4:mov bx,a6-3
 a8:add bx,3
    cmp bx,a7
    jae ret
    cmp al,[bx]
    jne a8
    mov bp,[bx+1]
 a5:rcr bp,1
    mov al,36
    sbb al,0
    and al,35
    stosb
    or bp,bp
    jnz a5
    mov al,32
    stosb
    ret
 a6:dd 0D05DC5CFh,01DD17517h,05477D275h,0D475C5D3h,01DD55717h,07745D657h,0D85D17D7h,057E05D1Dh
    dd 0745DE174h,0E35177E2h,0D7E47475h,051DDE551h,0E77715E6h,05DE85C57h,05C75E95Ch,0EB7157EAh
    dd 077EC715Dh,07175ED45h,0EF45D7EEh,0D5F045DDh,04757F171h,0F3475DF2h,047F44775h,07571F575h
    dd 0F755C7F6h,047F875D1h,05771F957h,0CD7751CCh,071BF5D47h,05111C35Dh,0CA4511CEh,045C44451h
    dd 05DD1C944h
 a7:

Não há muito espaço para fazer truques inteligentes aqui.

Python 3.1, sem unicode (213 215 223 240 248 249 chars)

o=""
for c in"%r"%input():
 u="W3YZ56C$EF. 89'0HIJM/OP+%RSTUV12X4ABD-7GKLNQ".find(c);n=sum(b"))&&&,(*&2&&&)),&/8(*&1)<&/V&&&)),&/5);D&/S"[u:])-930+35*u
 while n:o+="###"[n%2*2:]+"   "[n&2:];n>>=2
print((o+"\n")*8)

Explicação:

A sequência do código 39 é codificada em um número base-4 (mais esquerdo = menos significativo) com:

  • bw → 3
  • Bw → 2
  • bW → 1
  • BW → 0

A sequência é então classificada, por exemplo

20333   Q
21233   N
21323   L
...

A diferença de entradas adjacentes é realizada, dando uma lista como [48, 12, 3, …]. Então 35 é adicionado a esta lista para garantir que os números caam na faixa ASCII. Isso dá o "))&&&,…" corda.

Este código também levou a favor do * não aparecerá na entrada, então podemos substituí -la por qualquer caráter inválido, incluindo '. Em Cpython repr("ABC") == "'ABC'", para que pudéssemos nos livrar de 2 caracteres.

Python 3.1, com Unicode (154 158 chars)

Com base no J Solução, aproveitando o "O personagem # pode ser substituído por outro caráter de densidade superior se desejada " regra, definindo a densidade como área de partes escuras divididas pelo menor retângulo delimitado do glifo. :)

print((''.join(" #"[int(c)]for d in"%r"%input()for c in bin(2*ord("䝝啕啕啕䑅儑啕䗝啕啕啕䔑啕䕷煝䑑凝瑗屗眕凗瑵屵具瑝屝啕啕啕啕啕啕啕甗崗睅圗病巅呷甝崝圝畇嵇睑均痑巑嗇畱嵱坱煗䝗燕䗗煵䝵"[ord(d)-32]))[2:])+"\n")*8)

Python (2.6) - 430 312 302 caracteres

Terceiro, vá no problema, ainda espaço para melhorias. Contagem de personagens por wc -m.

#coding:UTF8
k=""
for c in"*%s*"%raw_input():
 i=" $*.02468BDFHJLNPRTVXZ%+-/13579ACEGIKMOQSUWY".find(c)*2
 for j in"%05d%s"%tuple(map(ord,u"ಊҺ௖ூ௄Һ姢ҺЈҺӎϴЈϴӐϲ刦ҺҺ௄ϴ௄Ҽூ划ಊϴಊҺЈϴЈҼІ划ӎϴӎಊϴ௄ϴಌϲІ௖ூ௖ூҼ௖І刦ϴ勮ϲ刨ϲІҼӎҺ划௄勚ூ刔ூϲಌҺಊ划Ј勚І刔ІϲӐҺӎ姢ϴ媪ϲ姤ϲ"[i:i+2])):k+=["#"," ","###","   "][int(j)]
 k+=" "
exec"print k;"*8

Lua, 318 caracteres

z={"1358ACEHKMORUWY.","UVWXYZ-. $/+*","2369BCFILMPSVWZ ","0123456789$/%","0456DEFJNOPTXYZ*","ABCDEFGHIJ$+%","0789GHIJQRST-. *","KLMNOPQRST/+%","1247ABDGKLNQUVX-",""}i="*"..(...).."*"o=""for c in i:gfind(".")do for j=1,10 do o=o..((j%2==0 and" "or"#"):rep(z[j]:find(c,1,true)and 3 or 1))end end for j=1,8 do print(o)end

Não espero ganhar perguntas de código-gol com Lua, por isso não me sinto mal ao responder ao meu próprio desafio aqui. Também estava usando uma codificação diferente, achei que poderia ser interessante para os outros.

Outras observações

Depois de olhar atentamente para a codificação, parece que pode haver uma maneira de dispensar a pesquisa da tabela e calcular a codificação do código de barras diretamente. No entanto, descobri que minhas tentativas de construir os cálculos obtiveram mais código do que a tabela. (Este pode não ser o caso em outros idiomas.)

Tendo dividido os personagens em grupos que indicavam onde estavam as barras e espaços largos, vi alguns padrões interessantes. Parece que há apenas um amplo espaço para 40 dos personagens, com $/+% sendo exceções (cada um deles tem três espaços.) Os 40 caracteres sendo divididos com 10 em cada slot. E existem duas barras largas para os mesmos 40 caracteres. As barras largas parecem ter uma codificação binária, com a última barra sendo um pouco de paridade. Os padrões de bits da barra são 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, onde os números com mais de 2 bits estão sendo evitados.

1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-._*
1 3 5  8  A C E  H  K M O  R  U W Y  .   1010100100
 23  6  9  BC  F  I  LM  P  S  VW  Z  _  0110010010
   456   0   DEF   J   NOP   T   XYZ   * 0001110001
      7890      GHIJ      QRST      -._* 0000001111
12 4  7   AB D  G   KL N  Q   UV X  -    1101001000 --> Parity

Eu acho que é um desafio para outro dia ver se os códigos de barras podem ser codificados sem tabelas de pesquisa.

Fiz o código para trabalhar com o código 39 códigos de barras em sistemas incorporados. Existem dois estilos de códigos, que eu penso como os 39 códigos "regulares" e os quatro "Oddballs". Os códigos regulares têm um dos dez padrões de largura de barra (dois três largos estreitos) e um dos quatro padrões de larguras espaciais (um três largos estreitos). Os Oddballs têm cinco barras estreitas e um dos quatro padrões de larguras de bar (três largos um estreito). Para renderizar um código de barras com código compacto, converta o caractere em um número 0-39 (para códigos normais) ou 40, 50, 60 ou 70 para "Oddballs". Em seguida, divmod 10. O dígito superior selecionará um dos oito padrões de larguras espaciais; Se o dígito superior for três ou menos, o dígito inferior selecionará um dos dez padrões de larguras da barra. Se o dígito superior for 4-7, todas as cinco barras devem ser estreitas.

O código funciona de maneira muito compacta usando algumas pequenas tabelas de pesquisa. Como as tabelas de pesquisa podem ser representadas de forma compacta como strings no código -fonte, abordagens com tabelas de pesquisa maiores podem ter um código -fonte mais curto (embora eu pense no código do código -fonte do Golf de código deve ser contado em bytes usando a codificação mais favorável; uma abordagem com uma sequência de uma sequência de Os personagens estranhos que levariam três bytes para armazenar no UTF-8 e dois bytes para UTF-16 deveriam ser 'carregados' 3 bytes cada um para personagens estranhos, ou dois bytes cada um para todos os personagens, o que produzir um total menor). Uma abordagem que usa uma seleção de caracteres estranhos que se encaixam inteiramente dentro de alguma página de código de byte de bytes específica deve ser cobrada um byte por caractere.

spam spam spam spam adorável spam

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top