A barcode of EAN-13 symbology consists of 13 digits (0-9). The last digit of this barcode is its check digit. It is calculated by the following means (the barcode 8923642469559 is used as an example):
Starting from the second digit, sum up all alternating digits and multiply the sum by 3:
8 9 2 3 6 4 2 4 6 9 5 5 9 | | | | | | 9 +たす 3 +たす 4 +たす 4 +たす 9 +たす 5 =わ 34 | 34 ×ばつ 3 = 102Then, sum up all of the remaining digits, but do not include the last digit:
8 9 2 3 6 4 2 4 6 9 5 5 9 | | | | | | 8 +たす 2 +たす 6 +たす 2 +たす 6 +たす 5 =わ 29Add the numbers obtained in steps 1 and 2 together:
29 + 102 = 131The number you should add to the result of step 3 to get to the next multiple of 10 (140 in this case) is the check digit.
If the check digit of the barcode matches the one calculated as explained earlier, the barcode is valid.
More examples:
6537263729385 is valid.
1902956847427 is valid.
9346735877246 is invalid. The check digit should be 3, not 6.
Your goal is to write a program that will:
- Receive a barcode as its input.
- Check whether the barcode is valid
- Return 1 (or equivalent) if the barcode is valid, 0 (or equivalent) otherwise.
This is code-golf, so the shortest code in terms of bytes wins.
13 Answers 13
05AB1E, (削除) 15 (削除ここまで) 10 bytes
εNÉ·>*}OTÖ
Explanation
ε } # apply to each digit
NÉ # is the current index odd?
·> # double and increment(yielding 1 or 3)
* # multiply by the current number
O # sum all modified digits
TÖ # is evenly divisible by 10
-
\$\begingroup\$ Nice answer! Definitely shorter than what I was working on. I like the
xyou've used in combination withOto sum the entire stack in one go to combine the*3and+of the two numbers. As well as the(T%to get the remainder. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年10月22日 13:28:15 +00:00Commented Oct 22, 2018 at 13:28 -
\$\begingroup\$ @KevinCruijssen: The comparison feels a bit surperflous. Can you think of a counterexample to εNÉ·>*}OTÖ working? \$\endgroup\$Emigna– Emigna2018年10月22日 13:32:29 +00:00Commented Oct 22, 2018 at 13:32
-
\$\begingroup\$ Hmm, not really. It would be useful to have more test cases than the 4 we have now. Can't really think of anything where
S13S13∍*OTÖwould fail right now (so well done golfing 4 bytes). It also seems similar as the Python answer (and Jelly as well I think; I can't really read Jelly all that well). \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年10月22日 13:36:59 +00:00Commented Oct 22, 2018 at 13:36
Wolfram Language (Mathematica), 34 bytes
Check[#~BarcodeImage~"EAN13";1,0]&
A port of my EAN-8 answer.
Perl 6, (削除) 29 (削除ここまで) 26 bytes
{:1[.comb «*»(1,3)]%%10}
-3 bytes if a list of digits is acceptable.
Explanation
{ } # Anonymous Block
.comb # Split into characters
«*»(1,3) # Multiply with 1 and 3 alternately
:1[ ] # Sum (conversion from base 1 is shorter than sum())
%%10 # Check if divisible by 10
Japt -!, 14 bytes
¬Ë*(Ev a3Ãx %A
¬Ë*(Ev a3Ãx %A Full prgram.
¬ Convert to array -_-
Ë Map
* Multiply current number by
(Ev a3Ã 1 if index is even, else 3
x sum
%A mod 10?
-
1\$\begingroup\$ It may be in the comments instead of question, but you aren't allowed to take the input as a list of digits: Question from HyperNeutrino: "Can we take input as a list of digits? For example, instead of reading the barcode as "123", I'd read it as [1, 2, 3]" Response from OP: "No, it should be input as 123, string or number doesn't matter." \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年10月22日 14:02:48 +00:00Commented Oct 22, 2018 at 14:02
-
\$\begingroup\$ @KevinCruijssen Sorry, I though it was allowed :c \$\endgroup\$Luis felipe De jesus Munoz– Luis felipe De jesus Munoz2018年10月22日 14:09:42 +00:00Commented Oct 22, 2018 at 14:09
-
\$\begingroup\$ Yeah, I thought so too until I saw the comments in the chat.. >.> I've asked OP to add it to the challenge description (or just allow an array of digits since I/O is usually flexible by default..) \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年10月22日 14:14:45 +00:00Commented Oct 22, 2018 at 14:14
APL (Dyalog Unicode), 15 bytes
0=×ばつ1 3⍴⍨≢
Anonymous train, outputs 1 for True and 0 for False. TIO links to a prettified version of the output.
Totally not helped at all by @ngn or @dzaima (thanks guys).
How:
0=×ばつ1 3⍴⍨≢ ⍝ Main fn
≢ ⍝ Tally the argument (will always be 13)
1 3⍴⍨ ⍝ Reshape the vector (1 3) to 13 elements
×ばつ ⍝ Multiply the original vector by that, then sum
10| ⍝ Modulo 10
0= ⍝ equals 0
Retina 0.8.2, (削除) 23 (削除ここまで) 22 bytes
.(.)
$&1ドル1ドル
.
$*
M`
1$
Try it online! Link includes test cases. Edit: Saved 1 byte thanks to Martin Ender's comment on @Leo's Retina answer to the EAN-8 question. Explanation:
.(.)
$&1ドル1ドル
Triplicate alternate digits.
.
$*
Convert each digit to unary.
M`
Count the number of character boundaries, which is one more than the number of characters.
1$
Check for divisibilty by 10, but allow for the 1 we just added.
Java 8, (削除) 69 (削除ここまで) (削除) 67 (削除ここまで) 62 bytes
n->{int s=0,m=3;for(;n>0;n/=10)s+=n%10*(m^=2);return s%10<1;}
-5 bytes thanks to @OlivierGrégoire.
-1 byte thanks to my own 1-year old answer for the Is my barcode valid? challenge, and @OlivierGrégoire to remind me of it.. xD
Explanation:
s->{ // Method with long parameter and boolean return-type
int s=0, // Sum, starting at 0
m=3; // Multiplier, starting at 3
for(;n>0; // Loop as long as the input is not 0 yet
n/=10) // After every iteration: integer-divide the input by 10
s+= // Increase the sum by:
n%10* // The last digit of the input multiplied by:
(m^=2); // either 1 or 3 (alternating every iteration)
return s%10<1;} // Then return whether the sum is divisible by 10
-
\$\begingroup\$ 58 bytes by taking the digits as an array of integers. \$\endgroup\$Olivier Grégoire– Olivier Grégoire2018年10月22日 14:15:54 +00:00Commented Oct 22, 2018 at 14:15
-
\$\begingroup\$ @OlivierGrégoire OP disallowed it I'm afraid, although I've asked to reconsider the default flexible I/O rules. My 69-bytes version was the same as yours, except with added
.getBytes()\$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年10月22日 14:16:37 +00:00Commented Oct 22, 2018 at 14:16 -
1\$\begingroup\$ Ok. The question itself wasn't clear on it. Anyways, here's a 62 bytes golf:
n->{int s=0,i=3;for(;n>0;n/=10)s+=n%10*(i=4-i);return s%10<1;}\$\endgroup\$Olivier Grégoire– Olivier Grégoire2018年10月22日 14:24:22 +00:00Commented Oct 22, 2018 at 14:24 -
\$\begingroup\$ Also, indeed, the version was the same because I took your version, removed the
.getBytes()and switch the input parameter just to show that different input meant shorter answer, before I saw that the chat showed that indeed that input method wasn't allowed. \$\endgroup\$Olivier Grégoire– Olivier Grégoire2018年10月22日 14:31:00 +00:00Commented Oct 22, 2018 at 14:31 -
1\$\begingroup\$ @OlivierGrégoire Nice golf with
i=4-i. And it indeed looked suspiciously the same including variable names. ;p \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年10月22日 14:32:18 +00:00Commented Oct 22, 2018 at 14:32
-
\$\begingroup\$
%5¬can be5ḍ, or you could golf it to 10 bytes:D0;s2Sḅ35ḍ. with a semi-port of @Dennis♦' answer here. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年10月22日 15:14:43 +00:00Commented Oct 22, 2018 at 15:14 -
\$\begingroup\$ @KevinCruijssen oh cool, thanks \$\endgroup\$2018年10月22日 18:49:17 +00:00Commented Oct 22, 2018 at 18:49
Pyth, (削除) 11 (削除ここまで) 10 bytes
!es*V*jT7l
Accepts input as a list of digits. Try it online here, or verify all test cases at once here.
!es*V*jT7lQQ Implicit: Q=eval(input())
Trailing QQ implied
jT7 10 in base 7 - yields [1,3]
* lQ Repeat the above len(input) times
*V Q Vectorised multiply the above with the input
s Take the sum
e % 10
! Logical not
Edit: saved a byte by replacing ,1 3 with jT7
9) become a4\$\endgroup\$