Barcodegolf: Hasilkan UPC angka

12

Hampir setiap toko saat ini menggunakan barcode Kode Produk Universal (UPC) untuk menyederhanakan proses pemeriksaan. Jika nama itu tidak berarti apa-apa bagi Anda, Anda pasti akan mengenali seperti apa tampilannya:

Contoh barcode UPC-A

Format

Sistem yang paling umum adalah UPC-A, yang menggunakan 12 digit untuk mewakili setiap produk tertentu. Setiap digit dikodekan ke dalam serangkaian garis-garis hitam dan putih untuk memungkinkan mesin membaca kode, panjang tujuh bit. Ada total pola senilai 11 bit yang menunjukkan awal, tengah, dan akhir barcode. Ini mencapai total panjang barcode 12 × 7 + 11 = 95 bit. (Mulai sekarang, ketika biner digunakan untuk merujuk pada warna setiap bit, 0berwarna putih dan 1hitam.)

Awal dan akhir keduanya memiliki pola 101. Digit-digit tersebut kemudian dibagi menjadi 2 kelompok dengan 6 dan dikodekan seperti yang ditunjukkan di bawah ini, dengan pola 01010antara kelompok kiri dan kanan. Tabel ini mencantumkan pola untuk setiap nomor. Perhatikan bahwa polanya berbeda tergantung pada apakah digit berada di sisi kanan atau kiri (Ini memungkinkan barcode dipindai secara terbalik). Namun, pola untuk kanan adalah kebalikannya (swap hitam untuk putih dan sebaliknya) dari pola kiri.

Tabel konversi UPC

Jika Anda tidak dapat melihat gambar di atas, ini adalah setara biner masing-masing angka.

#   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

Contoh

Katakanlah Anda memiliki UPC 022000 125033. (Itu bukan angka acak. Berikan komentar jika Anda mengetahui signifikansinya.) Anda mulai dengan pelat ini yang sama di setiap barcode:

101xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx01010xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx101

Untuk digit, Anda ganti masing-masing dengan pengkodean yang sesuai untuk sisi (kiri atau kanan) yang aktif. Jika Anda masih bingung, lihat gambar di bawah ini.

Rincian pengkodean UPC

Berikut ini adalah output dalam biner dengan |pipa yang memisahkan bagian-bagiannya.

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

Tantangan

Tulis program yang mengeluarkan kode batang UPC-A untuk input pengguna. Dimensi gambar harus 95 × 30 piksel, dengan masing-masing "bit" berukuran satu piksel dan tinggi 30 piksel. Garis-garis hitam dalam rgb(0, 0, 0)dan garis-garis putih transparan atau konsisten rgb(255, 255, 255).

Catatan

  • Ambil input dari stdin atau baris perintah, atau tulis fungsi yang mengambil string atau integer (perhatikan bahwa input dapat memiliki angka nol di depan, dan sebagian besar bahasa menghapusnya atau mengonversi angka menjadi oktal).
  • Keluarkan gambar dengan salah satu cara berikut:
    • Simpan ke file dengan nama dan format (PNG, PBM, dll.) Pilihan Anda.
    • Tampilkan di layar.
    • Keluarkan data file-nya ke stdout.
  • Anda mungkin tidak menggunakan pustaka atau builtin yang menghasilkan barcode ( saya melihat Anda, Mathematica ), meskipun Anda dapat menggunakan pustaka gambar atau grafik.
  • Digit terakhir dari UPC biasanya digit periksa , tetapi untuk tujuan ini Anda tidak perlu khawatir.

Contohnya

Berikut adalah beberapa contoh untuk menguji kode Anda. Output biner juga diberikan untuk kenyamanan.

Memasukkan: 012345678910

Keluaran:

10100011010011001001001101111010100011011000101010101000010001001001000111010011001101110010101

Memasukkan: 777777222222

Keluaran:

10101110110111011011101101110110111011011101101010110110011011001101100110110011011001101100101

Mencetak gol

Ini adalah kode golf , jadi pengiriman terpendek (dalam byte menang). Tiebreaker pergi ke pos paling awal.

NinjaBearMonkey
sumber
Mmm ... buah yang berair.
Dennis
Bisakah input diambil sebagai array? mis["777777","222222"]
Downgoat
@ Vihan Hmm, saya pikir itu sedikit peregangan. Saya akan mengatakan tidak.
NinjaBearMonkey
2
Barcode UPC yang dipindai pertama kali!
Dennis
1
Ini brilian. Barcode selalu membuat saya terpesona
Beta Decay

Jawaban:

3

CJam, 58 57 byte

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

Mencetak Bitmap Portable (ASCII) ke STDOUT. Cobalah online.

Bagaimana itu bekerja

'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.
Dennis
sumber
4

Rev 1 BBC BASIC, 155 ascii chars, tosize filesize 132 bytes

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

menyimpan beberapa byte dengan memasukkan offset 43 ke dalam iloop. Agar tidak melanggar MOD247 tambahan harus ditambahkan untuk total 90.

Ini memindahkan kode batang lebih jauh dari asalnya, seperti yang ditunjukkan, jika itu dapat diterima:

masukkan deskripsi gambar di sini

Rev 0 BBC BASIC, 157 ascii chars, tosize filesize 137 bytes

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

Unduh juru bahasa di http://www.bbcbasic.co.uk/bbcwin/bbcwin.html

Mode layar default adalah teks hitam dengan latar belakang putih. Ini berbeda dari BASC BBC asli.

Versi tidak disatukan dengan pencetakan tes

Perhitungan bilah data tergantung pada IF j<42dan semua harus dilakukan pada satu baris. Dalam versi yang tidak disunat itu dilakukan dalam tiga langkah. Dalam versi golf, dua langkah terakhir digabungkan menjadi satu ekspresi besarp=...

Saya harus membalik urutan bitmap, karena saya gunakan >>(j MOD 7)untuk mengakses bit, yang berarti saya mengakses bit paling tidak penting terlebih dahulu. Setelah ini selesai, semua bitmap kiri dengan nyaman berada dalam kisaran 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

Output khas, versi tidak disatukan, dengan output tes

masukkan deskripsi gambar di sini

Level River St
sumber
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)

Bisa lebih pendek dengan fitur ES7 tapi saya tidak yakin tentang dukungan mereka jadi saya tetap dengan ES6. Saya juga mengasumsikan input sebagai array. Outputnya adalah file PBN . Ada banyak golf yang bisa dilakukan.

Jika saya melakukan kesalahan tinggalkan komentar dan saya pasti akan memperbaikinya

Downgoat
sumber
Saya pikir maksud Anda file 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

Salin ke file barcode.perl lalu jalankan seperti ini:

perl barcode.perl > output.pbm

kemudian masukkan nomor barcode.

Penjelasan:

Pola bit untuk digit barcode disimpan dalam string dan diganti dengan digit input menggunakan y///operator transliterasi Perl . Setiap nilai dalam string substitusi memiliki 48 (ASCII '0') yang ditambahkan darinya, untuk menghindari karakter yang tidak diinginkan. Digit di bagian kedua dari barcode adalah kebalikan dari yang ada di bagian pertama.

Pola pusat diatur ke 0000000 (pola yang jika tidak bisa tidak pernah muncul, dikodekan sebagai 'A' dan kemudian '0') dan kemudian diganti dengan 01010 daripada menangani panjang yang berbeda sebagai kasus khusus saat sprinting.

samgak
sumber
1

Oktaf, 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),:)

Versi multi-baris:

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),:)

nadalah ASCII setara dengan kode digit sisi kanan (mereka lebih mudah untuk masuk daripada sisi kiri karena semuanya karakter yang dapat ditampilkan). Setelah itu, konversi desimal ke biner langsung dengan beberapa perubahan tipe yang menjengkelkan dari char ke numeric. vmembangun string biner terakhir dan kemudian kita ulangi 30 kali dan output ke konsol.

Output sampel dengan hanya 2 dari 30 baris yang ditampilkan untuk singkatnya:

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
...

Output terkompresi:

1010111011011101101110110111011011101101110110101110110011011001101100110110011011001101100101

Saya awalnya bermaksud untuk menampilkan gambar, tetapi mengirimkan output ke konsol menyelamatkan saya 9 byte. Anda dapat menampilkan hasil menggunakan imshow, tetapi ini ditampilkan 1sebagai putih dan 0hitam, jadi Anda harus membalikkan data terlebih dahulu.

imshow(~v(ones(30,1),:));
gelas kimia
sumber
1

Cobra - 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)
Suram
sumber
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)
Dendrobium
sumber
"pengajuan terpendek (dalam byte menang)". Anda perlu menghitung kode Anda dalam byte, jadi jika menggunakan Unicode, itu 2 byte per karakter, saya pikir.
mbomb007
Bah, ya, saya kira jawaban saya tanpa unicoded lebih pendek
Dendrobium
0

Python 2, 174 byte

Saya tahu itu bisa bermain golf.

String sadalah tabel biner dalam pertanyaan dengan bagian kiri dari tabel sebagai bagian kiri dari string. Nilai-nilai adalah ANDed oleh 63 pertama jika di bagian kanan (hapus pertama 1), kemudian digeser oleh 63 untuk dicetak ASCII.

BUG: Saat ini sedang mencoba untuk memperbaiki bug. Output dari contoh pertama dimatikan oleh satu digit barcode. Jika Anda mengetahuinya, beri tahu saya.

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:])
mbomb007
sumber
Atau, saya membuat telah melakukan tantangan yang sepenuhnya salah. Beritahu saya dalam hal ini juga.
mbomb007