Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Code Golf: Code 39 Bar Code

J, 102 characters

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

Explanation. Read from the bottom up.:

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!

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

Hats-off to 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'

Only stores the 44 characters required and uses Ruby's transliteration function to map these

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

to the encoded values.


Python, 304 characters

No fancy Unicode compression. Only trick is to reorder the characters to maximize overlap. My first Python program.

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

Assembles to 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:

Not much scope for doing clever tricks here.


Python 3.1, without 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)

Explanation:

The code 39 sequence is encoded into a base-4 number (left-most = least significant) with:

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

The sequence is then sorted, e.g.

20333   Q
21233   N
21323   L
...

The difference of adjacent entries are taken, giving a list like [48, 12, 3, …]. Then 35 is added to this list to ensure the numbers fall in the ASCII range. This gives the "))&&&,…" string.

This code also has taken advantaged of the * will not appear in the input, so we may replace it by any invalid character, including '. In CPython repr("ABC") == "'ABC'", so we could get rid of 2 characters.


Python 3.1, with Unicode (154 158 chars)

Based on the J solution, taking advantage of the "The character # can be replaced with another character of higher density if wanted" rule, by defining density as area of dark parts divided by the smallest bounding rectangle of the glyph. :)

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 characters

Third go at the problem, still room for improvement. Character count by 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