3
\$\begingroup\$

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.

asked Oct 22, 2018 at 13:09
\$\endgroup\$
11
  • \$\begingroup\$ why did the last digit (9) become a 4 \$\endgroup\$ Commented Oct 22, 2018 at 13:11
  • \$\begingroup\$ Sorry, will fix it :) \$\endgroup\$ Commented Oct 22, 2018 at 13:12
  • \$\begingroup\$ 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) \$\endgroup\$ Commented Oct 22, 2018 at 13:13
  • 2
    \$\begingroup\$ Can we take input as a list of digits? (sorry for all the questions) \$\endgroup\$ Commented Oct 22, 2018 at 13:14
  • 1
    \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$ Commented Oct 22, 2018 at 13:14

13 Answers 13

5
\$\begingroup\$

Ruby, (削除) 45 40 (削除ここまで) 37 bytes

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

Try it online!

answered Oct 22, 2018 at 13:18
\$\endgroup\$
2
\$\begingroup\$

Python 3, 55 bytes

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

Try it online!

answered Oct 22, 2018 at 13:19
\$\endgroup\$
2
\$\begingroup\$

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
answered Oct 22, 2018 at 13:21
\$\endgroup\$
3
  • \$\begingroup\$ 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. \$\endgroup\$ Commented 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\$ Commented 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\$ Commented Oct 22, 2018 at 13:36
1
\$\begingroup\$

Wolfram Language (Mathematica), 34 bytes

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

Try it online!

A port of my EAN-8 answer.

answered Oct 22, 2018 at 13:51
\$\endgroup\$
1
\$\begingroup\$

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
answered Oct 22, 2018 at 13:43
\$\endgroup\$
1
\$\begingroup\$

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?

Try it online!

answered Oct 22, 2018 at 13:35
\$\endgroup\$
3
  • 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\$ Commented Oct 22, 2018 at 14:02
  • \$\begingroup\$ @KevinCruijssen Sorry, I though it was allowed :c \$\endgroup\$ Commented 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\$ Commented Oct 22, 2018 at 14:14
1
\$\begingroup\$

APL (Dyalog Unicode), 15 bytes

0=×ばつ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=×ばつ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
answered Oct 22, 2018 at 14:27
\$\endgroup\$
1
\$\begingroup\$

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!

answered Oct 22, 2018 at 14:34
\$\endgroup\$
1
\$\begingroup\$

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.

answered Oct 22, 2018 at 13:57
\$\endgroup\$
1
\$\begingroup\$

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

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
answered Oct 22, 2018 at 13:52
\$\endgroup\$
7
  • \$\begingroup\$ 58 bytes by taking the digits as an array of integers. \$\endgroup\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented 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\$ Commented Oct 22, 2018 at 14:32
1
\$\begingroup\$

Jelly, 10 bytes

D0;s2Sḅ35ḍ

Try it online!

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

answered Oct 22, 2018 at 13:23
\$\endgroup\$
2
  • \$\begingroup\$ %5¬ can be 5ḍ, or you could golf it to 10 bytes: D0;s2Sḅ35ḍ. with a semi-port of @Dennis♦' answer here. \$\endgroup\$ Commented Oct 22, 2018 at 15:14
  • \$\begingroup\$ @KevinCruijssen oh cool, thanks \$\endgroup\$ Commented Oct 22, 2018 at 18:49
0
\$\begingroup\$

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

answered Oct 22, 2018 at 14:03
\$\endgroup\$
0
\$\begingroup\$

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!

answered Oct 22, 2018 at 14:52
\$\endgroup\$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.