Ist mein Barcode gültig?

33

Ein EAN-8- Barcode enthält 7 Informationsstellen und eine 8. Prüfsummenstelle.

Die Prüfsumme wird berechnet, indem die Ziffern abwechselnd mit 3 und 1 multipliziert, die Ergebnisse addiert und vom nächsten Vielfachen von 10 subtrahiert werden.

Zum Beispiel mit folgenden Ziffern 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

Die Summe dieser resultierenden Ziffern ist 55 , die Prüfsummenziffer ist also 60 - 55 = 5


Die Herausforderung

Ihre Aufgabe ist es, anhand eines 8-stelligen Barcodes zu überprüfen, ob er gültig ist - einen wahren Wert zurückzugeben, wenn die Prüfsumme gültig ist, und andernfalls zu verfälschen.

  • Sie können Eingaben in einer der folgenden Formen vornehmen:
    • Eine Zeichenfolge mit einer Länge von 8 Zeichen, die die Barcode-Ziffern darstellt
    • Eine Liste mit 8 Ganzzahlen, den Ziffern des Barcodes
    • Eine nicht negative Ganzzahl (Sie können entweder führende Nullen annehmen, bei denen keine angegeben sind, dh 1= 00000001, oder eine Eingabe mit den angegebenen Nullen anfordern)
  • Builtins, die die EAN-8-Prüfsumme berechnen (dh die ersten 7 Stellen nehmen und die letzte berechnen), sind gesperrt.
  • Das ist , also gewinnt das kürzeste Programm (in Bytes)!

Testfälle

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

21034984 -> False
69165430 -> False
11965421 -> False
12345678 -> False
FlipTack
quelle
Im Zusammenhang mit dem Luhn-Algorithmus zur Überprüfung von Kreditkartennummern , möglicherweise eine Fälschung.
15.
1
Bei dieser Frage handelt es sich nicht um einen Barcode (der schwarz-weiß gestreift ist), sondern um die von einem Barcode codierte Nummer. Die Nummer kann ohne Barcode existieren und der Barcode kann andere Dinge als EANs codieren. Vielleicht ist nur " Ist meine EAN-8 gültig " ein besserer Titel?
Paŭlo Ebermann
2
@ PaŭloEbermann hat nicht ganz den gleichen
Klang
7
Beim Lesen von Barcodes erwarte ich, dass einige Bilder (oder zumindest eine Bitfolge) gelesen werden und keine Prüfsumme überprüft wird.
Paŭlo Ebermann
Stark verwandt , da eine ISBN-13 eine EAN ist.
Olivier Grégoire

Antworten:

5

Gelee , 7 Bytes

s2Sḅ3⁵ḍ

Probieren Sie es online!

Wie es funktioniert

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.
Dennis
quelle
13

JavaScript (ES6), 41 40 38 Byte

2 Byte dank @ETHProductions und 1 Byte dank @Craig Ayre gespeichert.

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

Übernimmt die Eingabe als Ziffernliste.

Legt die Summe aller Ziffern einschließlich der Prüfsumme fest.

Wenn die Summe ein Vielfaches von 10 ist, handelt es sich um einen gültigen Barcode.

Testfälle

Rick Hitchcock
quelle
Ich wollte sagen , dass Sie durch 3 Bytes speichern kann das Umschalten von Pre-Rekursion auf post-Rekursion mit g=([n,...s],i=3,t=0)=>n?g(s,4-i,t+n*i):t%10<1, aber Sie können einen besseren Weg gefunden haben ...
ETHproductions
Danke, @ETHproductions, ich habe zu geändert map, was meiner Meinung nach besser funktioniert, da die Eingabe eine Liste von Ziffern anstelle einer Zeichenfolge sein kann.
Rick Hitchcock
Vielleicht ein weiteres Byte mit retten s=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1?
ETHproductions
Ja, brillant, danke
Rick Hitchcock
Tolle Lösung! Könnten Sie ersetzen &&mit |dem Ausgang 1/0 seit truthy / falsy erlaubt?
Craig Ayre
10

Python 2 , 64 48 35 29 Bytes

Mypetlion sparte 19 Bytes

lambda x:sum(x[::2]*2+x)%10<1

Probieren Sie es online!

Halvard Hummel
quelle
lambda x:sum(x[::2]*3+x[1::2])%10<1Für 35 Bytes.
mypetlion
2
lambda x:sum(x[::2]*2+x)%10<1Für 29 Bytes.
Mypetlion
8

Gelee , 8 Bytes

m2Ḥ+µS⁵ḍ

Probieren Sie die Testsuite aus.

Gelee , 9 Bytes

JḂḤ‘×µS⁵ḍ

Probieren Sie es online aus oder testen Sie die Testsuite.

Wie das geht

m2Ḥ + µS⁵ḍ ~ Volles Programm.

m2 ~ Modular 2. Gibt jedes zweite Element der Eingabe zurück.
  Ḥ ~ Jeweils verdoppeln.
   + µ ~ Hänge die Eingabe an und starte eine neue monadische Kette.
     S ~ Sum.
      ⁵ḍ ~ Ist durch 10 teilbar?
JḂḤ '× µS⁵ḍ ~ Volles Programm (monadisch).

J ~ 1-indizierter Längenbereich.
 Ḃ ~ Bit; Modulo jede Zahl im obigen Bereich um 2.
  Ḥ ~ Jeweils verdoppeln.
   '~ Inkrementiere jeden.
    × ~ Paarweise Multiplikation mit der Eingabe.
     µ ~ Startet eine neue monadische Kette.
      S ~ Sum.
       ⁵ḍ ~ Ist die Summe durch 10 teilbar?

Das Ergebnis für die ersten 7 Ziffern des Barcodes und die Prüfsummenziffer müssen zu einem Vielfachen von 10 addiert werden, damit es gültig ist. Somit ist die Prüfsumme gültig, wenn der auf die gesamte Liste angewendete Algorithmus durch 10 teilbar ist .

Mr. Xcoder
quelle
Immer noch 9 Bytes, aber mit konsistenten Werten:JḂḤ‘×µS⁵ḍ
HyperNeutrino
@HyperNeutrino Danke, ich wusste, dass es ein Atom dafür gibt!
Mr. Xcoder
Auch 9 Bytes JḂaḤ+µS⁵ḍ
::
@HyperNeutrino Nun, es gibt viele Alternativen: P
Mr. Xcoder
1
8 Bytes oder 8 Zeichen? m2Ḥ+µS⁵ḍist 15 Bytes in UTF-8, es sei denn, ich habe es falsch berechnet.
ta.speot.is
7

MATL , 10 Bytes

Vielen Dank an @Zgarb für den Hinweis auf einen Fehler, der jetzt korrigiert wurde.

IlhY"s10\~

Probieren Sie es online! Oder überprüfen Sie alle Testfälle .

Erläuterung

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
Luis Mendo
quelle
7

Befunge-98 (PyFunge) , 16 bis 14 Bytes

Es wurden 2 Bytes gespart, indem der zweite Teil mit janstelle von ;s übersprungen wurde ~und ein und +im ersten Teil ausgetauscht wurden, um ein und im zweiten Teil zu entfernen +.

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

Die Eingabe erfolgt in 8 Ziffern (ggf. mit führenden 0en) und nichts anderes.

Ausgabe über Exit-Code (Debug-Dropdown auf TIO öffnen), wobei 1 wahr und 0 falsch ist.

Probieren Sie es online!

Erläuterung

Dieses Programm verwendet eine Vielzahl von Tricks.

Zunächst werden die Ziffern nacheinander durch ihre ASCII-Werte gezogen. Normalerweise würde dies das Subtrahieren von 48 von jedem Wert erfordern, wenn wir ihn von der Eingabe lesen. Wenn wir es jedoch nicht ändern, verbleiben uns 16 (3 + 1 + 3 + 1 + 3 + 1 + 3 + 1) zusätzliche Exemplare von 48 in unserer Summe, was bedeutet, dass unsere Gesamtzahl 768 größer sein wird als was es sein soll Da es sich nur um die Summe Mod 10 handelt, können wir später nur noch 2 zur Summe addieren. Auf diese Weise können wir unformatierte ASCII-Werte aufnehmen und so etwa 6 Byte sparen.

Zweitens überprüft dieser Code nur, ob jedes andere Zeichen ein EOF ist, da die Eingabe garantiert nur 8 Zeichen lang ist.

Drittens #überspringt das am Ende der Zeile nicht das erste Zeichen, sondern das ;aus der anderen Richtung kommende. Dies ist besser, als #;stattdessen einen nach vorne zu setzen.

Da der zweite Teil unseres Programms nur einmal ausgeführt wird, müssen wir ihn nicht so einrichten, dass er die erste Hälfte überspringt, wenn er rückwärts ausgeführt wird. Auf diese Weise können wir den Befehl jump verwenden, um die zweite Hälfte zu überspringen, während wir den Befehl beenden, bevor wir ihn rückwärts ausführen.

Schritt für Schritt

Hinweis: "Ungerade" und "Gerade" basieren auf einem 0-indizierten System. Das erste Zeichen ist ein gerades Zeichen mit dem Index 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
MilderMilquetoast
quelle
6

Wolfram Language (Mathematica) , 26 21 Bytes

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

Probieren Sie es online!

Übernimmt die Eingabe als Liste mit 8 Ziffern.

Wie es funktioniert

2-9^Range@8ist kongruent modulo 10 bis 2-(-1)^Range@8, das ist {3,1,3,1,3,1,3,1}. Wir nehmen das Skalarprodukt dieser Liste mit der Eingabe und prüfen, ob das Ergebnis durch 10 teilbar ist.

Wolfram Language (Mathematica) , 33 Bytes und nicht konkurrierend

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

Probieren Sie es online!

Übernimmt die Eingabe als Zeichenfolge. Rückgabe 1für gültige Barcodes und0 ungültige .

Wie es funktioniert

Das Beste, was ich an einem eingebauten Gerät finden konnte (da Mathematica sich nur um diese dreht).

Das innere Bit #~BarcodeImage~"EAN8";1erzeugt ein Bild des EAN8-Barcodes, ignoriert ihn dann vollständig und wertet ihn mit 1 aus. Wenn der Barcode jedoch ungültig ist, BarcodeImagewird eine Warnung generiert, die Checkfängt und in diesem Fall 0 zurückgibt .

Mischa Lawrow
quelle
3
Führen Sie die Berechnung von Hand durch, weil sie kürzer ist oder weil Wolfram noch keine ValidateEAN8BarCode () -Funktion in seiner Standardbibliothek hat?
Mark
1
@ Mark Mathematica kann den Barcode nicht direkt validieren , aber ich habe gerade herausgefunden BarcodeImage, dass das Bild des Barcodes generiert und der Barcode dabei validiert wird. So Check[#~BarcodeImage~"EAN8";0,1]<1&funktionieren würde (aber es ist länger).
Mischa Lawrow
5

Java 8, 58 56 55 Bytes

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

-2 Bytes indirekt dank @RickHitchcock , indem er verwendet, (m=4-m)*ianstatt m++%2*2*i+ies in seiner JavaScript-Antwort zu sehen .
-1 Byte indirekt dank @ETHProductions (und @RickHitchcock ) durch Verwendung von (m^=2)*ianstelle von (m=4-m)*i.

Erläuterung:

Probieren Sie es hier aus.

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
Kevin Cruijssen
quelle
1
Sie können ein weiteres Byte mit einem Trick speichern, den @ETHProductions mir gezeigt hat: change m=4-mto m^=2.
Rick Hitchcock
@ RickHitchcock Ah, natürlich .. Ich verwende ^=1ziemlich oft in Antworten, wenn ich zwischen 0und wechseln möchte 1. ^=2funktioniert in diesem Fall, um zwischen 1und zu wechseln 3. Netter Trick, und danke für den Kommentar, um ihn zu erwähnen. :)
Kevin Cruijssen
4

05AB1E , 14 Bytes

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

Probieren Sie es online!

Benötigt führende 0s, nimmt eine Liste von Ziffern.

Erik der Outgolfer
quelle
Scheint zu scheitern 3100004(sollte wahr sein).
Zgarb
@Zgarb Du vermisst 0dort einen.
Erik der Outgolfer
Oh, es braucht eine Schnur? Okay, mein Böser.
Zgarb
@Zgarb Nun, Sie können die Anführungszeichen weglassen, aber ja, Sie brauchen das Anführen 0. Diese Antwort verwendet tatsächlich Zahlenfunktionen für Zeichenfolgen, eine der Funktionen von 05AB1E.
Erik der Outgolfer
@ Mr.Xcoder Die Frage ist nicht sehr klar, ich füge einen weiteren Code hinzu, der das unten regelt.
Erik der Outgolfer
4

Pyth , 8 Bytes

!es+*2%2

Überprüfen Sie alle Testfälle!

Pyth , 13 Bytes

Wenn wir annehmen können, hat die Eingabe immer genau 8 Stellen:

!es.e*bhy%hk2

Überprüfen Sie alle Testfälle!


Wie funktioniert das?

! es + * 2% 2 ~ Volles Programm.

      % 2 ~ Eingabe [:: 2]. Jedes zweite Element der Eingabe.
    * 2 ~ Double (Liste zweimal wiederholen).
   + ~ Hängt die Eingabe an.
  s ~ Summe.
 e ~ Letzte Ziffer.
! ~ Logisches NICHT.
! es.e * sbhy% hk2 ~ Volles Programm.

               ~ Konvertiere die Eingabe in einen String.
   .e ~ Aufgezählte Karte, die den aktuellen Wert in b und den Index in k speichert.
          % hk2 ~ Umgekehrte Parität des Index. (k + 1)% 2.
        hy ~ Double, inkrementieren. Dies ordnet ungerade ganze Zahlen 1 und gerade 3 zu.
      b ~ Die aktuelle Ziffer.
     * ~ Multiplizieren.
  s ~ Summe.
 e ~ Letzte Ziffer.
! ~ Logische Verneinung.

Wenn die Summe der ersten 7 Ziffern nach der Anwendung des Algorithmus von 10 subtrahiert und dann mit der letzten Ziffer verglichen wird, entspricht dies der Überprüfung, ob die Summe aller Ziffern nach der Anwendung des Algorithmus ein Vielfaches von 10 ist .

Mr. Xcoder
quelle
Scheint zu scheitern 3100004(sollte wahr sein).
Zgarb
@Zgarb Warten wir sollen 3*3+1*1+0*3+...oder 0*3+3*1+1*0..? Ich dachte, wir sollten das erstere machen
Mr. Xcoder
In der neuen Spezifikation werden führende Ziffern hinzugefügt, um sicherzustellen, dass es genau 8 gibt (wenn ich das richtig verstehe).
Zgarb
@ Zgarb Ok, behoben.
Mr. Xcoder
4

Haskell , 40 38 Bytes

a=3:1:a
f x=mod(sum$zipWith(*)a x)10<1

Probieren Sie es online!

Nimmt die Eingabe als Liste mit 8 ganzen Zahlen. Ein praktisches Beispiel für die Verwendung unendlicher Listen.

Bearbeiten: 2 Bytes dank GolfWolf gespeichert

Butterhunde
quelle
2
Durch die Verwendung einer rekursiven Definition werden cycle 2 Byte gespart .
Cristian Lupascu
4

Netzhaut , 23 22 Bytes

-1 Byte Danke an Martin Ender !

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

Probieren Sie es online!

Erläuterung

Beispiel Eingabe: 20378240

(.).
$1$1$&

Ersetzen Sie jedes Ziffernpaar durch die erste Ziffer, die zweimal wiederholt wird, gefolgt von dem Paar selbst. Wir bekommen2220333788824440

.
$*

Wandle jede Ziffer in eine unäre um. Mit Klammern zur Verdeutlichung erhalten wir(11)(11)(11)()(111)(111)...

M`

Zählen Sie die Anzahl der Übereinstimmungen der leeren Zeichenfolge, die um eins höher ist als die Anzahl der Übereinstimmungen in der Zeichenfolge. (Mit den letzten beiden Schritten haben wir im Grunde genommen die Summe jeder Ziffer +1 genommen.) Ergebnis:60

1$

Passen Sie a 1am Ende der Zeichenfolge an. Wir haben die Ziffern abwechselnd mit 3 und 1 multipliziert und summiert, für einen gültigen Barcode sollte dieser durch 10 teilbar sein (letzte Ziffer 0); aber wir auch 1 im letzten Schritt hinzugefügt, so dass wir die letzte Ziffer sein 1. Endergebnis wollen: 1.

Löwe
quelle
2
Ich denke, Sie können das .auf der Matchbühne ablegen und das Match 1$am Ende beenden.
Martin Ender
@MartinEnder sehr nett, das mache ich, danke!
Leo
3

Power , 85 Bytes

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

Probieren Sie es online! oder Überprüfen Sie alle Testfälle

Implementiert den Algorithmus wie definiert. Nimmt Eingaben auf $a, zieht jede Ziffer mit heraus "$a"[0..6]und durchläuft sie mit |%{...}. Bei jeder Iteration nehmen wir die Ziffer, wandeln sie in eine Zeichenfolge um "$_"und wandeln sie dann in eine Ganzzahl um, +bevor wir sie mit entweder 3oder 1(durch Inkrementieren von $iModulo 2) multiplizieren .

Diese Ergebnisse werden alle zusammengefasst und summiert -join'+'|iex. Wir nehmen diesen Ergebnis-Mod 10, subtrahieren ihn von 10und nehmen wieder den Ergebnis-Mod 10(dieser zweite Mod ist notwendig, um den 00000000Testfall zu berücksichtigen ). Wir prüfen dann, ob -eqdies der letzten Ziffer entspricht. Dieses boolesche Ergebnis verbleibt in der Pipeline und die Ausgabe ist implizit.

AdmBorkBork
quelle
Scheint zu scheitern 3100004(sollte wahr sein).
Zgarb
@Zgarb Funktioniert bei mir? Probieren Sie es online!
AdmBorkBork
Ah ok, ich habe es ohne die Anführungszeichen getestet.
Zgarb
@ Zgarb Ah, ja. Ohne die Anführungszeichen wird PowerShell implizit als Ganzzahl umgewandelt, wobei die führenden Nullen entfernt werden.
AdmBorkBork
3

Gelee , 16 Bytes

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

Probieren Sie es online!

Nimmt Eingaben als Ziffernliste entgegen

HyperNeutrino
quelle
Nitpick: Ihre TIO-Timeouts. Auch 16 Bytes .
Erik der Outgolfer 15.11.17
@EriktheOutgolfer Warte was wie. Es funktioniert, wenn ich das Din die Fußzeile stecke. Und yay danke! : D
HyperNeutrino
@EriktheOutgolfer Mache ich etwas falsch? Ihr 16-Byte scheint ungültig zu sein?
HyperNeutrino
Vielleicht funktioniert es ein bisschen anders, aber deine scheint auch ein bisschen ungültig zu sein ... speziell denke ich, dass die letzte Zeile sein sollte DµṪ=Ç.
Erik der Outgolfer 15.11.17
1
Scheint zu scheitern 3100004(sollte wahr sein).
Zgarb
3

APL (Dyalog) , 14 Bytes

Entspricht der Streetster-Lösung .

Voller Programmteil. Fordert zur Eingabe einer Nummernliste von STDIN auf.

0=10|+/⎕×83 1

Probieren Sie es online!

Ist…

0= Null gleich

10| der mod-10 von

+/ die Summe von

⎕× die eingabezeiten

8⍴3 1 acht Elemente zyklisch entnommen aus [3,1]

?

Adam
quelle
1
Du meinst, APL kann es nicht in einem Charakter von so etwas wie Ancient Sumerian oder Linear B machen?
Mark
zug
3

05AB1E , 9 Bytes

3X‚7∍*OTÖ

Probieren Sie es online!

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
kalsowerus
quelle
Nett! Als ich das sah, dachte ich zuerst, ich hätte es noch nicht benutzt.
Magic Octopus Urn
31×S*OTÖfür 8 Bytes. ×drückt nur 31 nmal. Wenn Sie multiplizieren, werden die zusätzlichen 31er automatisch gelöscht.
Magic Octopus Urn
@MagicOctopusUrn Das scheint im 6. Testfall nicht zu funktionieren69165430 -> 1
kalsowerus
3

J, 17 Bytes

-10 bytes dank cole

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

Probieren Sie es online!

Hierbei wird die Multiplikation von Listen gleicher Größe verwendet, um die Kombination aus Zip und Multiplikation der ursprünglichen Lösung zu vermeiden, sowie der "Trick 1#.zur Basis 1" , um die Produkte zu addieren. Die Vorgehensweise auf hoher Ebene ähnelt der ursprünglichen Erklärung.

Original, 27 Bytes

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

Probieren Sie es online!

erklärt

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
Jona
quelle
0=10|1#.(8$3 1)*]sollte für 17 Bytes funktionieren (funktioniert auch mit dem gleichen Algorithmus). Ich bin mir ziemlich sicher, dass in der Beta ein Hook auf der rechten Seite mit einem Nomen enden 0=10|1#.]*8$3 1kann , also kann es für 15 funktionieren (ich würde nachsehen, aber es scheint nicht zu funktionieren?)
Cole
@cole, ich liebe diese Verbesserung. Ich habe den 1#.Trick zwei- oder dreimal gelernt und vergessen ... danke, dass du mich daran erinnert hast. Übrigens funktionierte die 15-Byte-Version in TIO nicht.
Jonah
3

C (gcc) 84 82 72 61 54 Bytes

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

-21 Bytes von Neil

-7 Bytes von Nahuel Fouilleul

Probieren Sie es online!

Entwickelt unabhängig von der Antwort von Steadybox

'f' ist eine Funktion, die den Barcode als '' annimmt intund 1für 'Wahr' 'und' 0Falsch ' zurückgibt .

  • fspeichert die letzte Ziffer von xin s( s=x%10),

  • Berechnet dann die Summe in c( for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;)

    • cist die Summe, iist ein Zähler

    • Addieren Sie für jede Ziffer, einschließlich der ersten, 1+2*i%4die Ziffer ( x%10) zur Prüfsumme und erhöhen Sie idie Zahl ( i++in 3-2*i++%4).

      • 1+2*i%4ist 1 wenn igerade und 0 wenn iungerade
  • Gibt dann zurück, ob die Summe ein Vielfaches von zehn ist. Da wir die letzte Ziffer (multipliziert mit 1) hinzugefügt haben, ist die Summe ein Vielfaches von zehn, wenn der Barcode gültig ist. (verwendet GCC-abhängiges undefiniertes Verhalten zum Auslassen return).

Pizzapants184
quelle
Ich denke (x%10)kann sowieso genauso sein xwie du es c%10später nimmst. Auch ich denke du kannst es benutzen i<8und dann einfach testen, ob c%10am Ende Null ist.
Neil
@ Neil Danke! Das hat -10 Bytes.
Pizzapants184
In der Tat denke ich, sist unnötig:c;i;f(x){for(i=c=0;i<8;x/=10)c+=(1+2*i++%4)*x;return c%10<1;}
Neil
die tio-Verbindung ist 61 Bytes, aber in der Antwort ist es 72, weiß auch nicht, warum x=c%10<1oder c=c%10<1anstatt return c%10<1immer noch funktioniert
Nahuel Fouilleul
auch i<8kann ersetzt werden durchx
Nahuel FOUILLEUL
3

C 63 Bytes

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

Angenommen, das 0ist trueund jeder andere Wert ist false.

+3 Bytes für besseren Rückgabewert

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

Ergänzen Sie ==0die returnAussage.

Ungolfed

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
}

Hierbei wird die alternative Definition von EAN-Prüfsummen verwendet, bei der die Prüfziffer so gewählt wird, dass die Prüfsumme des gesamten Barcodes einschließlich der Prüfziffer ein Vielfaches von 10 ist. Mathematisch funktioniert dies genauso, aber es ist viel einfacher zu schreiben.

Initialisierung von Variablen innerhalb der Schleife, wie von Steadybox vorgeschlagen, 63 Bytes

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

Entfernen von geschweiften Klammern, wie von Steadybox vorgeschlagen, 61 Byte

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

Verwenden <1 statt ==0für einen besseren Rückgabewert, wie von Kevin Cruijssen vorgeschlagen

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

Fügen Sie <1der returnAnweisung nur 2 Bytes hinzu, anstatt ==03 Bytes hinzuzufügen .

Micheal Johnson
quelle
Sie können zwei Bytes sparen, indem Sie das {}nach dem entfernen for. Außerdem müssen Funktionsübermittlungen wiederverwendbar sein , sodass Sie sinnerhalb der Funktion initialisieren müssen (nur i;s=0;zu i,s;und i=0;zu ändern i=s=0;).
Steadybox
@Steadybox Wie kann ich die geschweiften Klammern entfernen?
Micheal Johnson
Es gibt nur eine Aussage in ihnen. Wenn es danach keine geschweiften Klammern gibt for, ist der Schleifenkörper die nächste Anweisung. for(i=0;i<8;i++){s+=v[i]*3+v[++i];}ist das gleiche wie for(i=0;i<8;i++)s+=v[i]*3+v[++i];.
Steadybox
@Steadybox Oh natürlich. Dies ist eine der Macken der C-Syntax, die ich normalerweise vergesse, da ich beim Schreiben von normalem Code immer die geschweiften Klammern einsetze, auch wenn sie nicht erforderlich sind, da der Code dadurch besser lesbar wird.
Micheal Johnson
In Ihrer Wahr / Falsch-Antwort kann anstelle von +3 durch Hinzufügen ==0+2 durch Verwenden von verwendet <1werden. :)
Kevin Cruijssen
2

JavaScript (Node.js) , 47 Byte

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

Obwohl es bereits eine viel kürzere Antwort gibt, ist dies mein erster Versuch, in JavaScript zu golfen. Ich würde gerne Golfempfehlungen hören :-)

Testen

Alternativ können Sie es auch online ausprobieren!

Mr. Xcoder
quelle
2

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

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

-5 Bytes dank Dom Hastings. 37 + 1 Bytes waren

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

versuche es online

Nahuel Fouilleul
quelle
1
Habe ein bisschen damit gespielt und dachte, ich würde einen nützlichen Trick mit dir teilen: --$|Schalte zwischen diesen um 1und 0du kannst ihn anstelle ++$i%2eines abwechselnden Booleschen verwenden! Außerdem ist alles, was zählt, dass total ( $s) übereinstimmt /0$/und 33 Bytes erreicht, die diese Änderungen kombinieren mit s///: Online ausprobieren! ( -list nur für die Sichtbarkeit)
Dom Hastings
Ja, ich denke an s/./(something with $&)/geund zu /0$/passen, aber nicht die beiden kombiniert.
Nahuel Fouilleul
2

Brainfuck, 228 Bytes

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

Kann wohl ein bisschen verbessert werden. Die Eingabe erfolgt jeweils 1-stellig, die Ausgänge 1 für wahr und 0 für falsch.

Wie es funktioniert:

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

Setze 8 auf Position 3.

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

Nimmt die Eingabe 8 Mal vor und ändert sie jedes Mal vom ASCII-Wert auf den tatsächlichen Wert +2. Die Eingänge sind durch Einsen voneinander getrennt, die entfernt werden, um die spätere Multiplikation zu vereinfachen.

>[->]

Subtrahiere einen von jedem Gegenstand. Unser Band sieht jetzt so aus

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

Mit jedem Wert 1 mehr als es sein sollte. Dies liegt daran, dass Nullen unseren Multiplikationsprozess durcheinander bringen.

Jetzt können wir mit der Multiplikation beginnen.

<<<<

Gehe zum vorletzten Punkt.

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

Multiplizieren Sie bei Null das Element, bei dem es sich befindet, mit drei und verschieben Sie dann zwei Elemente nach links. Jetzt haben wir alles, was wir brauchten, mit drei multipliziert und sind auf dem Band an der allerersten Stelle.

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

Summiere die gesamte Liste.

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

Der Wert, den wir haben, ist 16 mehr als der tatsächliche Wert. Beheben Sie dies durch Subtrahieren von 16.

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

Wir müssen testen, ob die Summe ein Vielfaches von 10 ist. Die maximale Summe ist mit allen 9s, was 144 ist. Da keine Summe größer als 10 * 15 ist, setzen Sie 15 und 10 auf das Band, in dieser Reihenfolge und nach rechts das Recht der Summe.

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

Gehen Sie zu 15. Testen Sie, ob die Summe ungleich Null ist. Wenn dies der Fall ist, subtrahieren Sie 10 davon. Jetzt sind wir entweder auf der (leeren) Summenposition oder auf der (ebenfalls leeren) Zehnposition. Bewege einen nach rechts. Wenn wir auf der Summenposition waren, sind wir jetzt auf der Position ungleich Null. Wenn ja, gehen Sie zweimal nach rechts. Jetzt sind wir in beiden Fällen in der gleichen Position. Addiere zehn zu den zehn Positionen und subtrahiere eins von den 15 Positionen.

Der Rest ist für die Ausgabe:

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

Gehen Sie zur Summenposition. Wenn es nicht null (negativ) ist, ist der Barcode ungültig. Stelle die Position auf -1. Addieren Sie nun 49, um den korrekten ASCII-Wert zu erhalten: 1, wenn er gültig ist, 0, wenn er ungültig ist.

Bolce Bussiere
quelle
2

Java 8, 53 Bytes

Golf gespielt:

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

Direkte Berechnung im Lambda erscheint zur kürzesten Lösung. Es passt in einen einzelnen Ausdruck, minimiert den Lambda-Overhead und entfernt überflüssige Variablendeklarationen und Semikolons.

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);
  }
}

Ausgabe:

[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

quelle
2

QBasic, 54 52 Bytes

Die langweilige Antwort stellte sich als die kürzeste heraus:

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

Hiermit werden die Ziffern durch Kommas getrennt eingegeben. Meine ursprüngliche 54-Byte-Lösung, die jeweils eine Ziffer eingibt, verwendet einen "schöneren" Ansatz:

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

C # (.NET Core) , 65 62 Bytes

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

Probieren Sie es online!

Danksagung

-3 Bytes dank @KevinCruijssen und dem netten Trick mit dem Exklusiv-Oder-Operator.

DeGolfed

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

Probieren Sie es online!

Ein direkter Port von @Snowmans Antwort .

Ayb4btu
quelle
Für Ihre erste Antwort: b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}( 62 Bytes ) oder alternativ mit einem foreach auch 62 Bytes: b=>{int s=0,t=1;foreach(int i in b)s+=i*(t^=2);return s%10<1;}(das ist ein Port meiner Java 8 Antwort ).
Kevin Cruijssen
1

MATLAB / Octave , 32 Bytes

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

Probieren Sie es online!

Ich werde dies trotz der anderen Octave-Antwort posten, während ich diesen Code und Ansatz entwickelte, ohne die anderen Antworten anzusehen.

Hier haben wir eine anonyme Funktion, die die Eingabe als Array von 8 Werten nimmt und true zurückgibt, wenn ein gültiger Barcode vorliegt, andernfalls false.

Das Ergebnis wird wie folgt berechnet.

              2*x(1:2:7)
             [          ,x]
         sum(              )
     mod(                   ,10)
@(x)~
  1. Ungerade Stellen (eine indiziert) werden mit 2 multipliziert.
  2. Das Ergebnis wird dem Eingabearray vorangestellt und ergibt ein Array, dessen Summe die ungeraden Ziffern dreimal und die geraden Ziffern einmal enthält.
  3. Wir machen die Summe, die auch die gelieferte Prüfsumme in unserer Summe enthält.
  4. Als nächstes wird das Modulo 10 durchgeführt. Wenn die angegebene Prüfsumme gültig wäre, würde die Summe aller multiplizierten Stellen einschließlich des Prüfsummenwerts ein Vielfaches von 10 ergeben. Daher würde nur ein gültiger Barcode 0 zurückgeben.
  5. Das Ergebnis wird invertiert, um bei Gültigkeit eine logische Ausgabe von true zu erhalten.
Tom Carpenter
quelle
1

Excel, 37 Bytes

Interpretieren von "Eine Liste mit 8 Ganzzahlen", um 8 separate Zellen in Excel zuzulassen:

=MOD(SUM(A1:H1)+2*(A1+C1+E1+G1),10)=0
Wernisch
quelle
= MOD (SUMME ((A1: H1) + 2 * (A1 + C1 + E1 + G1)), 10) = 0 existiert diese Formel in Excel?
RosLuP
@RosLuP, nicht vordefiniert, nein. Aber Modulo, Sum, + etc tun ;-)
Wernisch
Ich möchte nur sagen, dass es so scheint, als ob in APL zunächst y = (A1: H1) + 2 * (A1 + C1 + E1 + G1) und nach der Summe und dem Mod gut geht; in APL geht nicht gut erste Summe (A1: H1) usw. etwas wie (1,2,3) + 4 = (5,6,7) und als Summe (5,6,7) = 18; Beachten Sie, dass Summe (1,2,3) = 6 und 6 + 4 = 10 von 18 abweichen. Aber möglicherweise mache ich Fehler in etwas
RosLuP
@RosLuP, Entschuldigung, hat die geänderten ()s in Ihrem Kommentar verpasst .
Wernisch
Problem ist, wie Excel interpretiert =(A1:H1): Dies wird nicht als Array behandelt. Ist ungültig, wenn in einer Spalte platziert, die nicht im A-HBereich liegt. Wenn in AH in einer Spalte platziert, wird nur der Wert für diese Spalte zurückgegeben. (Formel in% ergibt%: C2 -> C1 H999 -> H1 K1 -> #WERT!)
Wernisch
1

Rubin, 41 Bytes

Nimmt eine Reihe von ganzen Zahlen. -6 Bytes dank Jordan.

->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
Anzeigename
quelle
Nett! FWIW brauchst du maphier überhaupt nicht: Nimmt zipeinen Block. Sie können ein paar Bytes mehr sparen, indem Sie Folgendes verwenden, $.anstatt Folgendes zu initialisieren s:->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
Jordan
1

TI-Basic (Serie 83), 18 Byte

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

Nimmt Eingaben als Liste auf Ans. Rückgabe 1für gültige Barcodes und0 ungültige .

Ein Port meiner Mathematica-Antwort . Enthält einen Screenshot anstelle einer Online-Testumgebung:

Barcode-Screenshot

Bemerkenswerte Eigenschaft: binomcdf(7,0wird verwendet, um die Liste zu generieren {1,1,1,1,1,1,1,1}(die Liste der Wahrscheinlichkeiten, dass es aus 7 Versuchen mit Erfolgswahrscheinlichkeit 0 höchstens N Erfolge für N = 0,1, ..., 7 gibt). Dann cumSum(macht dies zu{1,2,3,4,5,6,7,8} .

Dies ist ein Byte kürzer als die Verwendung des seq(Befehls, obwohl es historisch gesehen der Punkt war, dass es auch bedeutend schneller ist.

Mischa Lawrow
quelle