Mã hóa mã 39


16

Viết hàm hoặc chương trình mã hóa một chuỗi thành mã vạch định dạng Mã 39 , trong đó mỗi ký tự được mã hóa thành năm thanh cách nhau bởi bốn khoảng trống. Một trong hai thanh và một trong các khoảng trống là rộng và các khoảng trống khác là hẹp (10 * 4 mã) hoặc ba trong số các khoảng trống rộng và không có thanh nào là (4 mã). Điều này cung cấp 44 mã khác nhau, từ đó một mã là mã dành riêng được sử dụng để biểu thị điểm bắt đầu và kết thúc của chuỗi được mã hóa.

Các thách thức

Đầu vào là một chuỗi chỉ chứa các ký tự từ tập hợp

1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-. +/$%

Đầu ra là chuỗi được mã hóa dưới dạng chuỗi mã vạch. Khoảng cách hẹp và khoảng cách giữa các vi khuẩn là một không gian duy nhất và một khoảng cách rộng là ba không gian. Thanh hẹp là chuỗi byte UTF-8 cho ký tự Unicode "Khối đầy đủ",, 0xE2 0x96 0x88và thanh rộng là ba chuỗi / ký tự byte như vậy ( ███). Danh sách đầy đủ các mã là:

      Spaces
      0100 0010 0001 1000 1011 1101 1110 0111
Bars
00000                       +    /    $   %
10001   1    A    K    U
01001   2    B    L    V
11000   3    C    M    W
00101   4    D    N    X
10100   5    E    O    Y
01100   6    F    P    Z
00011   7    G    Q    -
10010   8    H    R    .
01010   9    I    S  space          1=wide
00110   0    J    T  start/end      0=narrow

Các thanh và không gian được xen kẽ, bắt đầu từ một thanh, vì vậy, ví dụ Q là

bar   0 0 0  1     1 
code  █ █ █ ███   ███
space  0 0 0    1

Sau khi mã hóa tất cả các ký tự, chuỗi được phân tách ở cả hai đầu bằng █ █ ███ ███ █. Khoảng cách giữa các vi khuẩn, một khoảng trống, được chèn vào giữa mỗi chữ cái. Giải pháp của bạn có thể xuất ra các khoảng trắng ở cuối và một dòng mới (theo thứ tự đó).

Ví dụ

""     → "█   █ ███ ███ █ █   █ ███ ███ █"

"A"    → "█   █ ███ ███ █ ███ █ █   █ ███ █   █ ███ ███ █"

"C++"  → "█   █ ███ ███ █ ███ ███ █   █ █ █   █ █   █   █ █   █ █   █   █ █   █ ███ ███ █"

"GOLF" → "█   █ ███ ███ █ █ █ █   ███ ███ ███ █ ███ █   █ █ ███ █ █   ███ █ ███ ███   █ █ █   █ ███ ███ █"

Các định dạng đầu vào / đầu ra tiêu chuẩn được cho phép và các sơ hở tiêu chuẩn không được phép. Đây là , vì vậy mã ngắn nhất được đo bằng byte sẽ thắng!


1
Chúng tôi có thể sử dụng ký tự ASCII có thể in được không (bạn có thể chọn ký tự nào cho phép) thay vì █?
Erik the Outgolfer

Đối với ngôn ngữ như BrainFuck, cái gì được tính là "một lần sử dụng"?
l4m2

1
@Angs Ý tôi là về đầu ra về cơ bản, không phải trong mã. Thật không công bằng khi đưa ra hình phạt cho việc sử dụng #nhân vật, vì, chẳng hạn, "#"không phải là lý do duy nhất nó có thể được sử dụng trong ngôn ngữ.
Erik the Outgolfer

@EriktheOutgolfer Ý tôi là ở dạng chuỗi ký tự và tương tự, nhưng xem xét điểm của l4m2 có lẽ tốt nhất là không cho phép nó. Rốt cuộc, có ngôn ngữ nào không thể xuất ba byte không?
Angs

Câu trả lời:


7

JavaScript (ES6), 225 212 byte

Đã lưu 4 byte nhờ @ l4m2

s=>`#${s}#`.replace(/./g,c=>'0202020202'.replace(/./g,(j,k)=>[C='█',C+C+C,' ','   '][(i="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT".indexOf(c),[170,257,260,5,272,17,20,320,65,68,80][i>>2]^2<<i%4*2)>>k&1|j]))

Hãy thử trực tuyến!

Làm sao?

Bảng có thể được sắp xếp lại sao cho mặt nạ nhị phân 9 bit của ký tự nhanh chóng được suy ra từ hàng và cột của nó bằng công thức sau:

n = m XOR (2 << k)

với:

  m  | k: 0   2   4   6
-----+------------------      Examples:
 170 |    %   +   /   $
 257 |    U   1   A   K         'G' = 320 XOR (2 << 4) = 320 XOR 32 = 352
 260 |    V   2   B   L
   5 |    W   3   C   M         '+' = 170 XOR (2 << 2) = 170 XOR 8  = 162
 272 |    X   4   D   N
  17 |    Y   5   E   O
  20 |    Z   6   F   P
 320 |    -   7   G   Q
  65 |    .   8   H   R
  68 |   spc  9   I   S
  80 |    #   0   J   T

s=>`#${s}#`.replace(/./g,c=>'0202020202'.replace(/./g,(j,k)=>[C='#',C+C+C,' ',' '][(i="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT".indexOf(c),[,257,260,5,272,17,20,320,65,68,80][i>>2]|(2<<i%4*2^(i<4)*170))>>k&1|j]))(221)
l4m2

@ l4m2 Điều đó dường như không hợp lệ. Tuy nhiên, tôi đã quản lý để tìm một bản sửa lỗi cho 221 byte .
Erik the Outgolfer

@EriktheOutgolfer Tôi nghĩ rằng về cơ bản những gì l4m2 đã gửi với một khối đầy đủ thay vì '#'. Hay tôi đang thiếu một cái gì đó?
Arnauld

@Arnauld Bản gốc của họ không có không gian đúng.
Erik the Outgolfer

3

Màu đỏ , 452 445 byte

func[s][q: func[x y z][append/dup x y z]append insert s"*""*"b:
func[n][v: copy[]until[append v n % 2 * 2 + 1
1 > n: n / 2]q v 1 5 - length? v
reverse v]a: q":1234567890:ABCDEFGHIJ:KLMNOPQRST:UVWXYZ-. *"" "44
a/45: #"+"a/56: #"/"a/67: #"$"a/78: #"%"foreach t s[i: index? find a t
k: b pick[0 17 9 24 5 20 12 3 18 10 6]either 0 = j: i % 11[11][j]m:
b pick[8 4 2 16 22 26 28 14]i - 1 / 11 + 1 z: copy""repeat n 5[q z"█"k/(n)
q z" "m/(n)]prin z]]

Hãy thử trực tuyến!

Tôi sẽ cố gắng chơi gôn hơn nữa, nhưng tôi không mong đợi nhiều từ giải pháp ngây thơ này.


2

Java 10, 455 byte

s->{String r="",R=r;for(var c:("~"+s+"~").split(""))r+=r.format("%9s",Long.toString(new int[]{148,289,97,352,49,304,112,37,292,100,52,265,73,328,25,280,88,13,268,76,28,259,67,322,19,274,82,7,262,70,22,385,193,448,145,400,208,133,388,196,138,162,168,42}["~1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-. +/$%".indexOf(c)],2)).replace(' ','0');for(int l=r.length(),i=0,c;i<l;R+=""+(i%9%2<1?c<49?"█":"███":c<49?" ":"   ")+(i%9>7&++i<l?" ":""))c=r.charAt(i);return R;}

Hãy thử trực tuyến.

Giải trình:

s->{                     // Method with String as both parameter and return-type
  String r="",           //  Temp-String, staring empty
         R=r;            //  Result-String, starting empty as well
  for(var c:("~"+s+"~")  //  Prepend and append "~" to the input
            .split(""))  //  And loop over each character
    r+=r.format("%9s",Long.toString( 
                         //   Convert the following integer to a 9-bit binary String:
       new int[]{148,289,97,352,49,304,112,37,292,100,52,
                 265,73,328,25,280,88,13,268,76,28,259,67,322,
                 19,274,82,7,262,70,22,385,193,448,145,400,208,
                 133,388,196,138,162,168,42}
                         //    Array containing all decimal values of the binary Strings
       ["~1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ-. +/$%".indexOf(c)]
                         //    with the index based on the current character
   ,2)).replace(' ','0');
                         //   (also part of the integer to 9-bit binary String conversion)
  for(int l=r.length(),i=0,c;i<l;
                         //  Loop `i` over the temp-String
      R+=                //    After every iteration: append the following to the result:
         ""+(i%9%2<1?    //     If `i` modulo-9 modulo-2 is 0:
              c<49?      //      And `c` is '0':
               "█"       //       Append a single block
              :          //      Else:
               "███"     //       Append three blocks
             :c<49?      //     Else-if `c` is '0':
              " "        //      Append a single space
             :           //     Else:
              "   ")     //      Append three spaces
         +(i%9>7         //     If `i` modulo-9 is 8,
           &++i<l?       //     and this is not the very last character
            " "          //      Append a space delimiter
           :             //     Else:
            ""))         //      Append nothing more
    c=r.charAt(i);       //   Set `c` to the current character in `r`
  return R;}             //  Return the result

2

C (gcc) , 311 , 303 byte

(*P)()=printf;i;j;w;m[]={170,257,260,5,272,17,20,320,65,68,80};char*b=" \0\xE2\x96\x88",*t="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT",*c;p(x){j=256;w=2;while(j){P(b+w);if(x&1){P(b+w);P(b+w);}x/=2;j>>=1;w=2*!w;}P(" ");}f(char*_){p(82);for(c=_;*c;c++){i=strchr(t,*c)-t;p(m[i>>2]^(2<<(i&3)*2));}p(82);}

Hãy thử trực tuyến!

-8 nhờ trần

Sử dụng chiến lược mã hóa từ câu trả lời của Arnauld. Liên kết TIO bao gồm -wchuyển đổi và soạn sẵn để loại bỏ các cảnh báo, những điều này là không cần thiết và do đó không được bao gồm trong điểm số.

Ngoài sơ đồ mã hóa như Arnauld đã giải thích, mẹo khác ở đây là duy trì wbiến khi chuyển đổi giữa 2 và 0 ( w=2*!w). Điều này cho phép tôi chọn giữa chuỗi thứ nhất và thứ hai trong b. Đầu tiên là một không gian, thứ hai là hình chữ nhật đầy.


thông minh, bạn nên đăng nó :)
LambdaBeta

2

C (gcc) , 241 239 227 213 207 byte

#define P printf(i%2?" ":"█")
i;p(x){for(i=9;i--;x/=2)P,x&1&&P+P;P;}f(char*_){p(82);for(char*t="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT";*_;p(L"ªāĄ\5Đ\21\24ŀADP"[i/4]^2<<i%4*2))i=index(t,*_++)-t;p(82);}

Hãy thử trực tuyến!

Dựa trên triển khai của @ LambdaBeta .

Hơi ít chơi golf:

#define P printf(i%2?" ":"█")
i;
p(x){
 for(i=9;i--;x/=2)
  P,
  x&1&&
   P+
   P;
 P;
}
f(char*_){
 p(82);
 for(char*t="%+/$U1AKV2BLW3CMX4DNY5EOZ6FP-7GQ.8HR 9IS#0JT";*_;p(L"ªāĄ\5Đ\21\24ŀADP"[i/4]^2<<i%4*2))
  i=index(t,*_++)-t;
 p(82);
}

1

Than , 90 byte

⪫EE⪫**S⌕⁺⁺⭆…αχ﹪⊕μχα-. *+/$%ι⪫E⁵⁺⎇μ× ∨⁼›ι³⁹⁼²﹪⁻÷ι∨›ι³⁹χμ⁴¦³ω×█∨›ι³⁹∨§↨℅§.6':+3<-59ι²⊕μ³ω 

Hãy thử trực tuyến! Lưu ý: Không gian lưu trữ. Liên kết là phiên bản dài dòng của mã. Giải trình:

⪫EE⪫**S...⪫E⁵⁺...ω 

Quấn chuỗi đầu vào theo *s và sau đó ánh xạ qua chuỗi đó hai lần, cuối cùng nối kết quả với khoảng trắng. Đối với bản đồ thứ hai, sau đó có một bản đồ bổ sung trong phạm vi ẩn 0..4, trong đó hai chuỗi con được nối với nhau và các kết quả đó sau đó được nối với hằng số chuỗi rỗng được xác định trước.

⌕⁺⁺⭆…αχ﹪⊕μχα-. *+/$%ι

Đối với bản đồ bên trong đầu tiên, hãy tạo một chuỗi được hình thành bằng cách lấy các chữ số tăng dần, bảng chữ cái viết hoa và các ký hiệu -. *+/$%và tìm kiếm vị trí của ký tự đầu vào được ánh xạ. Ví dụ, C++sẽ ánh xạ tới [12, 40, 40].

⎇μ× ∨⁼›ι³⁹⁼²﹪⁻÷ι∨›ι³⁹χμ⁴¦³ω

Chuỗi con đầu tiên đại diện cho khoảng trắng trước các thanh. Không có gì trước thanh đầu tiên, nhưng các thanh khác phụ thuộc vào vị trí của ký tự đầu vào được ánh xạ: nếu trên 39, thì chỉ một nơi có một khoảng trắng, trong khi nếu dưới 40, thì chỉ một nơi có ba khoảng trắng và vị trí cũng được chuyển đổi thành một cột bằng cách chia nó cho 10. Nếu cột và chỉ số vòng lặp khác nhau 2 (modulo 4) thì đó là vị trí lẻ.

×█∨›ι³⁹∨§↨℅§.6':+3<-59ι²⊕μ³

Chuỗi con thứ hai đại diện cho các thanh. Nếu vị trí trên 39 thì luôn có một thanh nếu không vị trí được tra cứu trong một mảng các bit được ánh xạ tới các ký tự. Chẳng hạn, nếu vị trí là 12, thì được lập chỉ mục tròn cho ký tự ', 100111ở dạng nhị phân, biểu thị các thanh rộng trong cột 1 và 2. (Phần đầu 1bị bỏ qua, nó chỉ đơn giản đảm bảo số bit nhất quán.)


1

Perl 5 , 244 byte

$l="{ ,   ,...,.........}"x9;@h{$",qw($ % + - . /),0..9,'',A..Z}=(<"$l">)[q{..=9...Z.>>...J=9..j.%r1...=).[.>=-..Ux?V.^=8.>.6o+ax_.=(..B=,..Yx6..b=(..#r'p.^...G.<=,..Sx5B.\=(.V.It..z:..-z.=<6.}=~s/./ord$&/gre=~/.{6}/g];s/^|./$h{$&} /g;$\=$h{''}

Hãy thử trực tuyến!

Chứa nhiều ký tự không thể in và ký tự byte cao, liên kết TIO cung cấp một xxdđại diện. Tôi hy vọng điều này sẽ kết thúc nhỏ hơn và tôi vẫn có thể đóng gói dữ liệu theo cách hiệu quả hơn để tôi thấy tôi đi như thế nào. Điều này xây dựng tất cả các hoán vị " "," ","█","███"và sau đó ánh xạ các chỉ dẫn của danh sách đến các ký tự tương ứng.


1

Haskell , 275 270 byte

z=0:z
x!0=[]
x!n=mod n x:x!div n x
e c|Just a<-lookup c.zip"W3YZ56C$EF. 89*HM/ORU1QGNTDJ7%40LSBIP2-+XVKA".((++)<*>(reverse<$>))$take 9.(++z).(2!)<$>scanl(+)7(67!0x117CDBC49F9EEEF11C3A659CACB31236)=zipWith(\l c->c<$[1..2*l+1])(a++[0])(cycle"█ ")>>=id
f s='*':s++"*">>=e

Hãy thử trực tuyến!

Toán tử x!ntính toán các chữ số cơ sở x của n, được sử dụng hai lần để giải nén mã. Các mã được nén đầu tiên dưới dạng các chuỗi nhị phân có wide = 1 và hẹp = 0, không liên quan đến màu sắc, ví dụ R↔10000110↔262. Các số này sau đó được sắp xếp và phân biệt để lấy các số trong phạm vi [3,66], được nén với thuật toán ngược lại với thuật toán chữ số nhị phân như 0x117CDBC49F9EEEF11C3A659CACB31236. Điều này chỉ chứa một nửa mã, phần còn lại là đảo ngược của các mã này.

Ung dung:

z=0:z                       -- infinite zeroes for padding
x!0=[]                      -- digits of n in base x, recursion base case
x!n=mod n x:x!div n x       -- digits of n in base x
e c | Just a                -- read upwards from (*)
  <-lookup c                -- lookup code, given letter
  . zip"W3YZ56C$EF. 89*HM/ORU1QGNTDJ7%40LSBIP2-+XVKA" 
                            -- combine codes with correct letters
  . ((++)<*>(reverse<$>))   -- concatenate list and list with reverse codes
  $ take 9                  -- take nine
  . (++z)                   -- pad with infinite zeroes on right
  . (2!)                    -- convert to binary digits – [[1,1,1],[1,0,1,1]…]
  <$> scanl (+) 7           -- cumulative sum starting from 7 – [7,13,19,22,25…]
        (67!0x117CDBC49F9EEEF11C3A659CACB31236)       
                            -- (*) digits in base 67 – [6,6,3,3,3,9,5,7…]
  = zipWith
      (\l c->c<$[1..2*l+1]) -- combine width and color, length is 2*l+1
      (a++[0])              -- list of widths as 0/1, 0 added for interchar gap
      (cycle"█ ")           -- infinite list of bar colors, leftovers are unused
  >>=id                     -- concatenate
f s='*':s++"*">>=e          -- surround string with delimiters, map e and concat
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.