Mã vạch của tôi có hợp lệ không?


33

Một EAN-8 mã vạch bao gồm 7 chữ số thông tin và một checksum chữ số 8.

Tổng kiểm tra được tính bằng cách nhân các chữ số với 3 và 1 xen kẽ, thêm kết quả và trừ đi bội số tiếp theo của 10.

Ví dụ, cho các chữ số 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

Tổng các chữ số kết quả này là 55 , vì vậy chữ số tổng kiểm tra là 60 - 55 = 5


Các thách thức

Nhiệm vụ của bạn là, được cung cấp mã vạch 8 chữ số, xác minh xem nó có hợp lệ không - trả về giá trị trung thực nếu tổng kiểm tra hợp lệ và giả mạo nếu không.

  • Bạn có thể nhận đầu vào dưới bất kỳ hình thức nào sau đây:
    • Một chuỗi, có độ dài 8 ký tự, biểu thị các chữ số mã vạch
    • Danh sách 8 số nguyên, chữ số của mã vạch
    • Một số nguyên không âm (bạn có thể giả sử các số 0 đứng đầu trong đó không có số nào được đưa ra, tức là 1= 00000001hoặc yêu cầu đầu vào với các số 0 đã cho)
  • Các nội dung tính toán tổng kiểm tra EAN-8 (nghĩa là lấy 7 chữ số đầu tiên và tính toán cuối cùng) đều bị cấm.
  • Đây là , vì vậy chương trình ngắn nhất (tính bằng byte) sẽ thắng!

Các trường hợp thử nghiệm

20378240 -> True
33765129 -> True
77234575 -> True
00000000 -> True

21034984 -> False
69165430 -> False
11965421 -> False
12345678 -> False

Liên quan đến thuật toán Luhn để xác minh số thẻ tín dụng , có thể là bản sao.
xnor

1
Câu hỏi này không thực sự là về mã vạch (là thứ sọc trắng đen), mà là về số được mã hóa bằng mã vạch. Số có thể tồn tại mà không cần mã vạch và mã vạch có thể mã hóa những thứ khác ngoài EAN. Có lẽ chỉ " EAN-8 của tôi hợp lệ " là một tiêu đề tốt hơn?
Paŭlo Ebermann

2
@ PaŭloEbermann không hoàn toàn có chiếc nhẫn tương tự ...
FlipTack

7
Khi đọc về mã vạch, tôi mong đợi một số đọc hình ảnh (hoặc ít nhất là một chuỗi bit), không xác minh tổng kiểm tra.
Paŭlo Ebermann

Liên quan chặt chẽ , vì ISBN-13 là EAN.
Olivier Grégoire

Câu trả lời:


5

Thạch , 7 byte

s2Sḅ3⁵ḍ

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

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

s2Sḅ3⁵ḍ  Main link. Argument: [a,b,c,d,e,f,g,h] (digit array)

s2       Split into chunks of length 2, yielding [[a,b], [c,d], [e,f], [g,h]].
  S      Take the sum of the pairs, yielding [a+c+e+g, b+d+f+h].
   ḅ3    Convert from ternary to integer, yielding 3(a+c+e+g) + (b+d+f+h).
     ⁵ḍ  Test if the result is divisible by 10.

13

JavaScript (ES6), 41 40 38 byte

Đã lưu 2 byte nhờ @ETH sản phẩm và 1 byte nhờ @Craig Ayre.

s=>s.map(e=>t+=e*(i^=2),t=i=1)|t%10==1

Lấy đầu vào là một danh sách các chữ số.

Xác định tổng của tất cả các chữ số, bao gồm cả tổng kiểm tra.

Nếu tổng là bội số của 10, thì đó là mã vạch hợp lệ.

Các trường hợp thử nghiệm


Tôi sẽ nói rằng bạn có thể tiết kiệm 3 byte bằng cách chuyển đổi từ trước đệ quy để hậu đệ quy với g=([n,...s],i=3,t=0)=>n?g(s,4-i,t+n*i):t%10<1, nhưng bạn có thể đã tìm thấy một cách tốt hơn ...
ETHproductions

Cảm ơn, @ETHproductions, tôi đã đổi thành map, cái mà tôi nghĩ là hoạt động tốt hơn vì đầu vào có thể là một danh sách các chữ số thay vì một chuỗi.
Rick Hitchcock

Có lẽ lưu một byte khác với s=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1?
Sản xuất ETH

Vâng, tuyệt vời, cảm ơn :)
Rick Hitchcock

Giải pháp tuyệt vời! Bạn có thể thay thế &&bằng |đầu ra 1/0 vì sự thật / giả được cho phép không?
Craig Ayre


8

Thạch , 8 byte

m2Ḥ+µS⁵ḍ

Hãy thử bộ thử nghiệm.

Thạch , 9 byte

JḂḤ‘×µS⁵ḍ

Dùng thử trực tuyến hoặc Thử bộ thử nghiệm.

Làm thế nào điều này hoạt động

m2Ḥ + TIẾNG ~ Chương trình đầy đủ.

m2 ~ Modular 2. Trả về mọi phần tử thứ hai của đầu vào.
  Ḥ ~ Nhân đôi mỗi cái.
   + Tập ~ Nối đầu vào và bắt đầu một chuỗi đơn âm mới.
     S ~ Tổng.
      ⁵ḍ ~ Có chia hết cho 10 không?
JḂḤ '× GianS⁵ḍ ~ Chương trình đầy đủ (đơn âm).

J ~ 1 phạm vi độ dài chỉ mục.
 Ḃ ~ Bit; Modulo mỗi số trong phạm vi trên bằng 2.
  Ḥ ~ Nhân đôi mỗi cái.
   '~ Tăng mỗi.
    × ~ Nhân đôi với đầu vào.
     Tổ hợp ~ Bắt đầu một chuỗi đơn nguyên mới.
      S ~ Tổng.
       ⁵ḍ ~ Tổng có chia hết cho 10 không?

Kết quả cho 7 chữ số đầu tiên của mã vạch và chữ số tổng kiểm tra phải thêm vào bội số của 10 để nó có hiệu lực. Do đó, tổng kiểm tra là hợp lệ nếu thuật toán được áp dụng cho toàn bộ danh sách chia hết cho 10 .


Vẫn còn 9 byte nhưng với các giá trị nhất quán:JḂḤ‘×µS⁵ḍ
HyperNeutrino

@HyperNeutrino Cảm ơn, tôi biết có một nguyên tử cho việc này!
Ông Xcoder

Ngoài ra 9 byte :: JḂaḤ+µS⁵ḍP
HyperNeutrino

@HyperNeutrino Vâng, có rất nhiều lựa chọn thay thế: P
Ông Xcoder

1
8 byte hay 8 ký tự? m2Ḥ+µS⁵ḍlà 15 byte trong UTF-8, trừ khi tôi tính toán sai.
ta.speot.is

7

MATL , 10 byte

Cảm ơn @Zgarb đã chỉ ra một lỗi, giờ đã sửa.

IlhY"s10\~

Hãy thử trực tuyến! Hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình

Ilh     % Push [1 3]
Y"      % Implicit input. Run-length decoding. For each entry in the
        % first input, this produces as many copies as indicated by
        % the corresponding entry of the second input. Entries of
        % the second input are reused cyclically
s       % Sum of array
10\     % Modulo 10
~       % Logical negate. Implicit display

7

Befunge-98 (PyFunge) , 16 14 byte

Đã lưu 2 byte bằng cách bỏ qua phần thứ hai bằng cách sử dụng jthay vì ;s, cũng như hoán đổi phần a ~+phần thứ nhất để loại bỏ +phần thứ hai.

~3*+~+6jq!%a+2

Đầu vào có 8 chữ số (có 0 đầu nếu có) và không có gì khác.

Đầu ra thông qua mã thoát (mở trình đơn gỡ lỗi trên TIO), trong đó 1 là đúng và 0 là sai.

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

Giải trình

Chương trình này sử dụng nhiều thủ thuật.

Trước hết, nó lấy các chữ số từng cái một thông qua các giá trị ASCII của chúng. Thông thường, điều này sẽ yêu cầu trừ 48 từ mỗi giá trị khi chúng ta đọc nó từ đầu vào. Tuy nhiên, nếu chúng tôi không sửa đổi nó, chúng tôi còn lại 16 (3 + 1 + 3 + 1 + 3 + 1 + 3 + 1) các bản sao bổ sung của 48 trong tổng của chúng tôi, có nghĩa là tổng số của chúng tôi sẽ lớn hơn 768 những gì nó "nên" là. Vì chúng tôi chỉ quan tâm đến tổng mod 10, nên chúng tôi chỉ có thể thêm 2 vào tổng sau. Do đó, chúng ta có thể nhận các giá trị ASCII thô, tiết kiệm 6 byte hoặc hơn.

Thứ hai, mã này chỉ kiểm tra nếu mọi ký tự khác là EOF, vì đầu vào được đảm bảo chỉ dài 8 ký tự.

Thứ ba, #ở cuối dòng không bỏ qua ký tự đầu tiên, nhưng sẽ bỏ qua ;nếu đến từ hướng khác. Điều này tốt hơn là đặt một #;ở phía trước thay thế.

Vì phần thứ hai của chương trình của chúng tôi chỉ chạy một lần, chúng tôi không phải thiết lập chương trình để nó bỏ qua nửa đầu khi chạy ngược. Điều này cho phép chúng ta sử dụng lệnh nhảy để nhảy qua nửa thứ hai, khi chúng ta thoát ra trước khi thực hiện nó đi lùi.

Từng bước một

Lưu ý: Các ký tự "lẻ" và "chẵn" dựa trên hệ thống được lập chỉ mục 0. Ký tự đầu tiên là số chẵn, có chỉ số 0.

~3*+~+      Main loop - sum the digits (with multiplication)
~           If we've reached EOF, reverse; otherwise take char input. This will always
                be evenly indexed values, as we take in 2 characters every loop.
 3*+        Multiply the even character by 3 and add it to the sum.
    ~       Then, take an odd digit - we don't have to worry about EOF because
                the input is always 8 characters.
     +      And add it to the sum.
      6j    Jump over the second part - We only want to run it going backwards.

        q!%a+2    The aftermath (get it? after-MATH?)
            +2    Add 2 to the sum to make up for the offset due to reading ASCII
          %a      Mods the result by 10 - only 0 if the bar code is valid
         !        Logical not the result, turning 0s into 1s and anything else into 0s
        q         Prints the top via exit code and exits


6

Ngôn ngữ Wolfram (Mathicala) , 26 21 byte

10∣(2-9^Range@8).#&

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

Lấy đầu vào là một danh sách gồm 8 chữ số.

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

2-9^Range@8là modulo đồng dạng 10 đến 2-(-1)^Range@8, đó là {3,1,3,1,3,1,3,1}. Chúng tôi lấy sản phẩm chấm của danh sách này với đầu vào và kiểm tra xem kết quả có chia hết cho 10 không.

Ngôn ngữ Wolfram (Mathicala) , 33 byte và không cạnh tranh

Check[#~BarcodeImage~"EAN8";1,0]&

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

Đưa đầu vào dưới dạng một chuỗi. Trả về 1mã vạch hợp lệ và 0cho mã không hợp lệ.

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

Điều tốt nhất tôi có thể tìm thấy theo cách tích hợp (vì Mathematica là tất cả về những thứ đó).

Bit bên trong #~BarcodeImage~"EAN8";1, tạo ra hình ảnh của mã vạch EAN8, sau đó bỏ qua hoàn toàn và đánh giá thành 1. Tuy nhiên, nếu mã vạch không hợp lệ, sau đó BarcodeImagetạo cảnh báo, Checkbắt, trả về 0 trong trường hợp đó.


3
Bạn đang thực hiện tính toán bằng tay vì nó ngắn hơn hay vì Wolfram chưa có hàm ValidateESE8BarCode () ở đâu đó trong thư viện chuẩn của nó?
Đánh dấu

1
@Mark Mathematica không thể xác thực mã vạch trực tiếp, nhưng tôi vừa tìm thấy BarcodeImage, nó tạo ra hình ảnh của mã vạch và xác thực mã vạch trong quy trình. Vì vậy, Check[#~BarcodeImage~"EAN8";0,1]<1&sẽ làm việc (nhưng nó dài hơn).
Misha Lavrov

5

Java 8, 58 56 55 byte

a->{int r=0,m=1;for(int i:a)r+=(m^=2)*i;return r%10<1;}

-2 byte gián tiếp nhờ vào @RickHitchcock , bằng cách sử dụng (m=4-m)*ithay vì m++%2*2*i+isau khi thấy nó trong câu trả lời JavaScript của mình .
-1 byte gián tiếp nhờ vào @ETH sản phẩm (và @RickHitchcock ), bằng cách sử dụng (m^=2)*ithay vì (m=4-m)*i.

Giải trình:

Hãy thử nó ở đây.

a->{              // Method with integer-array parameter and boolean return-type
  int r=0,        //  Result-sum
      m=1;        //  Multiplier
  for(int i:a)    //  Loop over the input-array
    r+=           //   Add to the result-sum:
       (m^=2)     //    Either 3 or 1,
       *i;        //    multiplied by the digit
                  //  End of loop (implicit / single-line body)
  return r%10<1;  //  Return if the trailing digit is a 0
}                 // End of method

1
Bạn có thể lưu một byte khác bằng một mẹo @ETH sản phẩm cho tôi thấy: thay đổi m=4-mthành m^=2.
Rick Hitchcock

@RickHitchcock Ah, tất nhiên .. Tôi sử dụng ^=1khá thường xuyên trong câu trả lời khi tôi muốn thay đổi giữa 01. ^=2hoạt động trong trường hợp này để thay đổi giữa 13. Thủ thuật hay, và cảm ơn vì nhận xét đã đề cập đến nó. :)
Kevin Cruijssen

4

05AB1E , 14 byte

θ¹¨3X‚7∍*O(T%Q

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

Cần 0s hàng đầu , có danh sách các chữ số.


Có vẻ thất bại trên 3100004(nên là sự thật).
Zgarb

@Zgarb Bạn đang thiếu một cái 0đó.
Erik người vượt trội

Oh, nó cần một chuỗi? Được rồi, xấu của tôi.
Zgarb

@Zgarb Vâng, bạn có thể bỏ qua các trích dẫn, nhưng vâng, bạn cần hàng đầu 0. Câu trả lời này thực sự sử dụng các hàm số trên chuỗi, một trong những tính năng của 05AB1E.
Erik the Outgolfer

@ Mr.Xcoder Câu hỏi không rõ lắm về điều đó, tôi sẽ thêm một mã khác xử lý vấn đề đó bên dưới.
Erik the Outgolfer

4

Bình thường , 8 byte

!es+*2%2

Xác nhận tất cả các trường hợp thử nghiệm!

Bình thường , 13 byte

Nếu chúng ta có thể giả sử đầu vào luôn có đúng 8 chữ số:

!es.e*bhy%hk2

Xác nhận tất cả các trường hợp thử nghiệm!


Cái này hoạt động ra sao?

! es + * 2% 2 ~ Chương trình đầy đủ.

      % 2 ~ Đầu vào [:: 2]. Mỗi yếu tố thứ hai của đầu vào.
    * 2 ~ Double (lặp lại danh sách hai lần).
   + ~ Nối đầu vào.
  s ~ Tổng.
 e ~ Chữ số cuối.
! ~ Logic KHÔNG.
! es.e * sbhy% hk2 ~ Chương trình đầy đủ.

               ~ Chuyển đổi đầu vào thành Chuỗi.
   .e ~ Bản đồ được liệt kê, lưu trữ giá trị hiện tại theo b và chỉ mục theo k.
          % hk2 ~ chẵn lẻ của chỉ số. (k + 1)% 2.
        hy ~ Nhân đôi, tăng dần. Điều này ánh xạ các số nguyên lẻ thành 1 và thậm chí là 3.
      b ~ Chữ số hiện tại.
     * ~ Nhân lên.
  s ~ Tổng.
 e ~ Chữ số cuối.
! ~ Phủ định logic.

Nếu tổng của 7 chữ số đầu tiên sau khi được áp dụng, thuật toán sẽ bị trừ đi 10 và sau đó so với chữ số cuối cùng, điều này tương đương với việc kiểm tra xem tổng của tất cả các chữ số hay không, sau khi thuật toán được áp dụng là bội số của 10 .


Có vẻ thất bại trên 3100004(nên là sự thật).
Zgarb

@Zgarb Chờ chúng ta nên làm 3*3+1*1+0*3+...hay 0*3+3*1+1*0..? Tôi nghĩ rằng chúng tôi phải làm điều trước đây
Ông Xcoder

Trong thông số kỹ thuật mới, các chữ số hàng đầu được thêm vào để đảm bảo có chính xác 8 (nếu tôi hiểu chính xác).
Zgarb

@Zgarb Ok, đã sửa.
Ông Xcoder


4

Võng mạc , 23 22 byte

-1 byte nhờ Martin Ender !

(.).
$1$1$&
.
$*
M`
1$

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

Giải trình

Ví dụ đầu vào: 20378240

(.).
$1$1$&

Thay thế mỗi vài chữ số bằng chữ số đầu tiên được lặp lại hai lần theo sau bởi chính cặp số đó. Chúng tôi nhận được2220333788824440

.
$*

Chuyển đổi từng chữ số để unary. Với dấu ngoặc đơn được thêm vào cho rõ ràng, chúng tôi nhận được(11)(11)(11)()(111)(111)...

M`

Đếm số lượng khớp của chuỗi trống, nhiều hơn số lượng của chuỗi trong chuỗi. (Với hai bước cuối cùng, về cơ bản chúng tôi đã lấy tổng của từng chữ số +1) Kết quả:60

1$

Nối a 1ở cuối chuỗi. Chúng tôi đã nhân các chữ số với 3 và 1 xen kẽ và tính tổng chúng, đối với mã vạch hợp lệ, số này sẽ chia hết cho 10 (chữ số cuối 0); nhưng chúng tôi cũng đã thêm 1 ở bước cuối cùng, vì vậy chúng tôi muốn chữ số cuối cùng là 1. Kết quả cuối cùng : 1.


2
Tôi nghĩ rằng bạn có thể thả .trên sân khấu trận đấu và trận đấu 1$ở cuối.
Martin Ender

@MartinEnder rất hay, tôi sẽ làm điều đó, cảm ơn!
Leo

3

PowerShell , 85 byte

param($a)(10-(("$a"[0..6]|%{+"$_"*(3,1)[$i++%2]})-join'+'|iex)%10)%10-eq+"$("$a"[7])"

Hãy thử trực tuyến! hoặc Xác minh tất cả các trường hợp kiểm tra

Triển khai thuật toán theo định nghĩa. Đưa đầu vào $a, kéo ra từng chữ số "$a"[0..6]và lặp qua chúng với |%{...}. Mỗi lần lặp, chúng ta lấy chữ số, đúc nó thành một chuỗi "$_"sau đó đúc nó thành một số nguyên +trước khi nhân nó với một 3hoặc 1(được chọn bằng cách tăng $imodulo 2).

Những kết quả đó được tập hợp lại với nhau và tổng hợp -join'+'|iex. Chúng tôi lấy mod kết quả đó 10, trừ đi từ đó 10và một lần nữa lấy mod kết quả 10(mod thứ hai này là cần thiết để tính toán cho 00000000trường hợp thử nghiệm). Sau đó chúng tôi kiểm tra xem đó có -eqphải là chữ số cuối cùng không. Kết quả Boolean đó được để lại trên đường ống và đầu ra là ẩn.


Có vẻ thất bại trên 3100004(nên là sự thật).
Zgarb

@Zgarb Làm việc cho tôi? Hãy thử trực tuyến!
admBorkBork

Ah ok, tôi đã thử nó mà không có dấu ngoặc kép.
Zgarb

@Zgarb À, ừ. Nếu không có dấu ngoặc kép, PowerShell sẽ hoàn toàn truyền dưới dạng một số nguyên, tước số 0 đứng đầu.
admBorkBork

3

Thạch , 16 byte

ż3,1ṁ$P€SN%⁵
Ṫ=Ç

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

lấy đầu vào là một danh sách các chữ số


Nitpick: thời gian chờ TIO của bạn. Ngoài ra, 16 byte .
Erik the Outgolfer

@EriktheOutgolfer Chờ gì thế nào. Nó hoạt động khi tôi đặt Dchân trang. Và cảm ơn bạn! : D
HyperNeutrino

@EriktheOutgolfer Tôi có làm gì sai không? 16 -ter của bạn dường như không hợp lệ?
HyperNeutrino

Có thể, nó hoạt động hơi khác, nhưng bạn có vẻ hơi không hợp lệ ... cụ thể là tôi nghĩ dòng cuối cùng nên có DµṪ=Ç.
Erik the Outgolfer

1
Có vẻ thất bại trên 3100004(nên là sự thật).
Zgarb

3

APL (Dyalog) , 14 byte

Tương đương với giải pháp của streetster .

Toàn thân chương trình. Nhắc nhở danh sách các số từ STDIN.

0=10|+/⎕×83 1

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

Là…

0= không bằng

10| mod-10 của

+/ Tổng của

⎕× thời gian đầu vào

8⍴3 1 tám yếu tố được lấy theo chu kỳ từ [3,1]

?


1
Bạn có nghĩa là APL không thể làm điều đó trong một nhân vật từ một cái gì đó như Ancient Sumerian hoặc Tuyến tính B?
Đánh dấu

tàu: 0 = 10 | - / + 2 × + /
ngn

3

05AB1E , 9 byte

3X‚7∍*OTÖ

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

3X‚7∍*OTÖ    # Argument a
3X‚          # Push [3, 1]
   7∍        # Extend to length 7
     *       # Multiply elements with elements at same index in a
      O      # Total sum
       TÖ    # Divisible by 10

Tốt đẹp! Điều đầu tiên tôi nghĩ là "kéo dài theo chiều dài" khi tôi thấy cái này, chưa sử dụng cái đó.
Bạch tuộc ma thuật Urn

31×S*OTÖcho 8 byte. ×chỉ cần đẩy 31 nlần. Khi bạn nhân lên, nó sẽ tự động giảm thêm 31 giây.
Bạch tuộc ma thuật Urn

@MagicOctopusUrn Điều đó dường như thất bại trong bài kiểm tra thứ 669165430 -> 1
kalsowerus

3

J, 17 byte

-10 byte nhờ cole

0=10|1#.(8$3 1)*]

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

Điều này sử dụng phép nhân các danh sách có kích thước bằng nhau để tránh kết hợp zip / nhân của giải pháp ban đầu, cũng như "thủ thuật cơ sở 1" 1#.để thêm các sản phẩm lại với nhau. Cách tiếp cận cấp cao tương tự như lời giải thích ban đầu.

bản gốc, 27 byte

0=10|{:+[:+/[:*/(7$3 1),:}:

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

giải thích

0 =                                        is 0 equal to... 
    10 |                                   the remainder when 10 divides...
         {: +                              the last input item plus...
              [: +/                        the sum of...
                    [: */                  the pairwise product of...
                          7$(3 1) ,:       3 1 3 1 3 1 3 zipped with...
                                     }:    all but the last item of the input

0=10|1#.(8$3 1)*]nên hoạt động với 17 byte (cũng thực hiện cùng một thuật toán). Tôi khá chắc chắn rằng trong bản beta, bạn có thể có một cái móc kết thúc ở phía bên phải với một danh từ, vì vậy 0=10|1#.]*8$3 1có thể hoạt động trong 15 (Tôi sẽ kiểm tra trên tio nhưng nó dường như không hoạt động?)
cole

@cole, tôi thích sự cải thiện này. Tôi đã tìm hiểu và quên đi 1#.mánh khóe như 2 hoặc 3 lần ... cảm ơn vì đã nhắc nhở tôi. Oh btw phiên bản 15 byte không hoạt động trong TIO.
Giô-na

3

C (gcc), 84 82 72 61 54 byte

c;i;f(x){for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;c=c%10<1;}

-21 byte từ Neil

-7 byte từ Nahuel Fouilleul

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

Được phát triển độc lập với câu trả lời của Steadybox

'F' là một hàm lấy mã vạch làm số intvà trả về 1True và 0sai.

  • flưu trữ các chữ số cuối cùng của xnăm s( s=x%10),

  • Sau đó tính tổng trong c( for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;)

    • clà tổng, ilà một bộ đếm

    • đối với mỗi chữ số bao gồm chữ số đầu tiên, hãy thêm số 1+2*i%4lần chữ số ( x%10) vào tổng kiểm tra và số gia i(số i++trong 3-2*i++%4)

      • 1+2*i%4là 1 khi ichẵn và 0 khi ilẻ
  • Sau đó trả về cho dù tổng là bội số của mười và vì chúng tôi đã thêm chữ số cuối cùng (nhân với 1), tổng sẽ là bội số của mười iff mã vạch là hợp lệ. (sử dụng hành vi không xác định phụ thuộc GCC để bỏ qua return).


Tôi nghĩ (x%10)có thể giống xnhư bạn đang dùng c%10sau này. Ngoài ra tôi nghĩ rằng bạn có thể sử dụng i<8và sau đó chỉ cần kiểm tra xem c%10cuối cùng có bằng không.
Neil

@Neil Cảm ơn! Điều đó có -10 byte.
pizzapants184

Trong thực tế tôi nghĩ slà không cần thiết:c;i;f(x){for(i=c=0;i<8;x/=10)c+=(1+2*i++%4)*x;return c%10<1;}
Neil

liên kết tio là 61 byte nhưng trong câu trả lời là 72, cũng không biết tại sao x=c%10<1hoặc c=c%10<1thay vì return c%10<1vẫn hoạt động
Nahuel Fouilleul

cũng i<8có thể được thay thế bằngx
Nahuel Fouilleul

3

C, 63 byte

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10;}

Giả sử đó 0truevà bất kỳ giá trị khác là false.

+3 byte cho giá trị trả về tốt hơn

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10==0;}

Thêm ==0vào returntuyên bố.

Bị đánh cắp

int check(int* values)
{
    int result = 0;
    for (int index = 0; index < 8; index++)
    {
        result += v[i] * 3 + v[++i]; // adds this digit times 3 plus the next digit times 1 to the result
    }
    return result % 10 == 0; // returns true if the result is a multiple of 10
}

Điều này sử dụng định nghĩa thay thế của tổng kiểm tra EAN trong đó số kiểm tra được chọn sao cho tổng kiểm tra của toàn bộ mã vạch bao gồm cả số kiểm tra là bội số của 10. Về mặt toán học, việc này giống nhau nhưng việc viết đơn giản hơn rất nhiều.

Khởi tạo các biến trong vòng lặp theo đề xuất của Steadybox, 63 byte

i;s;c(int*v){for(i=s=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10;}

Xóa dấu ngoặc nhọn theo đề xuất của Steadybox, 61 byte

i;s;c(int*v){for(i=s=0;i<8;i++)s+=v[i]*3+v[++i];return s%10;}

Sử dụng <1thay vì ==0cho giá trị hoàn trả tốt hơn theo đề xuất của Kevin Cruijssen

i;s=0;c(int*v){for(i=0;i<8;i++){s+=v[i]*3+v[++i];}return s%10<1;}

Thêm <1vào returncâu lệnh, điều này chỉ thêm 2 byte thay vì ==0thêm 3 byte.


Bạn có thể lưu hai byte bằng cách loại bỏ {}sau for. Ngoài ra, các chức năng đệ trình phải được sử dụng lại , vì vậy bạn cần khởi tạo sbên trong chức năng (chỉ cần thay đổi i;s=0;thành i,s;i=0;thành i=s=0;).
Steadybox

@Steadybox Làm cách nào để xóa dấu ngoặc nhọn?
Micheal Johnson

Chỉ có một tuyên bố bên trong họ. Khi không có dấu ngoặc nhọn sau for, thân vòng lặp sẽ là câu lệnh tiếp theo. for(i=0;i<8;i++){s+=v[i]*3+v[++i];}cũng giống như for(i=0;i<8;i++)s+=v[i]*3+v[++i];.
Steadybox

@Steadybox Tất nhiên rồi. Đó là một trong những điểm kỳ quặc của cú pháp C mà tôi thường quên, bởi vì khi viết mã bình thường, tôi luôn bao gồm các dấu ngoặc nhọn ngay cả khi chúng không cần thiết, bởi vì nó làm cho mã dễ đọc hơn.
Micheal Johnson

Trong câu trả lời đúng / sai của bạn, thay vì +3 bằng cách thêm ==0nó có thể là +2 bằng cách sử dụng <1thay thế. :)
Kevin Cruijssen

2

JavaScript (Node.js) , 47 byte

e=>eval(e.map((a,i)=>(3-i%2*2)*a).join`+`)%10<1

Mặc dù đã có câu trả lời ngắn hơn nhiều, nhưng đây là lần đầu tiên tôi chơi golf trong JavaScript vì vậy tôi muốn nghe các đề xuất về chơi gôn :-)

Kiểm tra

Ngoài ra, bạn có thể dùng thử trực tuyến!


2

Perl 5, 37 32 + 1 (-p) byte

s/./$-+=$&*(--$|*2+1)/ge;$_=/0$/

-5 byte nhờ vào Dom Hastings. 37 +1 byte là

$s+=$_*(++$i%2*2+1)for/./g;$_=!!$s%10

thử trực tuyến


1
Có một chút chơi với điều này và nghĩ rằng tôi sẽ chia sẻ một mẹo hữu ích: --$|chuyển đổi giữa 10vì vậy bạn có thể sử dụng nó thay vì ++$i%2cho một boolean xen kẽ! Ngoài ra, tất cả những gì quan trọng là tổng số ( $s) khớp /0$/, được quản lý để có được 33 byte kết hợp những thay đổi đó với s///: Hãy thử trực tuyến! ( -lchỉ dành cho khả năng hiển thị)
Dom Hastings

vâng tôi mặc dù s/./(something with $&)/gevà để /0$/phù hợp nhưng không kết hợp cả hai.
Nahuel Fouilleul

2

Brainfuck, 228 byte

>>>>++++[<++>-]<[[>],>>++++++[<++++++++>-]<--[<->-]+[<]>-]>[->]<<<<[[<+>->+<]<[>+>+<<-]>>[<+>-]<<<<<]>>>>[>>[<<[>>+<<-]]>>]<<<++++[<---->-]+++++[<++<+++>>-]<<[<[>>[<<->>-]]>[>>]++[<+++++>-]<<-]<[[+]-<]<++++++[>++[>++++<-]<-]>>+.

Có lẽ có thể được cải thiện một chút công bằng. Đầu vào được lấy 1 chữ số tại một thời điểm, đầu ra 1 cho đúng, 0 cho sai.

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

>>>>++++[<++>-]<

Đặt 8 ở vị trí 3.

[[>],>>++++++[<++++++++>-]<--[<->-]+[<]>-]

Mất 8 lần nhập, thay đổi từ giá trị ascii thành giá trị thực +2 mỗi lần. Các đầu vào được đặt cách nhau bởi các đầu vào, sẽ được loại bỏ, để cho phép nhân dễ dàng hơn sau này.

>[->]

Trừ một từ mỗi mục. Băng của chúng tôi bây giờ trông giống như

0 0 0 0 4 0 4 0 8 0 7 0 6 0 2 0 3 0 10 0 0
                                         ^

Với mỗi giá trị 1 nhiều hơn mức cần thiết. Điều này là do số không sẽ làm rối quá trình nhân của chúng tôi.

Bây giờ chúng tôi đã sẵn sàng để bắt đầu nhân lên.

<<<<

Đi đến mục thứ hai đến mục cuối cùng.

[[<+>->+<]<[>+>+<<-]>>[<+>-]<<<<<]

Trong khi không, nhân số đó với ba, sau đó di chuyển hai mục sang trái. Bây giờ chúng tôi đã nhân mọi thứ chúng tôi cần lên gấp ba và chúng tôi ở vị trí đầu tiên trên băng.

>>>>[>>[<<[>>+<<-]]>>]

Tổng hợp toàn bộ danh sách.

<<<++++[<---->-]

Giá trị chúng tôi có nhiều hơn 16 so với giá trị thực tế. Khắc phục điều này bằng cách trừ 16.

+++++[<++<+++>>-]

Chúng ta cần kiểm tra xem tổng có phải là bội số của 10. Tổng tối đa là với tất cả 9 hay không, là 144. Vì không có tổng nào sẽ lớn hơn 10 * 15, đặt 15 và 10 vào băng, theo thứ tự đó và đúng quyền của tổng.

<<[<[>>[<<->>-]]>[>>]++[<+++++>-]<<-]

Di chuyển đến nơi 15 là. Trong khi nó khác không, hãy kiểm tra xem tổng có khác không không. Nếu có, trừ 10 từ nó. Bây giờ chúng tôi hoặc ở vị trí tổng (trống) hoặc trên vị trí mười (cũng trống). Di chuyển một quyền. Nếu chúng ta ở vị trí tổng, thì bây giờ chúng ta ở vị trí khác không 15. Nếu vậy, di chuyển đúng hai lần. Bây giờ chúng tôi ở cùng một vị trí trong cả hai trường hợp. Thêm mười vào vị trí mười và trừ một từ vị trí 15.

Phần còn lại dành cho đầu ra:

<[[+]-<]<++++++[>++[>++++<-]<-]>>+.

Di chuyển đến vị trí tổng. Nếu nó khác không (âm), mã vạch không hợp lệ; đặt vị trí thành -1. Bây giờ thêm 49 để nhận giá trị ascii chính xác: 1 nếu hợp lệ, 0 nếu không hợp lệ.


2

Java 8, 53 byte

Chơi gôn

b->(3*(b[0]+b[2]+b[4]+b[6])+b[1]+b[3]+b[5]+b[7])%10<1

Tính toán trực tiếp trong lambda dường như là giải pháp ngắn nhất. Nó phù hợp trong một biểu thức duy nhất, giảm thiểu chi phí lambda và loại bỏ các khai báo biến và dấu chấm phẩy bên ngoài.

public class IsMyBarcodeValid {

  public static void main(String[] args) {
    int[][] barcodes = new int[][] { //
        { 2, 0, 3, 7, 8, 2, 4, 0 }, //
        { 3, 3, 7, 6, 5, 1, 2, 9 }, //
        { 7, 7, 2, 3, 4, 5, 7, 5 }, //
        { 0, 0, 0, 0, 0, 0, 0, 0 }, //
        { 2, 1, 0, 3, 4, 9, 8, 4 }, //
        { 6, 9, 1, 6, 5, 4, 3, 0 }, //
        { 1, 1, 9, 6, 5, 4, 2, 1 }, //
        { 1, 2, 3, 4, 5, 6, 7, 8 } };
    for (int[] barcode : barcodes) {
      boolean result = f(b -> (3 * (b[0] + b[2] + b[4] + b[6]) + b[1] + b[3] + b[5] + b[7]) % 10 < 1, barcode);
      System.out.println(java.util.Arrays.toString(barcode) + " = " + result);
    }
  }

  private static boolean f(java.util.function.Function<int[], Boolean> f, int[] n) {
    return f.apply(n);
  }
}

Đầu ra:

[2, 0, 3, 7, 8, 2, 4, 0] = true
[3, 3, 7, 6, 5, 1, 2, 9] = true
[7, 7, 2, 3, 4, 5, 7, 5] = true
[0, 0, 0, 0, 0, 0, 0, 0] = true
[2, 1, 0, 3, 4, 9, 8, 4] = false
[6, 9, 1, 6, 5, 4, 3, 0] = false
[1, 1, 9, 6, 5, 4, 2, 1] = false
[1, 2, 3, 4, 5, 6, 7, 8] = false

2

QBasic, 54 52 byte

Ugh, câu trả lời nhàm chán hóa ra là ngắn nhất:

INPUT a,b,c,d,e,f,g,h
?(3*a+b+3*c+d+3*e+f+3*g+h)MOD 10=0

Điều này nhập các chữ số được phân tách bằng dấu phẩy. Giải pháp 54 byte ban đầu của tôi, nhập một chữ số tại một thời điểm, sử dụng cách tiếp cận "đẹp hơn":

m=3
FOR i=1TO 8
INPUT d
s=s+d*m
m=4-m
NEXT
?s MOD 10=0

2

C # (.NET Core) , 65 62 byte

b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}

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

Lời cảm ơn

-3 byte nhờ @KevinCruijssen và thủ thuật gọn gàng bằng cách sử dụng toán tử độc quyền hoặc.

Khói

b=>{
    int s=0,i=0,t=1;

    while(i<8)
        s+=b[i++]*(t^=2); // exclusive-or operator alternates t between 3 and 1.

    return s%10<1;
}

C # (.NET Core) , 53 byte

b=>(3*(b[0]+b[2]+b[4]+b[6])+b[1]+b[3]+b[5]+b[7])%10<1

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

Một cổng trực tiếp câu trả lời của @ Snowman .


Đối với câu trả lời đầu tiên của bạn: b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}( 62 byte ) hoặc thay thế bằng một foreach, cũng là 62 byte: b=>{int s=0,t=1;foreach(int i in b)s+=i*(t^=2);return s%10<1;}(là một cổng của câu trả lời Java 8 của tôi ).
Kevin Cruijssen

1

MATLAB / Octave , 32 byte

@(x)~mod(sum([2*x(1:2:7),x]),10)

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

Tôi sẽ đăng bài này mặc dù câu trả lời khác của Octave khi tôi phát triển mã và cách tiếp cận này mà không cần nhìn vào các câu trả lời khác.

Ở đây chúng ta có một hàm ẩn danh lấy đầu vào là một mảng gồm 8 giá trị và trả về true nếu mã vạch hợp lệ, sai khác ..

Kết quả được tính như sau.

              2*x(1:2:7)
             [          ,x]
         sum(              )
     mod(                   ,10)
@(x)~
  1. Các chữ số lẻ (một chỉ mục) được nhân với 2.
  2. Kết quả được thêm vào mảng đầu vào, đưa ra một mảng có tổng sẽ chứa các chữ số lẻ ba lần và các chữ số chẵn một lần.
  3. Chúng tôi thực hiện tổng số cũng sẽ bao gồm tổng kiểm tra được cung cấp trong tổng của chúng tôi.
  4. Tiếp theo modulo 10 được thực hiện. Nếu tổng kiểm tra được cung cấp là hợp lệ, tổng của tất cả các chữ số nhân bao gồm giá trị tổng kiểm tra sẽ là bội số của 10. Do đó, chỉ một mã vạch hợp lệ sẽ trả về 0.
  5. Kết quả được đảo ngược để có được đầu ra logic là đúng nếu hợp lệ.

1

Excel, 37 byte

Giải thích "Danh sách 8 số nguyên" khi cho phép 8 ô riêng biệt trong Excel:

=MOD(SUM(A1:H1)+2*(A1+C1+E1+G1),10)=0

= MOD (SUM ((A1: H1) + 2 * (A1 + C1 + E1 + G1)), 10) = 0 công thức này có tồn tại trong Excel không?
RosLuP

@RosLuP, không được xác định trước, không. Nhưng Modulo, Sum, + vv làm ;-)
Wernisch

Tôi chỉ muốn nói rằng dường như trong APL hoạt động tốt trước tiên y = (A1: H1) + 2 * (A1 + C1 + E1 + G1), và sau tổng và mod; trong APL không diễn ra tốt, tổng đầu tiên (A1: H1), v.v. (1,2,3) + 4 = (5,6,7) và hơn tổng (5,6,7) = 18; lưu ý rằng tổng (1,2,3) = 6 và 6 + 4 = 10 khác với 18. Nhưng có thể tôi mắc lỗi trong một cái gì đó
RosLuP

@RosLuP, Xin lỗi, đã bỏ lỡ các thay đổi ()trong nhận xét của bạn.
Wernisch

Vấn đề là cách Excel diễn giải =(A1:H1): Điều này không được xử lý như một mảng. Không hợp lệ nếu được đặt trong bất kỳ cột nào không nằm trong A-Hphạm vi. Nếu được đặt trong một cột trong AH, chỉ trả về giá trị cho cột đó. (Công thức tính theo% kết quả tính theo%: C2 -> C1 H999 -> H1 K1 -> #VALUE!)
Wernisch

1

Ruby, 41 byte

Có một loạt các số nguyên. -6 byte nhờ Jordan.

->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}

Tốt đẹp! FWIW bạn không cần mapở đây: zipmất một khối. Bạn có thể lưu thêm một vài byte bằng cách sử dụng $.thay vì khởi tạo s:->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
Jordan

1

TI-Basic (sê-ri 83), 18 byte

not(fPart(.1sum(2Ans-Ans9^cumSum(binomcdf(7,0

Đưa đầu vào như một danh sách trong Ans. Trả về 1mã vạch hợp lệ và0 cho không hợp lệ.

Một cổng của câu trả lời Mathicala của tôi . Bao gồm ảnh chụp màn hình, thay cho môi trường thử nghiệm trực tuyến:

ảnh chụp màn hình mã vạch

Tính năng đáng chú ý: binomcdf(7,0được sử dụng để tạo danh sách {1,1,1,1,1,1,1,1}(danh sách xác suất mà từ 7 thử nghiệm có xác suất thành công 0, sẽ có nhiều nhất N thành công, với N = 0,1, ..., 7). Sau đó, cumSum(biến điều này thành{1,2,3,4,5,6,7,8} .

Đây là một byte ngắn hơn so với sử dụng seq(lệnh, mặc dù về mặt lịch sử, điểm này là nó cũng nhanh hơn đáng kể.

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.