# Validate a barcode [duplicate]

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

1. 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 = 102

2. Then, 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 = 29

3. Add the numbers obtained in steps 1 and 2 together:

29 + 102 = 131

4. The 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:

1. Receive a barcode as its input.
2. Check whether the barcode is valid
3. Return 1 (or equivalent) if the barcode is valid, 0 (or equivalent) otherwise.

This is , so the shortest code in terms of bytes wins.

• why did the last digit (9) become a 4 Oct 22, 2018 at 13:11
• Sorry, will fix it :) Oct 22, 2018 at 13:12
• I recommend removing the 13-char check because it's trivial but annoying in certain languages. Up to you though whether you want to do input validation (most people leave it out but you can leave it in) Oct 22, 2018 at 13:13
• Can we take input as a list of digits? (sorry for all the questions) Oct 22, 2018 at 13:14
• Oct 22, 2018 at 13:14

# Ruby, 45 40 37 bytes

->n{(n+n.scan(/.(.)/)*''*2).sum%10<1}

Try it online!

# Python 3, 55 bytes

lambda s:not sum(int(i)*d for i,d in zip(s,[1,3]*7))%10

Try it online!

# 05AB1E, 15 10 bytes

εNÉ·>*}OTÖ

Try it online!

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
• Nice answer! Definitely shorter than what I was working on. I like the x you've used in combination with O to sum the entire stack in one go to combine the *3 and + of the two numbers. As well as the (T% to get the remainder. Oct 22, 2018 at 13:28
• @KevinCruijssen: The comparison feels a bit surperflous. Can you think of a counterexample to εNÉ·>*}OTÖ working? Oct 22, 2018 at 13:32
• 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). Oct 22, 2018 at 13:36

# Wolfram Language (Mathematica), 34 bytes

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

Try it online!

A port of my EAN-8 answer.

# Perl 6, 29 26 bytes

{:1[.comb «*»(1,3)]%%10}

Try it online!

-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 ª3Ãx %A

¬Ë*(Ev ª3Ãx %A  Full prgram.
¬               Convert to array -_-
Ë              Map
*             Multiply current number by
(Ev ª3Ã      1 if index is even, else 3
x     sum
%A   mod 10?

Try it online!

• 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." Oct 22, 2018 at 14:02
• @KevinCruijssen Sorry, I though it was allowed :c Oct 22, 2018 at 14:09
• 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..) Oct 22, 2018 at 14:14

# APL (Dyalog Unicode), 15 bytes

0=10|⊢+.×1 3⍴⍨≢

Try it online!

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=10|⊢+.×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

# Python 2, 50 bytes

lambda x,k=1,a=0:f(x/10,4-k,a+x*k)if x else a%10<1

Try it online!

# 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, 6967 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

Try it online.

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
• 58 bytes by taking the digits as an array of integers. Oct 22, 2018 at 14:15
• @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() Oct 22, 2018 at 14:16
• 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;} Oct 22, 2018 at 14:24
• 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. Oct 22, 2018 at 14:31
• @OlivierGrégoire Nice golf with i=4-i. And it indeed looked suspiciously the same including variable names. ;p Oct 22, 2018 at 14:32

# Jelly, 10 bytes

D0;s2Sḅ3⁵ḍ

Try it online!

-4 bytes thanks to Kevin Cruijssen (semi-port @Dennis)

• %⁵¬ can be ⁵ḍ, or you could golf it to 10 bytes: D0;s2Sḅ3⁵ḍ. with a semi-port of @Dennis♦' answer here. Oct 22, 2018 at 15:14
• @KevinCruijssen oh cool, thanks 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

# R, 65 bytes

function(b,y=b%/%10^(12:0)%%10)!sum(y[-1],y[(1:6)*2]*2)%%-10+y[1]

Try it online!