Code Golf:Code 39条形码

时间:2010-05-10 02:54:48

标签: language-agnostic code-golf barcode rosetta-stone code39

挑战

按字符数排序的最短代码,用于绘制Code 39条形码的ASCII表示。

关于Code 39的维基百科文章:http://en.wikipedia.org/wiki/Code_39

输入

输入将是Code 39条形码的一系列合法字符。这意味着43个字符有效:0 - 9 A - Z (空格)和-.$/+%*字符不会出现在输入中,因为它用作开始和结束字符。

输出

Code 39条形码中编码的每个字符都有九个元素,五个条形和四个空格。条形将用#个字符表示,空格将用空格字符表示。九个元素中的三个将是广泛的。窄元素将是一个字符宽,宽元素将是三个字符宽。应在每个字符图案之间添加单个空格的字符间空格。应重复该模式,以使条形码的高度为八个字符高。

开始/停止字符*(bWbwBwBwb)将表示如下:

                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       #   # ### ### # 
                       ^ ^ ^^ ^ ^ ^ ^^^
                       | | || | | | |||
           narrow bar -+ | || | | | |||
           wide space ---+ || | | | |||
           narrow bar -----+| | | | |||
         narrow space ------+ | | | |||
             wide bar --------+ | | |||
         narrow space ----------+ | |||
             wide bar ------------+ |||
         narrow space --------------+||
           narrow bar ---------------+|
inter-character space ----------------+
  • 需要在条形码的开头和结尾输出开始和结束字符*
  • 条形码之前或之后不需要包含安静的空间。
  • 不需要计算校验位。
  • 不需要完整的ASCII Code39编码,只需标准的43个字符。
  • 无需在ASCII条形码表示下方打印文本以识别输出内容。
  • 如果需要,可以用另一个更高密度的字符替换字符#。使用完整的块字符U + 2588,将允许条形码在打印时实际扫描。

测试用例

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

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

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

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

10 个答案:

答案 0 :(得分:25)

J,102个字符

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

解释。从下往上阅读。:

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!

答案 1 :(得分:8)

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

向大卫致敬

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'

仅存储所需的44个字符,并使用Ruby的音译功能来映射这些

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

到编码值。

答案 2 :(得分:7)

Python,304个字符

没有花哨的Unicode压缩。唯一的技巧是重新排序字符以最大化重叠。我的第一个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)

答案 3 :(得分:6)

<强>汇编

汇编为220字节。

    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:

在这里做巧妙的技巧的范围不大。

答案 4 :(得分:5)

Python 3.1,没有Unicode(213 215 223 240 248 249 字符)

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)

说明:

将代码39序列编码为基数为4的数字(最左侧=最低有效数字),其中包含:

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

然后对序列进行分类,例如

20333   Q
21233   N
21323   L
...

获取相邻条目的差异,得到类似[48, 12, 3, …]的列表。然后将35添加到此列表中以确保数字落在ASCII范围内。这会给出"))&&&,…"字符串。

此代码也利用*不会出现在输入中,因此我们可能会将其替换为任何无效字符,包括'。在CPython repr("ABC") == "'ABC'"中,我们可以删除2个字符。

答案 5 :(得分:3)

Python 3.1,带有Unicode(154 158 chars)

基于J solution利用“如果需要”规则,可以用另一个更高密度的字符替换字符#,通过定义密度为暗部分的面积除以字形的最小边界矩形。 :)

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

答案 6 :(得分:2)

Python(2.6) - 430 312 302个字符

第三个问题,仍有改进的余地。字符数由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

答案 7 :(得分:1)

Lua,318个字符

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

我不希望用Lua赢得任何代码高尔夫问题,所以我不会在这里回答我自己的挑战。它也使用了我认为可能对其他人感兴趣的不同编码。

其他观察

仔细观察编码后,看起来似乎有办法省去了表格查找,并直接计算条形码的编码。但是,我发现我构建计算的尝试占用了比表更多的代码。 (在其他语言中可能不是这种情况。)

将角色划分为指示宽条和空格所在的组,我看到了一些有趣的模式。看起来40个字符只有一个宽的空间,$/+%是例外(它们各有三个空格。)40个字符在每个插槽中被拆分为10。并且,相同的40个字符有两个宽条。宽条似乎有二进制编码,最后一个条是奇偶校验位。条形图的位模式为1,2,3,4,5,6,8,9,10,12,避免设置超过2位的数字。

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

我想在另一天看是否可以在没有查找表的情况下编码条形码是一个挑战。

答案 8 :(得分:0)

我已经完成了在嵌入式系统上使用代码39条形码的代码。有两种类型的代码,我认为它们是39个“常规”代码和4个“古怪代码”。常规代码具有十种条形宽度(两种宽三种窄)中的一种,以及四种空间宽度图案中的一种(一种宽三种窄)。奇怪的球有五个窄条和四个条宽图案之一(三个宽一个窄)。要使用紧凑代码渲染条形码,请将字符转换为0-39(对于普通代码),或者对于“古怪代码”为40,50,60或70。然后是divmod 10.高位数将选择八种空间宽度模式中的一种;如果高位数为3或更小,则低位数将选择10种条形宽度图案中的一种。如果高位是4-7,则所有五个条都应该窄。

使用一些小的查找表,代码非常紧凑。因为查找表可以在源代码中紧凑地表示为字符串,所以具有较大查找表的方法可能具有较短的源代码(尽管我认为代码高尔夫源代码大小应该使用最有利的编码以字节计数;具有字符串的方法以UTF-8存储三个字节的奇数字符和UTF-16的两个字节应该为“奇数”字符“收费”3个字节,或者对于所有字符分别为两个字节,以较小的总数为准。使用完全适合某些特定单字节代码页的奇数字符选择的方法应该按字符收费一个字节。

答案 9 :(得分:-1)

垃圾邮件垃圾邮件垃圾邮件可爱垃圾邮件