2
\$\begingroup\$

This question already has an answer here:

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.

\$\endgroup\$

marked as duplicate by Olivier Grégoire, mbomb007 code-golf Oct 22 '18 at 14:27

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

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

13 Answers 13

5
\$\begingroup\$

Ruby, 45 40 37 bytes

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

Try it online!

\$\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
\$\endgroup\$
  • \$\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\$ – Kevin Cruijssen Oct 22 '18 at 13:28
  • \$\begingroup\$ @KevinCruijssen: The comparison feels a bit surperflous. Can you think of a counterexample to εNÉ·>*}OTÖ working? \$\endgroup\$ – Emigna Oct 22 '18 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 Oct 22 '18 at 13:36
1
\$\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!

\$\endgroup\$
1
\$\begingroup\$

Wolfram Language (Mathematica), 34 bytes

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

Try it online!

A port of my EAN-8 answer.

\$\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
\$\endgroup\$
1
\$\begingroup\$

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!

\$\endgroup\$
  • 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 Oct 22 '18 at 14:02
  • \$\begingroup\$ @KevinCruijssen Sorry, I though it was allowed :c \$\endgroup\$ – Luis felipe De jesus Munoz Oct 22 '18 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 Oct 22 '18 at 14:14
1
\$\begingroup\$

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
\$\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!

\$\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.

\$\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
\$\endgroup\$
  • \$\begingroup\$ 58 bytes by taking the digits as an array of integers. \$\endgroup\$ – Olivier Grégoire Oct 22 '18 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 Oct 22 '18 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 Oct 22 '18 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 Oct 22 '18 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 Oct 22 '18 at 14:32
1
\$\begingroup\$

Jelly, 10 bytes

D0;s2Sḅ3⁵ḍ

Try it online!

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

\$\endgroup\$
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

\$\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!

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.