EAN-8 kodów kreskowych zawiera 7 cyfr informacji i 8 cyfra kontrolna.
Suma kontrolna jest obliczana przez pomnożenie cyfr przez 3 i 1 na przemian, dodanie wyników i odjęcie od następnej wielokrotności 10.
Na przykład, biorąc pod uwagę cyfry 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
Suma tych wynikowych cyfr wynosi 55 , więc cyfra sumy kontrolnej wynosi 60–55 = 5
Wyzwanie
Twoim zadaniem jest, biorąc pod uwagę 8-cyfrowy kod kreskowy, sprawdzenie, czy jest poprawny - zwrócenie prawdziwej wartości, jeśli suma kontrolna jest ważna, i fałszowanie w przeciwnym razie.
- Możesz przyjmować dane wejściowe w dowolnej z następujących form:
- Łańcuch o długości 8 znaków reprezentujący cyfry kodu kreskowego
- Lista 8 liczb całkowitych, cyfr kodu kreskowego
- Nieujemna liczba całkowita (możesz albo założyć zera na początku, gdzie nie podano żadnego, tj.
1
=00000001
, Albo zażądać wprowadzenia z podanymi zerami)
- Wbudowane, które obliczają sumę kontrolną EAN-8 (tj. Pobierają pierwsze 7 cyfr i obliczają ostatnie) są zakazane.
- To jest golf golfowy , więc wygrywa najkrótszy program (w bajtach)!
Przypadki testowe
20378240 -> True
33765129 -> True
77234575 -> True
00000000 -> True
21034984 -> False
69165430 -> False
11965421 -> False
12345678 -> False
code-golf
arithmetic
decision-problem
integer
checksum
FlipTack
źródło
źródło
Odpowiedzi:
Galaretka , 7 bajtów
Wypróbuj online!
Jak to działa
źródło
JavaScript (ES6),
414038 bajtówZaoszczędzono 2 bajty dzięki @ETHProductions i 1 bajt dzięki @Craig Ayre.
Pobiera dane wejściowe jako listę cyfr.
Określa sumę wszystkich cyfr, w tym sumę kontrolną.
Jeśli suma jest wielokrotnością 10, to jest to prawidłowy kod kreskowy.
Przypadki testowe
Pokaż fragment kodu
źródło
g=([n,...s],i=3,t=0)=>n?g(s,4-i,t+n*i):t%10<1
, ale można znaleźć lepszego sposobu ...map
, który moim zdaniem działa lepiej, ponieważ wejściem może być lista cyfr zamiast łańcucha.s=>s.map(e=>t+=e*(i=4-i),t=i=1)&&t%10==1
?&&
z|
do wyjścia 1/0 od truthy / falsy jest dozwolone?Python 2 ,
64483529 bajtówmypetlion zapisał 19 bajtów
Wypróbuj online!
źródło
lambda x:sum(x[::2]*3+x[1::2])%10<1
Dla 35 bajtów.lambda x:sum(x[::2]*2+x)%10<1
Dla 29 bajtów.Galaretka , 8 bajtów
Wypróbuj zestaw testowy.
Galaretka , 9 bajtów
Wypróbuj online lub Wypróbuj pakiet testowy.
Jak to działa
Wynik dla pierwszych 7 cyfr kodu kreskowego i cyfry sumy kontrolnej musi być dodany do wielokrotności 10 , aby był ważny. Tak więc suma kontrolna jest ważna, jeśli algorytm zastosowany do całej listy można podzielić przez 10 .
źródło
JḂḤ‘×µS⁵ḍ
JḂaḤ+µS⁵ḍ
Pm2Ḥ+µS⁵ḍ
ma 15 bajtów w UTF-8, chyba że źle to obliczyłem.MATL , 10 bajtów
Dzięki @Zgarb za wskazanie błędu, teraz poprawionego.
Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .
Wyjaśnienie
źródło
Befunge-98 (PyFunge) ,
1614 bajtówZaoszczędzono 2 bajty, pomijając drugą część za pomocą
j
zamiast;
s, a także zamieniając a~
iw+
pierwszej części, aby pozbyć się+
w drugiej.Dane wejściowe składają się z 8 cyfr (w razie potrzeby z zerami) i nic więcej.
Dane wyjściowe za pośrednictwem kodu wyjścia (otwórz menu debugowania w TIO), gdzie 1 to prawda, a 0 to fałsz.
Wypróbuj online!
Wyjaśnienie
Ten program wykorzystuje różne sztuczki.
Po pierwsze, cyfry po kolei przechodzą przez ich wartości ASCII. Zwykle wymagałoby to odjęcia 48 od każdej wartości podczas odczytywania jej z danych wejściowych. Jeśli jednak go nie zmodyfikujemy, pozostanie nam 16 (3 + 1 + 3 + 1 + 3 + 1 + 3 + 1) dodatkowych 48 kopii, co oznacza, że nasza suma będzie o 768 większa niż co to powinno być. Ponieważ zajmujemy się tylko modem sumowania 10, możemy po prostu dodać 2 do sumy później. Możemy zatem przyjąć surowe wartości ASCII, oszczędzając około 6 bajtów.
Po drugie, ten kod sprawdza tylko, czy co drugi znak jest EOF, ponieważ gwarantowana długość danych wejściowych wynosi tylko 8 znaków.
Po trzecie,#
koniec linii nie przeskakuje pierwszego znaku, ale przeskakuje,;
jeśli nadchodzi z innego kierunku. Jest to lepsze niż umieszczanie#;
z przodu.Ponieważ druga część naszego programu jest uruchamiana tylko raz, nie musimy go konfigurować, aby pomijała pierwszą połowę podczas uruchamiania wstecz. To pozwala nam użyć polecenia skoku, aby przeskoczyć drugą połowę, gdy wychodzimy przed wykonaniem jej cofania.
Krok po kroku
Uwaga: Znaki „nieparzyste” i „parzyste” oparte są na systemie 0-indeksowanym. Pierwszy znak jest parzysty, z indeksem 0.
źródło
C,
7877 bajtówWypróbuj online!
C (gcc), 72 bajty
Wypróbuj online!
źródło
Wolfram Language (Mathematica) ,
2621 bajtówWypróbuj online!
Pobiera dane wejściowe jako listę 8 cyfr.
Jak to działa
2-9^Range@8
jest przystający modulo 10 to2-(-1)^Range@8
, co jest{3,1,3,1,3,1,3,1}
. Bierzemy iloczyn iloczynu z tej listy z danymi wejściowymi i sprawdzamy, czy wynik można podzielić przez 10.Wolfram Language (Mathematica) , 33 bajty i niekonkurujące
Wypróbuj online!
Pobiera dane wejściowe jako ciąg. Zwraca
1
prawidłowe i0
niepoprawne kody kreskowe .Jak to działa
Najlepsza rzecz, jaką mogłem znaleźć na drodze do wbudowania (ponieważ Mathematica o to chodzi).
Bit wewnętrzny
#~BarcodeImage~"EAN8";1
, generuje obraz kodu kreskowego EAN8, a następnie całkowicie go ignoruje i ocenia na 1. Jednak jeśli kod kreskowy jest nieprawidłowy,BarcodeImage
generuje ostrzeżenie, któreCheck
wyłapuje, zwracając w tym przypadku 0.źródło
BarcodeImage
, który generuje obraz kodu kreskowego i weryfikuje kod kreskowy w trakcie procesu. TakCheck[#~BarcodeImage~"EAN8";0,1]<1&
by działało (ale jest dłuższe).Java 8,
585655 bajtów-2 bajty pośrednio dzięki @RickHitchcock , używając
(m=4-m)*i
zamiastm++%2*2*i+i
po zobaczeniu go w odpowiedzi na JavaScript .-1 bajt pośrednio dzięki @ETHProductions (i @RickHitchcock ), używając
(m^=2)*i
zamiast(m=4-m)*i
.Wyjaśnienie:
Wypróbuj tutaj.
źródło
m=4-m
nam^=2
.^=1
dość często w odpowiedziach, kiedy chcę zmieniać pomiędzy0
i1
.^=2
działa w tym przypadku, aby zmieniać pomiędzy1
i3
. Niezła sztuczka i dziękuję za komentarz, aby wspomnieć o tym. :)05AB1E , 14 bajtów
Wypróbuj online!
Potrzebuje wiodących
0
s, bierze listę cyfr.źródło
3100004
(powinno być prawdą).0
nią.0
. Ta odpowiedź używa funkcji liczbowych na ciągach znaków, co jest jedną z cech 05AB1E.Pyth , 8 bajtów
Sprawdź wszystkie przypadki testowe!
Pyth , 13 bajtów
Jeśli możemy założyć, że dane wejściowe mają zawsze dokładnie 8 cyfr:
Sprawdź wszystkie przypadki testowe!
Jak to działa?
Jeśli suma pierwszych 7 cyfr po zastosowaniu algorytmu jest odejmowana od 10, a następnie porównywana z ostatnią cyfrą, jest to równoważne ze sprawdzaniem, czy suma wszystkich cyfr po zastosowaniu algorytmu jest wielokrotnością 10 .
źródło
3100004
(powinno być prawdą).3*3+1*1+0*3+...
lub0*3+3*1+1*0..
? Myślałem, że powinniśmy zrobić to pierwszeHaskell ,
4038 bajtówWypróbuj online!
Pobiera dane wejściowe jako listę 8 liczb całkowitych. Praktyczny przykład użycia nieskończonych list.
Edycja: Zapisano 2 bajty dzięki GolfWolf
źródło
cycle
oszczędzania 2 bajtów .Siatkówka ,
2322 bajtów-1 bajt dzięki Martin Ender !
Wypróbuj online!
Wyjaśnienie
Przykładowe dane wejściowe:
20378240
Zastąp każdą parę cyfr pierwszą dwukrotnie powtórzoną cyfrą, a następnie samą parą. Rozumiemy
2220333788824440
Konwertuj każdą cyfrę na unarną. Po dodaniu nawiasów dla uzyskania przejrzystości
(11)(11)(11)()(111)(111)...
Policz liczbę dopasowań pustego ciągu, która jest o jeden większa niż liczba dopasowań w ciągu. (W dwóch ostatnich krokach w zasadzie wzięliśmy sumę każdej cyfry +1) Wynik:
60
Dopasuj a
1
na końcu ciągu. Pomnożymy cyfry przez 3 i 1 na przemian i zsumujemy je, dla prawidłowego kodu kreskowego powinien on być podzielny przez 10 (ostatnia cyfra 0); ale również dodać 1 w ostatnim etapie, więc chcemy być ostatnia cyfra 1. Wynik końcowy:1
.źródło
.
scenę na mecz i1$
zakończyć mecz na końcu.PowerShell , 85 bajtów
Wypróbuj online! lub Zweryfikuj wszystkie przypadki testowe
Implementuje algorytm zgodnie z definicją. Pobiera dane wejściowe
$a
, wyciąga każdą cyfrę za pomocą"$a"[0..6]
i zapętla je za pomocą|%{...}
. Każdej iteracji bierzemy cyfrę, rzutujemy ją jako ciąg,"$_"
a następnie rzutujemy jako liczbę całkowitą+
przed pomnożeniem przez jeden3
lub1
(wybrany przez inkrementację$i
modulo2
).Wszystkie wyniki są zebrane razem i zsumowane
-join'+'|iex
. Bierzemy ten mod wyniku10
, odejmujemy go10
i ponownie bierzemy mod wyniku10
(ten drugi mod jest konieczny, aby uwzględnić00000000
przypadek testowy). Następnie sprawdzamy, czy jest to liczba-eq
całkowita do ostatniej cyfry. Ten wynik logiczny jest pozostawiany w potoku, a dane wyjściowe są niejawne.źródło
3100004
(powinno być prawdą).Galaretka , 16 bajtów
Wypróbuj online!
przyjmuje dane wejściowe jako listę cyfr
źródło
D
wstawiam stopkę. I dziękuję! : DDµṪ=Ç
.3100004
(powinno być prawdą).APL (Dyalog) , 14 bajtów
Odpowiednik z rozwiązania streetster .
Pełna treść programu. Monity o listę numerów z STDIN.
Wypróbuj online!
Jest…
0=
zero równe10|
mod-10 z+/
suma⎕×
czasy wejściowe8⍴3 1
osiem elementów zaczerpniętych cyklicznie z[3,1]
?
źródło
05AB1E , 9 bajtów
Wypróbuj online!
źródło
31×S*OTÖ
dla 8 bajtów.×
popycha 31n
razy. Po pomnożeniu automatycznie spada dodatkowe 31.69165430 -> 1
J, 17 bajtów
-10 bajtów dzięki Cole
Wypróbuj online!
Wykorzystuje to mnożenie list o jednakowych rozmiarach, aby uniknąć kombinacji zip / multiply oryginalnego rozwiązania, a także „trick 1 base”
1#.
aby dodać produkty razem. Podejście na wysokim poziomie jest podobne do pierwotnego wyjaśnienia.oryginał, 27 bajtów
Wypróbuj online!
wyjaśnił
źródło
0=10|1#.(8$3 1)*]
powinien działać dla 17 bajtów (robi ten sam algorytm). Jestem prawie pewien, że w wersji beta możesz mieć haczyk zakończony po prawej stronie rzeczownikiem, więc0=10|1#.]*8$3 1
może działać dla 15 (sprawdziłbym tio, ale wydaje się, że nie działa?)1#.
sztuczki i zapomniałem ją 2 lub 3 razy ... dzięki za przypomnienie. Oh btw 15 bajtowa wersja nie działała w TIO.C (gcc),
8482726154 bajtów-21 bajtów od Neila
-7 bajtów od Nahuela Fouilleula
Wypróbuj online!
Opracowany niezależnie od odpowiedzi Steadyboksa
„f” to funkcja, która przyjmuje kod kreskowy jako
int
i zwraca wartości1
True i0
False.f
przechowuje ostatnią cyfręx
ins
(s=x%10
),Następnie oblicza sumę w
c
(for(i=c=0;x;x/=10)c+=(1+2*i++%4)*x;
)c
jest sumąi
jest licznikiemdla każdej cyfry, w tym pierwszej, dodaj
1+2*i%4
liczbę cyfry (x%10
) do sumy kontrolnej i przyrostui
(i++
in3-2*i++%4
)1+2*i%4
wynosi 1, gdyi
jest parzysty, a 0, gdyi
jest nieparzystyNastępnie zwraca, czy suma jest wielokrotnością dziesięciu, a ponieważ dodaliśmy ostatnią cyfrę (pomnożoną przez 1), suma będzie wielokrotnością dziesięciu, jeśli kod kreskowy jest prawidłowy. (wykorzystuje niezdefiniowane zachowanie zależne od GCC
return
).źródło
(x%10)
i tak może byćx
tak jakc%10
później. Myślę też, że możesz użyć,i<8
a następnie po prostu przetestować, czyc%10
na końcu jest zero.s
jest to konieczne: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
lubc=c%10<1
zamiast tegoreturn c%10<1
nadal działai<8
może zostać zastąpiony przezx
C, 63 bajty
Zakłada się, że
0
jesttrue
i każda inna wartość jestfalse
.+3 bajty dla lepszej wartości zwracanej
Dodaj
==0
doreturn
wyciągu.Bez golfa
Wykorzystuje to alternatywną definicję sum kontrolnych EAN, w których cyfra kontrolna jest wybierana w taki sposób, że suma kontrolna całego kodu kreskowego, w tym cyfra kontrolna, jest wielokrotnością 10. Matematycznie to działa tak samo, ale jest o wiele łatwiejsze do napisania.
Inicjalizacja zmiennych wewnątrz pętli, jak sugeruje Steadybox, 63 bajty
Usuwanie nawiasów klamrowych zgodnie z sugestią Steadybox, 61 bajtów
Używanie
<1
zamiast==0
lepszej wartości zwrotu, jak sugerował Kevin CruijssenDodaj
<1
doreturn
instrukcji, to dodaje tylko 2 bajty zamiast dodawać,==0
która dodaje 3 bajty.źródło
{}
pofor
. Ponadto przesłane funkcje muszą być wielokrotnego użytku , więc musisz zainicjowaćs
wewnątrz funkcji (po prostu zmieńi;s=0;
nai,s;
ii=0;
nai=s=0;
).for
, treść pętli będzie następną instrukcją.for(i=0;i<8;i++){s+=v[i]*3+v[++i];}
jest taki sam jakfor(i=0;i<8;i++)s+=v[i]*3+v[++i];
.==0
, możesz być +2, używając<1
zamiast tego. :)JavaScript (Node.js) , 47 bajtów
Chociaż odpowiedź jest już znacznie krótsza, jest to moja pierwsza gra w golfa w JavaScript, więc chciałbym usłyszeć zalecenia dotyczące gry w golfa :-)
Testowanie
Pokaż fragment kodu
Alternatywnie możesz wypróbować online!
źródło
Perl 5,
3732 + 1 (-p) bytes-5 bytes thanks to Dom Hastings. 37 +1 bytes was
try it online
źródło
--$|
przełączanie między1
a0
więc można używać, zamiast++$i%2
za logiczną zmiennego! Liczy się tylko to, że total ($s
) pasuje/0$/
, udało się uzyskać 33 bajty łącząc te zmiany zs///
: Wypróbuj online! (-l
jest tylko dla widoczności)s/./(something with $&)/ge
i/0$/
pasuję, ale nie razem.Brainfuck, 228 bajtów
Prawdopodobnie można go nieco poprawić. Wejście jest pobierane 1 cyfra na raz, wyjścia 1 dla true, 0 dla false.
Jak to działa:
Umieść 8 w pozycji 3.
Pobiera dane 8 razy, za każdym razem zmieniając je z wartości ascii na wartość rzeczywistą +2. Wejścia są oddzielone od nich, które zostaną usunięte, aby umożliwić późniejsze pomnożenie.
Odejmij jeden od każdego elementu. Nasza taśma wygląda teraz jakoś
Z każdą wartością o 1 więcej niż powinno być. Wynika to z faktu, że zera zaburzą nasz proces mnożenia.
Teraz jesteśmy gotowi do rozpoczęcia mnożenia.
Przejdź do ostatniego do ostatniego elementu.
Przy zerowym pomnóż element, na którym jest, przez trzy, a następnie przesuń dwa elementy w lewo. Teraz pomnożyliśmy wszystko, czego potrzebowaliśmy, przez trzy i jesteśmy na pierwszym miejscu na taśmie.
Zsumuj całą listę.
Wartość, którą mamy, jest o 16 większa niż wartość rzeczywista. Napraw to, odejmując 16.
Musimy sprawdzić, czy suma jest wielokrotnością 10. Maksymalna suma to wszystkie 9, czyli 144. Ponieważ żadna suma nie będzie większa niż 10 * 15, umieść 15 i 10 na taśmie, w tej kolejności i prawo do prawo do sumy.
Przejdź tam, gdzie jest 15. Chociaż jest niezerowa, sprawdź, czy suma jest niezerowa. Jeśli tak, odejmij od niego 10. Teraz jesteśmy albo na (pustej) pozycji sumy, albo na (również pustej) pozycji dziesięciu. Przesuń jeden w prawo. Gdybyśmy byli na pozycji sumy, jesteśmy teraz na niezerowej pozycji 15. Jeśli tak, przesuń dwukrotnie w prawo. Teraz jesteśmy w tej samej pozycji w obu przypadkach. Dodaj dziesięć do dziesięciu pozycji i odejmij jedną z 15 pozycji.
Reszta dotyczy danych wyjściowych:
Przejdź do pozycji sumy. Jeśli jest niezerowy (ujemny), kod kreskowy jest nieprawidłowy; ustaw pozycję na -1. Teraz dodaj 49, aby uzyskać poprawną wartość ascii: 1 jeśli jest poprawna, 0 jeśli jest niepoprawna.
źródło
Java 8, 53 bajty
Gra w golfa:
Bezpośrednie obliczenia w lambda wydają się najkrótszym rozwiązaniem. Pasuje do pojedynczego wyrażenia, minimalizując narzut lambda i usuwając zewnętrzne deklaracje zmiennych i średniki.
Wydajność:
źródło
QBasic,
5452 bajtówNudna odpowiedź okazała się najkrótsza:
Wprowadza cyfry oddzielone przecinkami. Moje oryginalne 54-bajtowe rozwiązanie, które wprowadza jedną cyfrę na raz, wykorzystuje „ładniejsze” podejście:
źródło
C # (.NET Core) ,
6562 bajtówWypróbuj online!
Podziękowanie
-3 bajty dzięki @KevinCruijssen i zgrabnej sztuczce przy użyciu operatora exclusive-or.
DeGolfed
C # (.NET Core) , 53 bajty
Wypróbuj online!
Bezpośredni port odpowiedzi @ Snowman .
źródło
b=>{int s=0,i=0,t=1;while(i<8)s+=b[i++]*(t^=2);return s%10<1;}
( 62 bajty ), lub alternatywnie z foreach, również 62 bajty:b=>{int s=0,t=1;foreach(int i in b)s+=i*(t^=2);return s%10<1;}
(która jest portem mojej odpowiedzi Java 8 ).MATLAB / oktawa , 32 bajty
Wypróbuj online!
Zamierzam to opublikować pomimo drugiej odpowiedzi Octave, gdy opracowałem ten kod i podchodziłem do niego bez patrzenia na inne odpowiedzi.
Tutaj mamy anonimową funkcję, która przyjmuje dane wejściowe jako tablicę 8 wartości i zwraca true, jeśli poprawny kod kreskowy, false w przeciwnym razie ..
Wynik oblicza się w następujący sposób.
źródło
Excel, 37 bytes
Interpreting "A list of 8 integers" as allowing 8 separate cells in Excel:
źródło
()
s in your comment.=(A1:H1)
: This is not handled as an array. Is invalid if placed in any column not inA-H
range. If placed in a column in A-H, returns the value for that column only. (Formula in % results in %: C2 --> C1 H999 --> H1 K1 --> #VALUE!)Ruby, 41 Bytes
Takes an array of integers. -6 bytes thanks to Jordan.
źródło
map
here at all:zip
takes a block. You can save a couple more bytes by using$.
instead of initializings
:->n{n.zip([3,1]*4){|x,y|$.+=x*y};$.%10<1}
TI-Basic (83 series), 18 bytes
Takes input as a list in
Ans
. Returns1
for valid barcodes and0
for invalid ones.A port of my Mathematica answer. Includes screenshot, in lieu of an online testing environment:
Notable feature:
binomcdf(7,0
is used to generate the list{1,1,1,1,1,1,1,1}
(the list of probabilities that from 7 trials with success probability 0, there will be at most N successes, for N=0,1,...,7). Then,cumSum(
turns this into{1,2,3,4,5,6,7,8}
.This is one byte shorter than using the
seq(
command, though historically the point was that it's also significantly faster.źródło