代码之家  ›  专栏  ›  技术社区  ›  gwell

代码高尔夫:代码39条形码

  •  26
  • gwell  · 技术社区  · 7 年前

    挑战

    按字符计数绘制代码39条码的ascii表示形式的最短代码。

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

    输入

    输入将是代码39条码的合法字符字符串。这意味着43个字符有效: 0 - 9 A - Z (空间)和 -.$/+% . 这个 * 字符将不会出现在输入中,因为它用作开始和停止字符。

    产量

    代码39中编码的每个字符都有9个元素、5个条和4个空格。条形图将用 # 字符和空格将用空格字符表示。九行中有三行是宽的。窄元素宽一个字符,宽元素宽三个字符。每个字符模式之间应添加一个单独的字符间距。应重复该模式,使条形码的高度为八个字符高。

    开始/停止字符 * (BWBWBWB)的代表如下:

                           #   # ### ### # 
                           #   # ### ### # 
                           #   # ### ### # 
                           #   # ### ### # 
                           #   # ### ### # 
                           #   # ### ### # 
                           #   # ### ### # 
                           #   # ### ### # 
                           ^ ^ ^^ ^ ^ ^ ^^^
                           | | || | | | |||
               narrow bar -+ | || | | | |||
               wide space ---+ || | | | |||
               narrow bar -----+| | | | |||
             narrow space ------+ | | | |||
                 wide bar --------+ | | |||
             narrow space ----------+ | |||
                 wide bar ------------+ |||
             narrow space --------------+||
               narrow bar ---------------+|
    inter-character space ----------------+
    
    • 起止符 * 需要在条形码的开始和结束处输出。
    • 条形码前后不需要有安静的空间。
    • 无需计算校验位。
    • 不需要完整的ascii码39编码,只需要标准的43个字符。
    • 不需要在ascii条码表示下面打印文本来标识输出内容。
    • 角色 γ 如果需要,可以用另一个更高密度的字符替换。使用完整的块字符u+2588,将允许条码在打印时实际扫描。

    测试用例

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

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

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

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

    10 回复  |  直到 7 年前
        1
  •  25
  •   David    16 年前

    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!
    
        2
  •  8
  •   Anurag    16 年前

    红宝石(1.9)-121 一百三十二 一百四十一 一百六十六 一百七十 二百八十九 二百九十五

    向大卫致敬

    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>
    

    到编码的值。

        3
  •  7
  •   xan    16 年前

    蟒蛇,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)
    
        4
  •  6
  •   Imran    16 年前

    汇编程序

    汇编到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:
    

    在这里做聪明的把戏的余地不大。

        5
  •  5
  •   KennyTM    16 年前

    python 3.1,不带unicode(213 二百一十五 二百二十三 二百四十 二百四十八 二百四十九 字符)

    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'" ,所以我们可以去掉两个字符。

        6
  •  3
  •   KennyTM    9 年前

    python 3.1,使用unicode(154 一百五十八 字符)

    基于 J solution , 利用 “角色 # 如果需要,可以用另一个更高密度的字符替换” 通过将密度定义为 深色部分的面积除以字形的最小边框 . :)

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

    巨蟒(2.6)-- 四百三十 三百一十二 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
    
        8
  •  1
  •   gwell    16 年前

    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
    

    我想这是一个挑战,为另一天看看条码是否可以编码没有查表。

        9
  •  0
  •   supercat    16 年前

    我在嵌入式系统上用代码39来处理条码。有两种类型的代码,我认为是39个“常规”代码和四个“怪胎”。常规代码有10种条形宽度模式(2宽3窄)和4种空间宽度模式(1宽3窄)中的一种。这些怪胎有五个窄杆和四种杆宽模式之一(三宽一窄)。要使用压缩代码呈现条形码,请将字符转换为数字0-39(对于普通代码),或40、50、60或70(对于“古怪的代码”)。然后Divmod 10.上面的数字将选择八种宽度模式中的一种;如果上面的数字是三种或更少,下面的数字将选择十种宽度模式中的一种。如果上面的数字是4-7,那么所有的五个条都应该是窄的。

    代码使用几个小的查找表非常紧凑。因为在源代码中,查找表可以被紧凑地表示为字符串,所以具有较大查找表的方法可能具有较短的源代码(尽管我认为对于代码来说,golf源代码的大小应该使用最有利的编码以字节为单位进行计算;具有一系列奇怪字符的方法用utf-8存储需要3个字节,utf-16存储需要2个字节,对于古怪的字符,每个字节应该“充电”3个字节,对于所有字符,每个字节应该“充电”2个字节,以总数较小的为准)。一种使用完全适合某个特定单字节代码页的古怪字符选择的方法,应该对每个字符收取一个字节的费用。

        10
  •  -1
  •   2 revs, 2 users 65%<br/>veda300&#13;    15 年前

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

    推荐文章