Wyzwanie
Napisz najkrótszy program lub funkcję do obliczenia algorytmu Luhna do weryfikacji liczb (karty kredytowej).
Algorytm Luhna wyjaśniony
Z RosettaCode ten algorytm na potrzeby tego wyzwania jest określony jako taki, z przykładowym wejściem 49927398716
:
Reverse the digits, make an array:
6, 1, 7, 8, 9, 3, 7, 2, 9, 9, 4
Double the numbers in odd indexes:
6, 2, 7, 16, 9, 6, 7, 4, 9, 18, 4
Sum the digits in each number:
6, 2, 7, 7, 9, 6, 7, 4, 9, 9, 4
Sum all of the numbers:
6 + 2 + 7 + 7 + 9 + 6 + 7 + 4 + 9 + 9 + 4 = 70
If the sum modulo 10 is 0, then the number is valid:
70 % 10 = 0 => valid
Zasady IO
Dane wejściowe : ciąg lub liczba (do wyboru) w wybranym formacie wejściowym / wyjściowym języka
Wyjście : odpowiednio wartość prawdy lub fałszu , wskazująca, czy dane wejściowe są prawidłowe zgodnie z powyższym testem.
Uwagi / wskazówki
Staraj się nie publikować przypadkowo własnych numerów kart kredytowych lub kont, jeśli używasz ich do testowania :)
Jeśli dane wejściowe są niepoprawne i niemożliwe do przetworzenia przy użyciu określonego algorytmu (tj. Zbyt krótki, aby pracować z nim), możesz zrobić, co chcesz, w tym wysadzić mój komputer.
Jednak poprzedni punkt nie oznacza, że Twój język może robić, co chce, z liczbami, które są zbyt duże, aby można go było obsługiwać. Jeśli twój język nie jest w stanie obsłużyć przypadku testowego, rozważ wzięcie ciągu jako danych wejściowych.
Przykłady
Poniższe przykłady zostały sprawdzone przy pomocy tego skryptu Python ; jeśli uważasz, że ktoś się myli lub masz pytanie, po prostu ping @cat.
49927398716 True
49927398717 False
1234567812345670 True
1234567812345678 False
79927398710 False
79927398711 False
79927398712 False
79927398713 True
79927398714 False
79927398715 False
79927398716 False
79927398717 False
79927398718 False
79927398719 False
374652346956782346957823694857692364857368475368 True
374652346956782346957823694857692364857387456834 False
8 False **
0 True **
** zgodnie z implementacją Pythona, ale możesz zrobić wszystko, ponieważ są one zbyt krótkie, aby można je było spełnić poprzez ścisłe przestrzeganie specyfikacji.
Jeśli którakolwiek z powyższych unieważnia istniejące odpowiedzi (choć uważam, że nie powinno to być możliwe), to te odpowiedzi są nadal ważne. Jednak nowe odpowiedzi, aby były poprawne, powinny być zgodne z powyższą specyfikacją.
Tabela liderów
źródło
echo -n
-1% 2/
można połączyć w-2/
.1,
można zastąpić przez0
(0 jest przymuszane do tablicy, a następnie+
jest konkatenowane).9>9*-
można zastąpić przez9>+
(ponieważ zajmujemy się tylko ostatnią cyfrą). Ponadto sprawdzanie nieparzystych długości jest nieco długie, a użycie.,2%,\+
jest krótsze. Po wykonaniu tej czynności, możemy również zmienić{16%}%
i(\0=
na{16}/
(wewnątrz pętli). Po wykonaniu wszystkich, że będzie to wyglądać mniej więcej tak:.,2%,\+-2/0\+{{16%}/2*.9>+++}*10%!
.Python,
7369 znakówźródło
D[-2::-2]
->D[1::2]
ponieważ kolejność sumy nie jest ważna :)==0
można skrócić do<1
Python 3, 77 bajtów
źródło
C # 119 znaków:
Nie zbyt złe dla n00b kod golfowego w statycznie wpisywanych języka, mam nadzieję.
Można to zmniejszyć do 100 :
źródło
i%2<1?1:2
wstecz. Dzięki.Golfscript - 34 znaki
Przykładowy numer ze strony wikipedii 4992739871
źródło
.+(9%)
to bardzo innowacyjne (w każdym razie dla mnie). Lubię! +10(9%)
wynosi 9, a nie 0).PHP, 108 bajtów
źródło
Ruby - 85 znaków
źródło
Haskell, 96 bajtów
Musi być lepszy / krótszy sposób, ale oto moje rozwiązanie Haskell zawierające 96 znaków :
Niestety z tej
digitToInt
funkcji można korzystać tylko wtedy, gdyimport Data.Char
najpierw. W przeciwnym razie mogłem obniżyć do 88 znaków, zastępując((+(-48)).fromEnum)
jedigitToInt
.źródło
Windows PowerShell, 82
Historia:
+1 + +3
nadal można ocenić.źródło
Q, 63
stosowanie
źródło
{0=mod[sum"J"$raze($)($)x*#:[x]#1 2]10}"I"$'(|)
innym sposobem na podwojenie indeksów nieparzystych.D, 144 bajty
Bardziej czytelnie:
źródło
APL, 28 bajtów
Widok rozstrzelony
Przykłady
źródło
{0=10|+/⍎¨∊⍕¨⍵×⌽2-2|⍳⍴⍵}⍎¨
PowerShell 123
źródło
Perl,
464241 bajtówObejmuje +1 dla
-p
Podaj dane na STDIN:
luhn.pl
:źródło
$=-=-$&-$&*/\G(..)+$/
?0..4
* 2 daje,0, 2, 4, 6, 8
ale5..9
podaje,10,12,14,16,18
której suma1 3 5 7 9
ma te same ostatnie cyfry,11 13 15 17 19
co te same wartości0..9 * 2.2
, jakbyś obciął liczbę całkowitą. Pierwszy$&
już przyczynia się do tego1
, więc korekta1.2
jest nadal potrzebna.$=
może przechowywać tylko liczby całkowite i zaczyna się od wartości, która kończy się na 0, więc dba o obcięcie. Wartości ujemne są potrzebne, ponieważ/\G/
regex zmienia dowolne wartości$&
nadal na stosie ewaluacyjnym, więc należy je zmienićJavaScript (ES6), 61 bajtów
Nie konkuruje, ponieważ JavaScript był bardzo różny w 2011 roku.
Suma cyfr
2*n
to,2*n
jeślin in 0..4
,2*n-9
jeślin in 5..9
. To powiedziawszy, cała suma może być obliczona w jednym kroku.źródło
Galaretka ,
1211 bajtówWypróbuj online! (ze wszystkimi przypadkami testowymi)
Jak to działa
Alternatywnie, dla 12 bajtów:
źródło
8086 Montaż , IBM PC DOS,
29282523 bajtyWykorzystuje (nadużywa) instrukcje BCD do binarnego x86 do obsługi dzielenia i
modulo 10
sprawdzania poszczególnych cyfr . Okazuje się, że instrukcjeAAM
iAAD
wykonują BCD / binarną konwersję wartości bajtów (co może być bardzo przydatne), mimo że nie zostały one udokumentowane lub opisane jako ogólne wykonywanie tej funkcji.Dla wszystkich oficjalnych wersjach IBM / MS DOS,
AX
aBX
inicjowane są0000
na starcie ( ref , ref ) iDX
abyCS
, który jest wartością 12-bitowy więc gwarancją niezerowe i pozytywne. W ten sposób możemy zagwarantować,BX
to0
i może przerzucić / flopDX
do określenia parzyste / nieparzyste cyfry miejsca.Przykładowe dane wyjściowe:
Pobierz program testowy LUHN.COM IBM PC DOS.
źródło
Scala: 132
wezwanie:
źródło
JavaScript 1.8: 106 znaków
Oto oryginalne rozwiązanie, które wpadłem na pomysł, zanim znalazłem ten post:
Czytelna forma:
źródło
K4, 35 bajtów
źródło
Retina ,
4342 bajtySiatkówka jest (znacznie) nowsza od tego wyzwania.
Wiodąca pusta linia jest znacząca.
Drukuje
0
dla fałszerstwa i1
dla prawdziwych wyników.Wypróbuj online! (Nieznacznie zmodyfikowany, aby uruchomić wszystkie przypadki testowe jednocześnie).
Wyjaśnienie
Wstaw
;
w każdej pozycji, aby oddzielić cyfry.Od tego momentu
r
wielokrotnie dopasowujemy dwie cyfry i podwajamy lewą. W ten sposób unikamy kosztownego cofania listy.Dopasowujemy każdą cyfrę i konwertujemy ją na tyle
1
s (to znaczy przekształcamy każdą cyfrę w unarną).To dopasowuje każdą liczbę jednoargumentową i konwertuje ją z powrotem na dziesiętne, zastępując ją długością. W połączeniu z poprzednim etapem dodaje to podwojone cyfry.
Ponownie dopasowujemy każdą postać i przekształcamy ją w tyle
1
s. Oznacza to, że każdą cyfrę przeliczamy indywidualnie z powrotem na jednoargumentowy. To również pasuje do;
separatorów, które w konwersji są traktowane jako zera, co oznacza, że są po prostu usuwane. Ponieważ wszystkie liczby jednoargumentowe są teraz ściśnięte razem, automatycznie dodaliśmy jednoargumentowe przedstawienie wszystkich cyfr razem.Na końcu wstawiamy długość całego łańcucha, tj. Dziesiętną reprezentację jednoargumentowej sumy kontrolnej.
Na koniec zliczamy liczbę dopasowań tego wyrażenia regularnego, tzn. Sprawdzamy, czy reprezentacja dziesiętna kończy się
0
, drukując,0
czy1
odpowiednio.źródło
PowerShell, 74 bajty
Wyjaśnienie
Skrypt testowy
Wynik
źródło
05AB1E ,
1210 bajtówWypróbuj online! lub jako pakiet testowy
Wyjaśnienie
źródło
Haskell: 97
Z jakiegoś powodu to nie działa dla mnie , więc oto moja wersja
źródło
GNU sed, 140 bajtów
(w tym +1 za
-r
flagę)Sed prawie nigdy nie jest najbardziej naturalnym językiem arytmetyki, ale proszę bardzo:
źródło
APL, 38 bajtów
oczekuje liczby jako liczby, a nie ciągu, ale dzieje się tak tylko dlatego, że tryAPL (co zrozumiałe) nie implementuje
⍎
jeszcze bardziej redukowalne, jestem pewien ...
źródło
PHP - 136 znaków
źródło
MATL ,
2320 bajtów (nie konkuruje)Wypróbuj online!
Wyprowadza 1 dla prawidłowej liczby, w przeciwnym razie 0.
Zaoszczędzono trzy bajty dzięki sugestiom Luisa Mendo.
Wyjaśnienie
źródło
Galaretka , 14 bajtów
Wypróbuj online!
Wyjaśnienie:
źródło