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 Code-Golf , 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
code-golf
arithmetic
decision-problem
integer
checksum
FlipTack
quelle
quelle
Antworten:
Gelee , 7 Bytes
Probieren Sie es online!
Wie es funktioniert
quelle
JavaScript (ES6),
414038 Byte2 Byte dank @ETHProductions und 1 Byte dank @Craig Ayre gespeichert.
Ü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
Code-Snippet anzeigen
quelle
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 ...map
, was meiner Meinung nach besser funktioniert, da die Eingabe eine Liste von Ziffern anstelle einer Zeichenfolge sein kann.s=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1
?&&
mit|
dem Ausgang 1/0 seit truthy / falsy erlaubt?Python 2 ,
64483529 BytesMypetlion sparte 19 Bytes
Probieren Sie es online!
quelle
lambda x:sum(x[::2]*3+x[1::2])%10<1
Für 35 Bytes.lambda x:sum(x[::2]*2+x)%10<1
Für 29 Bytes.Gelee , 8 Bytes
Probieren Sie die Testsuite aus.
Gelee , 9 Bytes
Probieren Sie es online aus oder testen Sie die Testsuite.
Wie das geht
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 .
quelle
JḂḤ‘×µS⁵ḍ
JḂaḤ+µS⁵ḍ
m2Ḥ+µS⁵ḍ
ist 15 Bytes in UTF-8, es sei denn, ich habe es falsch berechnet.MATL , 10 Bytes
Vielen Dank an @Zgarb für den Hinweis auf einen Fehler, der jetzt korrigiert wurde.
Probieren Sie es online! Oder überprüfen Sie alle Testfälle .
Erläuterung
quelle
Befunge-98 (PyFunge) ,
16 bis14 BytesEs wurden 2 Bytes gespart, indem der zweite Teil mit
j
anstelle von;
s übersprungen wurde~
und ein und+
im ersten Teil ausgetauscht wurden, um ein und im zweiten Teil zu entfernen+
.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.
quelle
C,
7877 BytesProbieren Sie es online!
C (gcc), 72 Bytes
Probieren Sie es online!
quelle
Wolfram Language (Mathematica) ,
2621 BytesProbieren Sie es online!
Übernimmt die Eingabe als Liste mit 8 Ziffern.
Wie es funktioniert
2-9^Range@8
ist kongruent modulo 10 bis2-(-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
Probieren Sie es online!
Übernimmt die Eingabe als Zeichenfolge. Rückgabe
1
fü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";1
erzeugt ein Bild des EAN8-Barcodes, ignoriert ihn dann vollständig und wertet ihn mit 1 aus. Wenn der Barcode jedoch ungültig ist,BarcodeImage
wird eine Warnung generiert, dieCheck
fängt und in diesem Fall 0 zurückgibt .quelle
BarcodeImage
, dass das Bild des Barcodes generiert und der Barcode dabei validiert wird. SoCheck[#~BarcodeImage~"EAN8";0,1]<1&
funktionieren würde (aber es ist länger).Java 8,
585655 Bytes-2 Bytes indirekt dank @RickHitchcock , indem er verwendet,
(m=4-m)*i
anstattm++%2*2*i+i
es in seiner JavaScript-Antwort zu sehen .-1 Byte indirekt dank @ETHProductions (und @RickHitchcock ) durch Verwendung von
(m^=2)*i
anstelle von(m=4-m)*i
.Erläuterung:
Probieren Sie es hier aus.
quelle
m=4-m
tom^=2
.^=1
ziemlich oft in Antworten, wenn ich zwischen0
und wechseln möchte1
.^=2
funktioniert in diesem Fall, um zwischen1
und zu wechseln3
. Netter Trick, und danke für den Kommentar, um ihn zu erwähnen. :)05AB1E , 14 Bytes
Probieren Sie es online!
Benötigt führende
0
s, nimmt eine Liste von Ziffern.quelle
3100004
(sollte wahr sein).0
dort einen.0
. Diese Antwort verwendet tatsächlich Zahlenfunktionen für Zeichenfolgen, eine der Funktionen von 05AB1E.Pyth , 8 Bytes
Überprüfen Sie alle Testfälle!
Pyth , 13 Bytes
Wenn wir annehmen können, hat die Eingabe immer genau 8 Stellen:
Überprüfen Sie alle Testfälle!
Wie funktioniert das?
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 .
quelle
3100004
(sollte wahr sein).3*3+1*1+0*3+...
oder0*3+3*1+1*0..
? Ich dachte, wir sollten das erstere machenHaskell ,
4038 BytesProbieren 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
quelle
cycle
2 Byte gespart .Netzhaut ,
2322 Bytes-1 Byte Danke an Martin Ender !
Probieren Sie es online!
Erläuterung
Beispiel Eingabe:
20378240
Ersetzen Sie jedes Ziffernpaar durch die erste Ziffer, die zweimal wiederholt wird, gefolgt von dem Paar selbst. Wir bekommen
2220333788824440
Wandle jede Ziffer in eine unäre um. Mit Klammern zur Verdeutlichung erhalten wir
(11)(11)(11)()(111)(111)...
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
Passen Sie a
1
am 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
.quelle
.
auf der Matchbühne ablegen und das Match1$
am Ende beenden.Power , 85 Bytes
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 entweder3
oder1
(durch Inkrementieren von$i
Modulo2
) multiplizieren .Diese Ergebnisse werden alle zusammengefasst und summiert
-join'+'|iex
. Wir nehmen diesen Ergebnis-Mod10
, subtrahieren ihn von10
und nehmen wieder den Ergebnis-Mod10
(dieser zweite Mod ist notwendig, um den00000000
Testfall zu berücksichtigen ). Wir prüfen dann, ob-eq
dies der letzten Ziffer entspricht. Dieses boolesche Ergebnis verbleibt in der Pipeline und die Ausgabe ist implizit.quelle
3100004
(sollte wahr sein).Gelee , 16 Bytes
Probieren Sie es online!
Nimmt Eingaben als Ziffernliste entgegen
quelle
D
in die Fußzeile stecke. Und yay danke! : DDµṪ=Ç
.3100004
(sollte wahr sein).APL (Dyalog) , 14 Bytes
Entspricht der Streetster-Lösung .
Voller Programmteil. Fordert zur Eingabe einer Nummernliste von STDIN auf.
Probieren Sie es online!
Ist…
0=
Null gleich10|
der mod-10 von+/
die Summe von⎕×
die eingabezeiten8⍴3 1
acht Elemente zyklisch entnommen aus[3,1]
?
quelle
05AB1E , 9 Bytes
Probieren Sie es online!
quelle
31×S*OTÖ
für 8 Bytes.×
drückt nur 31n
mal. Wenn Sie multiplizieren, werden die zusätzlichen 31er automatisch gelöscht.69165430 -> 1
J, 17 Bytes
-10 bytes dank cole
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
Probieren Sie es online!
erklärt
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 enden0=10|1#.]*8$3 1
kann , also kann es für 15 funktionieren (ich würde nachsehen, aber es scheint nicht zu funktionieren?)1#.
Trick zwei- oder dreimal gelernt und vergessen ... danke, dass du mich daran erinnert hast. Übrigens funktionierte die 15-Byte-Version in TIO nicht.C (gcc)
8482726154 Bytes-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
int
und1
für 'Wahr' 'und'0
Falsch ' zurückgibt .f
speichert die letzte Ziffer vonx
ins
(s=x%10
),Berechnet dann die Summe in
c
(for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;
)c
ist die Summe,i
ist ein ZählerAddieren Sie für jede Ziffer, einschließlich der ersten,
1+2*i%4
die Ziffer (x%10
) zur Prüfsumme und erhöhen Siei
die Zahl (i++
in3-2*i++%4
).1+2*i%4
ist 1 wenni
gerade und 0 wenni
ungeradeGibt 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
).quelle
(x%10)
kann sowieso genauso seinx
wie du esc%10
später nimmst. Auch ich denke du kannst es benutzeni<8
und dann einfach testen, obc%10
am Ende Null ist.s
ist unnötig:c;i;f(x){for(i=c=0;i<8;x/=10)c+=(1+2*i++%4)*x;return c%10<1;}
x=c%10<1
oderc=c%10<1
anstattreturn c%10<1
immer noch funktionierti<8
kann ersetzt werden durchx
C 63 Bytes
Angenommen, das
0
isttrue
und jeder andere Wert istfalse
.+3 Bytes für besseren Rückgabewert
Ergänzen Sie
==0
diereturn
Aussage.Ungolfed
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
Entfernen von geschweiften Klammern, wie von Steadybox vorgeschlagen, 61 Byte
Verwenden
<1
statt==0
für einen besseren Rückgabewert, wie von Kevin Cruijssen vorgeschlagenFügen Sie
<1
derreturn
Anweisung nur 2 Bytes hinzu, anstatt==0
3 Bytes hinzuzufügen .quelle
{}
nach dem entfernenfor
. Außerdem müssen Funktionsübermittlungen wiederverwendbar sein , sodass Sies
innerhalb der Funktion initialisieren müssen (nuri;s=0;
zui,s;
undi=0;
zu änderni=s=0;
).for
, ist der Schleifenkörper die nächste Anweisung.for(i=0;i<8;i++){s+=v[i]*3+v[++i];}
ist das gleiche wiefor(i=0;i<8;i++)s+=v[i]*3+v[++i];
.==0
+2 durch Verwenden von verwendet<1
werden. :)JavaScript (Node.js) , 47 Byte
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
Code-Snippet anzeigen
Alternativ können Sie es auch online ausprobieren!
quelle
Perl 5,
3732 + 1 (-p) Bytes-5 Bytes dank Dom Hastings. 37 + 1 Bytes waren
versuche es online
quelle
--$|
Schalte zwischen diesen um1
und0
du kannst ihn anstelle++$i%2
eines abwechselnden Booleschen verwenden! Außerdem ist alles, was zählt, dass total ($s
) übereinstimmt/0$/
und 33 Bytes erreicht, die diese Änderungen kombinieren mits///
: Online ausprobieren! (-l
ist nur für die Sichtbarkeit)s/./(something with $&)/ge
und zu/0$/
passen, aber nicht die beiden kombiniert.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
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.
quelle
Java 8, 53 Bytes
Golf gespielt:
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.
Ausgabe:
quelle
QBasic,
5452 BytesDie langweilige Antwort stellte sich als die kürzeste heraus:
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:
quelle
C # (.NET Core) ,
6562 BytesProbieren Sie es online!
Danksagung
-3 Bytes dank @KevinCruijssen und dem netten Trick mit dem Exklusiv-Oder-Operator.
DeGolfed
C # (.NET Core) , 53 Byte
Probieren Sie es online!
Ein direkter Port von @Snowmans Antwort .
quelle
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 ).MATLAB / Octave , 32 Bytes
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.
quelle
Excel, 37 Bytes
Interpretieren von "Eine Liste mit 8 Ganzzahlen", um 8 separate Zellen in Excel zuzulassen:
quelle
()
s in Ihrem Kommentar verpasst .=(A1:H1)
: Dies wird nicht als Array behandelt. Ist ungültig, wenn in einer Spalte platziert, die nicht imA-H
Bereich 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!)Rubin, 41 Bytes
Nimmt eine Reihe von ganzen Zahlen. -6 Bytes dank Jordan.
quelle
map
hier überhaupt nicht: Nimmtzip
einen Block. Sie können ein paar Bytes mehr sparen, indem Sie Folgendes verwenden,$.
anstatt Folgendes zu initialisierens
:->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
TI-Basic (Serie 83), 18 Byte
Nimmt Eingaben als Liste auf
Ans
. Rückgabe1
für gültige Barcodes und0
ungültige .Ein Port meiner Mathematica-Antwort . Enthält einen Screenshot anstelle einer Online-Testumgebung:
Bemerkenswerte Eigenschaft:
binomcdf(7,0
wird 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). DanncumSum(
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.quelle