Barcodegolf: Tạo UPC của một số


12

Ngày nay, mọi cửa hàng đều sử dụng mã vạch Mã sản phẩm chung (UPC) để đơn giản hóa quy trình kiểm tra. Nếu tên không có ý nghĩa gì với bạn, bạn chắc chắn sẽ nhận ra chúng trông như thế nào:

Mẫu mã vạch UPC-A

định dạng

Hệ thống phổ biến nhất là UPC-A, sử dụng 12 chữ số để thể hiện từng sản phẩm cụ thể. Mỗi chữ số được mã hóa thành một chuỗi các sọc đen trắng để cho phép các máy đọc mã, độ dài bảy bit. Có tổng số các mẫu có giá trị 11 bit chỉ ra phần đầu, phần giữa và phần cuối của mã vạch. Điều này có tổng chiều dài mã vạch là 12 × 7 + 11 = 95 bit. (Từ bây giờ, khi nhị phân được sử dụng để chỉ màu của mỗi bit, 0là màu trắng và 1màu đen.)

Bắt đầu và kết thúc cả hai có một mô hình 101. Các chữ số sau đó được chia thành 2 nhóm 6 và được mã hóa như hình bên dưới, với một mẫu 01010giữa các nhóm bên trái và bên phải. Bảng này liệt kê các mẫu cho mỗi số. Lưu ý rằng mẫu khác nhau tùy thuộc vào chữ số ở bên phải hay bên trái (Điều này cho phép quét mã vạch lộn ngược). Tuy nhiên, mẫu cho bên phải là ngược lại (hoán đổi màu đen cho màu trắng và ngược lại) của mẫu bên trái.

Bảng chuyển đổi UPC

Nếu bạn không thể nhìn thấy hình ảnh ở trên, đây là tương đương nhị phân của mỗi số.

#   Left    Right
0   0001101 1110010
1   0011001 1100110
2   0010011 1101100
3   0111101 1000010
4   0100011 1011100
5   0110001 1001110
6   0101111 1010000
7   0111011 1000100
8   0110111 1001000
9   0001011 1110100

Thí dụ

Nói rằng bạn có UPC 022000 125033. (Đó không phải là số ngẫu nhiên. Hãy để lại nhận xét nếu bạn nhận ra tầm quan trọng của chúng.) Bạn bắt đầu với bản tóm tắt này giống nhau trong mỗi mã vạch:

101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx101

Đối với các chữ số, bạn thay thế từng chữ số bằng mã hóa tương ứng cho mặt bên (bên trái hoặc bên phải). Nếu bạn vẫn còn bối rối, hãy xem hình ảnh dưới đây.

Sự cố mã hóa UPC

Đây là đầu ra trong nhị phân với các |ống ngăn cách các bộ phận.

101|0001101|0010011|0010011|0001101|0001101|0001101|01010|1100110|1101100|1001110|1110010|1000010|1000010|101

Thử thách

Viết chương trình xuất mã vạch UPC-A cho đầu vào của người dùng. Kích thước của hình ảnh phải là 95 × 30 pixel, với mỗi "bit" rộng một pixel và cao 30 pixel. Các sọc đen nằm trong rgb(0, 0, 0)và các sọc trắng luôn trong suốt hoặc rgb(255, 255, 255).

Ghi chú

  • Lấy đầu vào từ stdin hoặc dòng lệnh hoặc viết hàm lấy chuỗi hoặc số nguyên (lưu ý rằng đầu vào có thể có các số 0 đứng đầu và hầu hết các ngôn ngữ sẽ loại bỏ chúng hoặc chuyển đổi số thành bát phân).
  • Xuất hình ảnh theo một trong các cách sau:
    • Lưu nó vào một tệp có tên và định dạng (PNG, PBM, v.v.) mà bạn chọn.
    • Hiển thị nó trên màn hình.
    • Xuất dữ liệu tệp của nó ra thiết bị xuất chuẩn.
  • Bạn không được sử dụng các thư viện hoặc nội dung tạo mã vạch ( Tôi đang nhìn vào bạn, Mathicala ), mặc dù bạn có thể sử dụng các thư viện hình ảnh hoặc đồ họa.
  • Chữ số cuối cùng của UPC thường là chữ số kiểm tra , nhưng với những mục đích này, bạn không phải lo lắng về nó.

Ví dụ

Dưới đây là một số ví dụ khác để kiểm tra mã của bạn với. Đầu ra nhị phân cũng được đưa ra để thuận tiện.

Đầu vào: 012345678910

Đầu ra:

10100011010011001001001101111010100011011000101010101000010001001001000111010011001101110010101

Đầu vào: 777777222222

Đầu ra:

10101110110111011011101101110110111011011101101010110110011011001101100110110011011001101100101

Chấm điểm

Đây là mã golf , vì vậy bài nộp ngắn nhất (tính bằng byte thắng). Tiebreaker đi đến bài viết sớm nhất.


Mmm ... trái cây ngon ngọt.
Dennis

Đầu vào có thể được thực hiện trong một mảng? ví dụ["777777","222222"]
Downgoat

@vihan Hmm, tôi nghĩ đó là một chút căng. Tôi sẽ nói không.
NinjaBearMonkey

2
Quét mã vạch UPC đầu tiên bao giờ hết!
Dennis

1
Điều này thật tuyệt vời. Mã vạch luôn mê hoặc tôi
Beta Decay

Câu trả lời:


3

CJam, 58 57 byte

'P1N95S30N[A1r:~"rflB\NPDHt":i2fbf=:R6<::!0AAR6>A1]s30*S*

In một BitMap di động (ASCII) sang STDOUT. Hãy thử trực tuyến.

Làm thế nào nó hoạt động

'P1N95S30N     e# Push 'P', 1, '\n', 95, ' ', 30 and '\n'.

[              e#
  A1           e#   Push 10 and 1.
  r            e#   Read a token from STDIN.
  :~           e#   Caluate each character ('0' -> 0).
  "rflB\NPDHt" e#   Push that string.
  :i           e#   Cast each character to integer.
               e#   This pushes [114 102 108 66 92 78 80 68 72 116].
  2fb          e#   Convert each integer to base 2.
               e#   This pushes the representations for the right side.
  f=           e#   Select the proper representation of each digit in the input.
  :R           e#   Save the result in R.
  6<           e#   Keep the representations of the first six digits.
  ::!          e#   Negate each binary digit to obtain the "left" representation.
  0AA          e#   Push 0, 10, 10.
  R6>          e#   Push the representations of the last six digits.
  A1           e#   Push 10, 1.
]s             e# Collect in an array and cast to string.

30*            e# Repeat the resulting string 30 times.
S*             e# Join it, using spaces as separators.

4

Rev 1 BBC BASIC, 155 ký tự ascii, tệp được mã hóa kích thước 132 byte

INPUTn$
FORi=91TO185p=i MOD2j=i MOD47IFj<42j+=i DIV141*42p=(j>41EORASC(MID$("XLd^bFznvh",VAL(MID$(n$,j/7+1,1))+1)))>>(j MOD7)AND1
IFp LINEi*2,60,i*2,0
NEXT

đã lưu một vài byte bằng cách kết hợp offset 43 vào ivòng lặp. Để tránh phá vỡ MOD2thêm 47 phải được thêm vào tổng cộng 90.

Điều này di chuyển mã vạch xa hơn từ nguồn gốc, như được hiển thị, nếu điều đó được chấp nhận:

nhập mô tả hình ảnh ở đây

Rev 0 BBC BASIC, ký tự 157 ascii, tệp được mã hóa kích thước 137 byte

INPUTn$
FORi=1TO95p=i MOD2j=(i+43)MOD47IFj<42j+=i DIV51*42p=(i>50EORASC(MID$("XLd^bFznvh",VAL(MID$(n$,j/7+1,1))+1)))>>(j MOD7)AND1
IFp LINEi*2,0,i*2,60
NEXT

Tải xuống thông dịch viên tại http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Chế độ màn hình mặc định là văn bản màu đen trên nền trắng. Điều này khác với BBC BASC ban đầu.

Phiên bản Ungolfed với in thử

Tính toán một thanh dữ liệu phụ thuộc IF j<42và tất cả phải được thực hiện trên một dòng. Trong phiên bản không được chỉnh sửa, nó được thực hiện theo ba bước. Trong phiên bản golf, hai bước cuối cùng được kết hợp thành một biểu thức lớn duy nhấtp=...

Tôi đã phải đảo ngược thứ tự của bitmap, bởi vì tôi sử dụng >>(j MOD 7)để truy cập các bit, điều đó có nghĩa là tôi truy cập vào bit quan trọng nhất trước tiên. Khi điều này được thực hiện, tất cả các bitmap bên trái đều thuận tiện trong phạm vi ASCII.

  INPUTn$
  FOR i=1TO95                            :REM iterate through 95 bars
    p=i MOD2                             :REM calculate colour of format bar 1=black
    j=(i+43)MOD47                        :REM repetition is 42 data bars + 5 format bars. offset and modulo. if j<42 it is a data bar and we must change p.

    REM if i DIV 51=1 we are in the second half, so add 42 to j. Find the bitmap for left hand value, from character j/7 of the input.
    REM i>50 evaluates to false=0 true=-1. XOR this with p to invert bitmap for right hand side. Shift and AND with 1.  
    IF j<42 j+=i DIV51*42:p=ASC(MID$("XLd^bFznvh",  VAL(MID$(n$,j/7+1,1))+1  )) :p=(i>50EORp)>>(j MOD7) AND 1

    IF j MOD 7 = 0 PRINT                  :REM format test output
    PRINT ;p;                             :REM print test output
    IF p LINEi*2-2,0,i*2-2,60             :REM if p=1 plot bar. there are 2 logical units for each pixel.
  NEXT

Đầu ra điển hình, phiên bản chưa được chỉnh sửa, với đầu ra thử nghiệm

nhập mô tả hình ảnh ở đây


2

JavaScript ES6, 225 byte

s=>`P1
30 90
`+([...`101${(f=(z,j)=>[...j].map(i=>`000${z[+i].toString(2)}`.slice(-7)).join``)([13,25,19,61,35,49,47,59,55,11],s[0])}01010${f([114,102,108,66,92,78,80,68,72,116],s[1])}101`].join` `+`
`).repeat(30).slice(0,-1)

Có thể ngắn hơn với các tính năng ES7 nhưng tôi không chắc về sự hỗ trợ của họ nên tôi gắn bó với ES6. Tôi cũng giả sử một đầu vào là một mảng. Đầu ra là một tệp PBN . Ngoài ra còn có rất nhiều golf để làm.

Nếu tôi làm bất cứ điều gì sai hãy để lại nhận xét và tôi chắc chắn sẽ sửa nó


Tôi nghĩ bạn có nghĩa là tệp PBM ...
sergiol

2

Perl, 153 byte

substr($_=<>,6,0)=A;y/0-9A/=ICmSa_kg;0/;$s.=sprintf("%07b",-48+ord$1^($k++>6?127:0))while/(.)/g;$s=~s/0{7}/01010/;print"P1
95 30
".('101'.$s.'101'.$/)x30

Sao chép vào một tệp mã vạch.perl và sau đó chạy như thế này:

perl barcode.perl > output.pbm

sau đó nhập số mã vạch.

Giải trình:

Các mẫu bit cho các chữ số mã vạch được lưu trữ trong một chuỗi và được thay thế cho các chữ số đầu vào bằng cách sử dụng Perl y/// toán tử chuyển ngữ . Mỗi giá trị trong chuỗi thay thế có 48 (ASCII '0') được thêm vào từ đó, để tránh các ký tự không thể in được. Các chữ số ở nửa sau của mã vạch là nghịch đảo của các chữ số trong nửa đầu.

Mẫu trung tâm được đặt thành 0000000 (mẫu có thể không bao giờ xuất hiện, được mã hóa thành 'A' và sau đó '0') và sau đó được thay thế bằng 01010 thay vì xử lý độ dài khác nhau của nó như một trường hợp đặc biệt khi sprinting.


1

Octave, 115 byte

function b(s)
n='rflB\MPDHt'-0;r=dec2bin(n(s-47)',7)'(:)-48;v=[a=[1 0 1] ~r(1:42)' 0 a r(43:84)' a];v(ones(30,1),:)

Phiên bản nhiều dòng:

function b(s)
   n='rflB\MPDHt'-0;
   r=dec2bin(n(s-47)',7)'(:)-48;
   v=[a=[1 0 1] ~r(1:42)' 0 a r(43:84)' a];
   v(ones(30,1),:)

nlà ASCII tương đương với các mã chữ số bên phải (chúng dễ nhập hơn bên trái vì chúng đều là các ký tự hiển thị). Sau đó, một chuyển đổi thập phân sang nhị phân thẳng với một số loại khó chịu thay đổi từ char sang số. vxây dựng chuỗi nhị phân cuối cùng và sau đó chúng tôi lặp lại nó 30 lần và xuất ra bàn điều khiển.

Đầu ra mẫu chỉ có 2 trong số 30 hàng được hiển thị cho ngắn gọn:

s = '777777222222';
ans =

 Columns 1 through 30:

   1   0   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1
   1   0   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   1   1   0   1
...

 Columns 31 through 60:

   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   0   1   1   1   0   1   1   0   0   1   1   0   1
   1   0   1   1   1   0   1   1   0   1   1   1   0   1   1   0   1   0   1   1   1   0   1   1   0   0   1   1   0   1
...

 Columns 61 through 90:

   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0
   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0   0   1   1   0   1   1   0
...

 Columns 91 through 94:

   0   1   0   1
   0   1   0   1
...

Đầu ra nén:

1010111011011101101110110111011011101101110110101110110011011001101100110110011011001101100101

Ban đầu tôi dự định hiển thị hình ảnh, nhưng việc gửi đầu ra tới bàn điều khiển đã tiết kiệm cho tôi 9 byte. Bạn có thể hiển thị kết quả bằng cách sử dụng imshow, nhưng nó hiển thị 1màu trắng và 0đen, vì vậy bạn phải đảo ngược dữ liệu trước.

imshow(~v(ones(30,1),:));

1

Rắn hổ mang - 218

do(s='')
    print'P1\n95 30'+('\n'+('101'+(for n in 12get Convert.toString(if((t=139+[2,14,8,50,24,38,36,48,44,0][s[n]to int-48])and n<6,t,~t),2)[-7:]+if(n-5,'','01010')).join('')+'101').toCharArray.join(' ')).repeat(30)

1

Javascript ES6, 199 byte

n=>`P1 95 30 `+(101+(g=(a,...s)=>(``+1e12+n).slice(...s,-6).split``.map(m=>(1e3+a[m].toString(2)).slice(-7)).join``)(a=[13,25,19,61,35,49,47,59,55,11],-12)+`01010`+g(a.map(i=>~i&127))+101).repeat(30)

"đệ trình ngắn nhất (tính bằng byte thắng)". Bạn cần phải đếm mã của mình theo byte, vì vậy nếu sử dụng Unicode, đó là 2 byte cho mỗi ký tự, tôi nghĩ vậy.
mbomb007

Bah, vâng, tôi đoán câu trả lời chưa được giải mã của tôi sau đó ngắn hơn
Dendrobium

0

Python 2, 174 byte

Tôi biết nó có thể được chơi gôn.

Chuỗi s là bảng nhị phân trong câu hỏi với nửa bên trái của bảng là nửa bên trái của chuỗi. Các giá trị được ANDed bởi 63 trước nếu ở nửa bên phải (loại bỏ 1 đầu tiên), sau đó thay đổi 63 để có thể in ASCII.

BUG: Hiện đang cố gắng sửa một lỗi. Đầu ra của ví dụ đầu tiên bị tắt bởi một chữ số của mã vạch. Nếu bạn tìm ra nó, xin vui lòng cho tôi biết.

I=raw_input()
s="LXR|bpnzvJcekA[MOCGs"
x="".join(format(ord(s[int(I[i])+10*(i>5)])-63|1+63*(i>5),'07b')for i in range(len(I)))
L=len(x)/2
print"101%s01010%s101"%(x[:L],x[L:])

Hoặc, tôi đã thực hiện thử thách hoàn toàn sai. Hãy cho tôi biết trong trường hợp đó quá.
mbomb007
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.