Sebuah EAN-8 barcode meliputi 7 digit informasi dan checksum digit ke-8.
Checksum dihitung dengan mengalikan digit dengan 3 dan 1 secara bergantian, menambahkan hasilnya, dan mengurangi dari kelipatan 10 berikutnya.
Misalnya, diberi angka 2103498
:
Digit: 2 1 0 3 4 9 8
Multiplier: 3 1 3 1 3 1 3
Result: 6 1 0 3 12 9 24
Jumlah digit yang dihasilkan ini adalah 55 , sehingga digit checksum adalah 60 - 55 = 5
Tantangan
Tugas Anda adalah, diberi barcode 8 digit, memverifikasi apakah valid - mengembalikan nilai kebenaran jika checksum valid, dan sebaliknya palsu.
- Anda dapat mengambil input dalam formulir berikut:
- String, panjang 8 karakter, mewakili digit kode batang
- Daftar 8 bilangan bulat, digit barcode
- Integer non-negatif (Anda dapat mengasumsikan nol terkemuka di mana tidak ada yang diberikan, yaitu
1
=00000001
, atau meminta input dengan nol yang diberikan)
- Builtin yang menghitung checksum EAN-8 (yaitu, ambil 7 digit pertama dan hitung yang terakhir) dilarang.
- Ini adalah kode-golf , jadi program terpendek (dalam byte) menang!
Uji Kasus
20378240 -> True
33765129 -> True
77234575 -> True
00000000 -> True
21034984 -> False
69165430 -> False
11965421 -> False
12345678 -> False
code-golf
arithmetic
decision-problem
integer
checksum
FlipTack
sumber
sumber
Jawaban:
Jelly , 7 byte
Cobalah online!
Bagaimana itu bekerja
sumber
JavaScript (ES6),
414038 byteDisimpan 2 byte berkat @ETHProductions dan 1 byte terima kasih ke @Craig Ayre.
Mengambil input sebagai daftar digit.
Menentukan jumlah semua digit, termasuk checksum.
Jika jumlahnya adalah kelipatan 10, maka itu adalah barcode yang valid.
Uji Kasus
Tampilkan cuplikan kode
sumber
g=([n,...s],i=3,t=0)=>n?g(s,4-i,t+n*i):t%10<1
, tetapi Anda mungkin telah menemukan cara yang lebih baik ...map
, yang menurut saya berfungsi lebih baik karena input dapat berupa daftar digit, bukan string.s=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1
?&&
dengan|
dengan output 1/0 karena kebenaran / kepalsuan diizinkan?Python 2 ,
64483529 bytemypetlion menyimpan 19 byte
Cobalah online!
sumber
lambda x:sum(x[::2]*3+x[1::2])%10<1
Selama 35 byte.lambda x:sum(x[::2]*2+x)%10<1
Selama 29 byte.Jelly , 8 byte
Coba test suite.
Jelly , 9 byte
Cobalah online atau Coba test suite.
Bagaimana ini bekerja?
Hasil untuk 7 digit pertama dari barcode dan digit checksum harus ditambahkan kelipatan 10 agar valid. Dengan demikian, checksum valid jika algoritma yang diterapkan pada seluruh daftar dapat dibagi 10 .
sumber
JḂḤ‘×µS⁵ḍ
JḂaḤ+µS⁵ḍ
Pm2Ḥ+µS⁵ḍ
adalah 15 byte di UTF-8, kecuali saya sudah salah menghitungnya.MATL , 10 byte
Terima kasih kepada @Zgarb karena menunjukkan kesalahan, sekarang diperbaiki.
Cobalah online! Atau verifikasi semua kasus uji .
Penjelasan
sumber
Befunge-98 (PyFunge) ,
1614 byteDisimpan 2 byte dengan melewatkan bagian kedua menggunakan
j
bukan;
s, serta menukar a~
dan+
di bagian pertama untuk menyingkirkan a+
di bagian kedua.Input dalam 8 digit (dengan awalan 0s jika berlaku) dan tidak ada yang lain.
Output melalui kode keluar (buka dropdown debug pada TIO), di mana 1 benar dan 0 salah.
Cobalah online!
Penjelasan
Program ini menggunakan berbagai trik.
Pertama-tama, dibutuhkan digit satu per satu melalui nilai ASCII mereka. Biasanya, ini membutuhkan pengurangan 48 dari setiap nilai saat kita membacanya dari input. Namun, jika kami tidak memodifikasinya, kami memiliki 16 (3 + 1 + 3 + 1 + 3 + 1 + 3 + 1) salinan tambahan dari 48 jumlah kami, yang berarti total kami akan menjadi 768 lebih besar dari apa itu "seharusnya". Karena kita hanya peduli dengan jumlah mod 10, kita bisa menambahkan 2 ke jumlah kemudian. Dengan demikian, kita dapat mengambil nilai ASCII mentah, menghemat 6 byte atau lebih.
Kedua, kode ini hanya memeriksa apakah setiap karakter lain adalah EOF, karena inputnya dijamin hanya 8 karakter.
Ketiga,#
pada akhir baris tidak melewatkan karakter pertama, tetapi akan melewatkan;
jika datang dari arah lain. Ini lebih baik daripada meletakkan#;
di depan saja.Karena bagian kedua dari program kami hanya berjalan sekali, kami tidak perlu mengaturnya sehingga akan melewati babak pertama ketika berjalan mundur. Ini memungkinkan kita menggunakan perintah lompat untuk melompati babak kedua, saat kita keluar sebelum mengeksekusinya mundur.
Selangkah demi selangkah
Catatan: Karakter "Ganjil" dan "Genap" didasarkan pada sistem yang diindeks 0. Karakter pertama adalah karakter genap, dengan indeks 0.
sumber
C,
7877 byteCobalah online!
C (gcc), 72 byte
Cobalah online!
sumber
Bahasa Wolfram (Mathematica) ,
2621 byteCobalah online!
Mengambil input sebagai daftar 8 digit.
Bagaimana itu bekerja
2-9^Range@8
adalah modulo 10 kongruen2-(-1)^Range@8
, yaitu{3,1,3,1,3,1,3,1}
. Kami mengambil produk titik dari daftar ini dengan input, dan memeriksa apakah hasilnya dapat dibagi 10.Bahasa Wolfram (Mathematica) , 33 byte dan tidak bersaing
Cobalah online!
Mengambil input sebagai string. Pengembalian
1
untuk barcode yang valid dan0
untuk yang tidak valid.Bagaimana itu bekerja
Hal terbaik yang bisa saya temukan di jalan bawaan (karena Mathematica adalah soal itu).
Bit bagian dalam
#~BarcodeImage~"EAN8";1
,, menghasilkan gambar dari barcode EAN8, kemudian mengabaikannya sepenuhnya dan mengevaluasi ke 1. Namun, jika barcode tidak valid, kemudianBarcodeImage
menghasilkan peringatan, yangCheck
menangkap, mengembalikan 0 dalam kasus itu.sumber
BarcodeImage
, yang menghasilkan gambar barcode, dan memvalidasi barcode dalam proses. BegituCheck[#~BarcodeImage~"EAN8";0,1]<1&
juga bekerja (tapi lebih lama).Java 8,
585655 byte-2 byte secara tidak langsung berkat @RickHitchcock , dengan menggunakan
(m=4-m)*i
alih-alihm++%2*2*i+i
setelah melihatnya dalam jawaban JavaScript- nya .-1 byte secara tidak langsung berkat @ETHProductions (dan @RickHitchcock ), dengan menggunakan
(m^=2)*i
alih-alih(m=4-m)*i
.Penjelasan:
Coba di sini.
sumber
m=4-m
kem^=2
.^=1
cukup sering menggunakan jawaban ketika saya ingin mengubah antara0
dan1
.^=2
berfungsi dalam hal ini untuk mengubah antara1
dan3
. Trik yang bagus, dan terima kasih atas komentarnya. :)05AB1E , 14 byte
Cobalah online!
Membutuhkan terkemuka
0
, mengambil daftar digit.sumber
3100004
(harus jujur).0
sana.0
. Jawaban ini sebenarnya menggunakan fungsi angka pada string, salah satu fitur 05AB1E.Pyth , 8 byte
Verifikasi semua kasus uji!
Pyth , 13 byte
Jika kita dapat berasumsi bahwa input selalu memiliki tepat 8 digit:
Verifikasi semua kasus uji!
Bagaimana cara kerjanya?
Jika jumlah dari 7 digit pertama setelah diterapkan algoritma dikurangi dari 10 dan kemudian dibandingkan dengan digit terakhir, ini sama dengan memeriksa apakah jumlah semua digit, setelah algoritma diterapkan adalah kelipatan dari 10 .
sumber
3100004
(harus jujur).3*3+1*1+0*3+...
atau tidak0*3+3*1+1*0..
? Saya pikir kita harus melakukan yang pertamaHaskell ,
4038 byteCobalah online!
Mengambil input sebagai daftar 8 bilangan bulat. Contoh praktis menggunakan daftar tak terbatas.
Sunting: Disimpan 2 byte berkat GolfWolf
sumber
cycle
menghemat 2 byte .Retina ,
2322 byte-1 byte terima kasih kepada Martin Ender !
Cobalah online!
Penjelasan
Input contoh:
20378240
Ganti setiap pasangan angka dengan digit pertama diulang dua kali diikuti oleh pasangan itu sendiri. Kita mendapatkan
2220333788824440
Ubah setiap digit menjadi unary. Dengan tanda kurung ditambahkan untuk kejelasan, kita dapatkan
(11)(11)(11)()(111)(111)...
Hitung jumlah kecocokan string kosong, yang satu lebih banyak dari jumlah yang ada dalam string. (Dengan dua langkah terakhir pada dasarnya kami telah mengambil jumlah setiap digit +1) Hasil:
60
Cocokkan
1
di akhir string. Kami telah mengalikan digit dengan 3 dan 1 secara bergantian dan menjumlahkannya, untuk barcode yang valid ini harus dapat dibagi dengan 10 (digit terakhir 0); tapi kami juga menambahkan 1 di langkah terakhir, jadi kami ingin angka terakhir menjadi 1. Hasil akhir:1
.sumber
.
pertandingan dan pertandingan1$
di akhir.PowerShell , 85 byte
Cobalah online! atau Verifikasi semua kasus uji
Menerapkan algoritma seperti yang didefinisikan. Mengambil input
$a
, menarik setiap digit dengan"$a"[0..6]
dan loop melalui mereka|%{...}
. Setiap iterasi, kami mengambil digit, melemparkannya sebagai string"$_"
kemudian melemparkannya sebagai int+
sebelum mengalikannya dengan salah satu3
atau1
(dipilih dengan menambah$i
modulo2
).Semua hasil itu dikumpulkan dan dijumlahkan
-join'+'|iex
. Kami mengambil mod hasil itu10
, kurangi dari10
, dan kembali mengambil mod hasil10
(mod kedua ini diperlukan untuk menjelaskan00000000
kasus uji). Kami kemudian memeriksa apakah itu-eq
ual ke digit terakhir. Hasil Boolean ditinggalkan di jalur pipa dan hasilnya tersirat.sumber
3100004
(harus jujur).Jelly , 16 byte
Cobalah online!
menerima input sebagai daftar digit
sumber
D
footer. Dan terima kasih! : DDµṪ=Ç
.3100004
(harus jujur).APL (Dyalog) , 14 byte
Setara dengan solusi streetster .
Tubuh program penuh. Meminta daftar nomor dari STDIN.
Cobalah online!
Aku s…
0=
nol sama dengan10|
mod-10 dari+/
jumlah dari⎕×
waktu input8⍴3 1
delapan elemen diambil secara siklis[3,1]
?
sumber
05AB1E , 9 byte
Cobalah online!
sumber
31×S*OTÖ
untuk 8 byte.×
hanya mendorong 31n
kali. Ketika Anda mengalikan, secara otomatis akan menjatuhkan 31 ekstra.69165430 -> 1
J, 17 byte
-10 byte berkat cole
Cobalah online!
Ini menggunakan penggandaan daftar berukuran sama untuk menghindari kombo zip / gandakan solusi asli, serta "trik dasar 1"
1#.
untuk menambahkan produk bersama. Pendekatan tingkat tinggi mirip dengan penjelasan asli.asli, 27 byte
Cobalah online!
dijelaskan
sumber
0=10|1#.(8$3 1)*]
harus bekerja selama 17 byte (melakukan algoritma yang sama juga). Saya cukup yakin bahwa dalam versi beta Anda dapat memiliki kait berakhir di sisi kanan dengan kata benda, jadi0=10|1#.]*8$3 1
mungkin bekerja untuk 15 (saya akan memeriksa tio tetapi tampaknya turun?)1#.
trik seperti 2 atau 3 kali ... terima kasih telah mengingatkan saya. Oh, btw versi 15 byte tidak berfungsi di TIO.C (gcc),
8482726154 byte-21 byte dari Neil
-7 byte dari Nahuel Fouilleul
Cobalah online!
Dikembangkan secara independen dari jawaban Steadybox
'f' adalah fungsi yang mengambil barcode sebagai
int
, dan mengembalikan1
untuk True dan0
False.f
menyimpan digit terakhir darix
dalams
(s=x%10
),Kemudian hitung jumlah dalam
c
(for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;
)c
adalah jumlah,i
adalah penghitunguntuk setiap digit termasuk yang pertama, tambahkan
1+2*i%4
kali digit (x%10
) ke checksum dan kenaikani
(i++
dalam3-2*i++%4
)1+2*i%4
adalah 1 saati
genap dan 0 bilai
ganjilKemudian mengembalikan apakah jumlahnya merupakan kelipatan dari sepuluh, dan karena kami menambahkan digit terakhir (dikalikan dengan 1), jumlahnya akan menjadi kelipatan dari sepuluh jika barcode itu valid. (menggunakan perilaku tidak terdefinisi tergantung GCC untuk menghilangkan
return
).sumber
(x%10)
bisa sajax
seperti yang Anda lakukanc%10
nanti. Juga saya pikir Anda dapat menggunakani<8
dan kemudian hanya menguji apakahc%10
nol pada akhirnya.s
tidak perlu:c;i;f(x){for(i=c=0;i<8;x/=10)c+=(1+2*i++%4)*x;return c%10<1;}
x=c%10<1
atauc=c%10<1
bukannyareturn c%10<1
masih berfungsii<8
dapat digantikan olehx
C, 63 byte
Mengasumsikan bahwa
0
adalahtrue
dan nilai lain adalahfalse
.+3 byte untuk nilai pengembalian yang lebih baik
Tambahkan
==0
kereturn
pernyataan.Tidak disatukan
Ini menggunakan definisi alternatif checksum EAN di mana digit cek dipilih sedemikian rupa sehingga checksum dari seluruh barcode termasuk digit periksa adalah kelipatan 10. Secara matematis ini berfungsi sama tetapi jauh lebih mudah untuk menulis.
Menginisialisasi variabel di dalam loop seperti yang disarankan oleh Steadybox, 63 byte
Menghapus kurung keriting seperti yang disarankan oleh Steadybox, 61 byte
Menggunakan
<1
daripada==0
untuk nilai pengembalian yang lebih baik seperti yang disarankan oleh Kevin CruijssenTambahkan
<1
kereturn
pernyataan, ini hanya menambah 2 byte daripada menambahkan==0
yang menambahkan 3 byte.sumber
{}
setelahfor
. Juga, pengiriman fungsi harus dapat digunakan kembali , jadi Anda perlu menginisialisasis
di dalam fungsi (hanya mengubahi;s=0;
kei,s;
dani=0;
kei=s=0;
).for
, tubuh loop akan menjadi pernyataan berikutnyafor(i=0;i<8;i++){s+=v[i]*3+v[++i];}
sama denganfor(i=0;i<8;i++)s+=v[i]*3+v[++i];
.==0
bisa +2 dengan menggunakan<1
sebagai gantinya. :)JavaScript (Node.js) , 47 byte
Meskipun sudah ada jawaban yang jauh lebih singkat, ini adalah upaya pertama saya bermain golf di JavaScript sehingga saya ingin mendengar rekomendasi golf :-)
Pengujian
Tampilkan cuplikan kode
Atau, Anda dapat mencobanya secara online!
sumber
Perl 5,
3732 + 1 (-p) byte-5 byte berkat Dom Hastings. 37 +1 byte tadinya
coba online
sumber
--$|
beralih antara1
dan0
sehingga Anda dapat menggunakannya daripada++$i%2
untuk boolean bergantian! Selain itu, yang terpenting adalah bahwa total ($s
) yang cocok/0$/
, berhasil mendapatkan 33 byte yang menggabungkan perubahan-perubahan itu dengans///
: Coba online! (-l
hanya untuk visibilitas)s/./(something with $&)/ge
dan untuk/0$/
mencocokkan tetapi tidak keduanya digabungkan.Brainfuck, 228 Bytes
Mungkin bisa ditingkatkan sedikit adil. Input diambil 1 digit pada satu waktu, output 1 untuk true, 0 untuk false.
Bagaimana itu bekerja:
Letakkan 8 di posisi 3.
Mengambil input 8 kali, mengubahnya dari nilai ascii ke nilai aktual +2 setiap kali. Input diberi spasi oleh yang, yang akan dihapus, untuk memungkinkan penggandaan yang lebih mudah nanti.
Kurangi satu dari setiap item. Rekaman kami sekarang terlihat seperti
Dengan setiap nilai 1 lebih dari yang seharusnya. Ini karena nol akan mengacaukan proses perkalian kami.
Sekarang kita siap untuk mulai mengalikan.
Pergi ke item kedua ke terakhir.
Sementara nol, gandakan item dengan tiga, lalu pindahkan dua item ke kiri. Sekarang kami telah mengalikan semua yang kami butuhkan menjadi tiga, dan kami berada di posisi pertama dalam rekaman itu.
Jumlahkan seluruh daftar.
Nilai yang kami miliki adalah 16 lebih dari nilai sebenarnya. Perbaiki ini dengan mengurangi 16.
Kita perlu menguji apakah jumlahnya adalah kelipatan 10. Jumlah maksimum adalah dengan semua 9s, yaitu 144. Karena tidak ada jumlah yang lebih besar dari 10 * 15, letakkan 15 dan 10 pada pita, dalam urutan itu dan hak untuk hak penjumlahan.
Pindah ke tempat 15. Meskipun tidak nol, uji apakah jumlahnya tidak nol. Jika ya, kurangi 10 dari itu. Sekarang kita berada pada posisi jumlah (kosong), atau pada posisi (juga kosong) sepuluh. Bergerak ke kanan. Jika kita berada di posisi penjumlahan, kita sekarang di posisi bukan-nol 15. Jika demikian, gerakkan ke kanan dua kali. Sekarang kami berada di posisi yang sama dalam kedua kasus. Tambahkan sepuluh ke posisi sepuluh, dan kurangi satu dari posisi 15.
Sisanya untuk output:
Pindah ke posisi penjumlahan. Jika bukan nol (negatif), barcode tidak valid; atur posisi ke -1. Sekarang tambahkan 49 untuk mendapatkan nilai ascii yang benar: 1 jika valid, 0 jika tidak valid.
sumber
Java 8, 53 byte
Golf:
Penghitungan langsung dalam lambda tampaknya merupakan solusi terpendek. Ini cocok dalam satu ekspresi, meminimalkan overhead lambda dan menghapus deklarasi variabel asing dan titik koma.
Keluaran:
sumber
QBasic,
5452 byteUgh, jawaban yang membosankan ternyata yang terpendek:
Ini input digit yang dipisahkan koma. Solusi 54 byte asli saya, yang memasukkan satu digit pada satu waktu, menggunakan pendekatan "lebih baik":
sumber
C # (.NET Core) ,
6562 byteCobalah online!
Ucapan Terima Kasih
-3 byte terima kasih kepada @KevinCruijssen dan trik rapi menggunakan operator-atau eksklusif.
DeGolfed
C # (.NET Core) , 53 byte
Cobalah online!
Port langsung jawaban @ Snowman .
sumber
b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}
( 62 byte ), atau sebagai alternatif dengan foreach, juga 62 byte:b=>{int s=0,t=1;foreach(int i in b)s+=i*(t^=2);return s%10<1;}
(yang merupakan port jawaban Java 8 saya ).MATLAB / Oktaf , 32 byte
Cobalah online!
Saya akan memposting ini terlepas dari jawaban Oktaf lainnya ketika saya mengembangkan kode dan pendekatan ini tanpa melihat jawaban yang lain.
Di sini kita memiliki fungsi anonim yang mengambil input sebagai array dari 8 nilai, dan mengembalikan true jika barcode yang valid, false sebaliknya ..
Hasilnya dihitung sebagai berikut.
sumber
Excel, 37 byte
Menafsirkan "Daftar 8 bilangan bulat" sebagai memungkinkan 8 sel terpisah di Excel:
sumber
()
dalam komentar Anda.=(A1:H1)
: Ini tidak ditangani sebagai sebuah array. Tidak valid jika ditempatkan di kolom mana pun yang tidak dalamA-H
jangkauan. Jika ditempatkan dalam kolom di AH, kembalikan nilai untuk kolom itu saja. (Formula dalam% menghasilkan%: C2 -> C1 H999 -> H1 K1 -> #VALUE!)Ruby, 41 Bytes
Mengambil array bilangan bulat. -6 byte berkat Jordan.
sumber
map
di sini sama sekali:zip
mengambil blok. Anda dapat menyimpan beberapa byte lagi dengan menggunakan$.
alih-alih menginisialisasis
:->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
TI-Basic (83 series), 18 byte
Mengambil input sebagai daftar di
Ans
. Pengembalian1
untuk barcode yang valid dan0
untuk yang tidak valid.Port jawaban Mathematica saya . Termasuk tangkapan layar, sebagai pengganti lingkungan pengujian online:
Fitur penting:
binomcdf(7,0
digunakan untuk menghasilkan daftar{1,1,1,1,1,1,1,1}
(daftar probabilitas yang dari 7 percobaan dengan probabilitas keberhasilan 0, akan ada paling banyak N keberhasilan, untuk N = 0,1, ..., 7). Lalu,cumSum(
ubah ini menjadi{1,2,3,4,5,6,7,8}
.Ini satu byte lebih pendek daripada menggunakan
seq(
perintah, meskipun secara historis intinya adalah bahwa itu juga secara signifikan lebih cepat.sumber