Tantangan
Tulis program atau fungsi terpendek untuk menghitung Algoritma Luhn untuk memverifikasi nomor (kartu kredit).
Algoritma Luhn menjelaskan
Dari RosettaCode , algoritme ini untuk tujuan tantangan ini ditentukan seperti itu, dengan contoh input dari 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
Aturan IO
Input : Suatu string atau angka (pilihan Anda), dalam format input / output pilihan bahasa Anda
Output : Nilai true atau falsy , masing-masing, yang menunjukkan apakah input valid atau tidak menurut tes di atas.
Catatan / Tips
Cobalah untuk tidak secara sengaja memposting kartu kredit atau nomor akun Anda sendiri, jika Anda menggunakannya untuk menguji :)
Jika input tidak valid dan tidak mungkin diproses dengan algoritma yang ditentukan (yaitu terlalu pendek untuk bekerja), Anda dapat melakukan apa pun yang Anda inginkan, termasuk meledakkan komputer saya.
Namun , peluru sebelumnya tidak berarti bahwa bahasa Anda dapat melakukan apa pun yang diinginkan dengan Angka yang terlalu besar untuk ditangani. Jika bahasa Anda tidak mampu menangani test case, maka pertimbangkan untuk mengambil string sebagai input.
Contohnya
Contoh berikut divalidasi dengan skrip Python ini ; jika Anda merasa ada yang salah atau memiliki pertanyaan, cukup 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 **
** sesuai dengan implementasi Python, tetapi Anda dapat melakukan apa saja karena ini terlalu pendek untuk memenuhi syarat oleh kepatuhan yang ketat terhadap spesifikasi.
Jika salah satu di atas membatalkan jawaban yang ada (meskipun saya yakin itu tidak mungkin), maka jawaban tersebut masih valid. Namun, jawaban baru , agar valid, harus mengikuti spesifikasi di atas.
Papan peringkat
sumber
echo -n
-1% 2/
dapat digabungkan menjadi-2/
.1,
dapat diganti dengan0
(0 dipaksa ke array, lalu+
digabungkan).9>9*-
dapat diganti dengan9>+
(karena kami hanya peduli dengan digit terakhir). Juga, memeriksa panjang ganjil agak panjang, menggunakan.,2%,\+
lebih pendek. Setelah melakukan ini, kita juga bisa mengubah{16%}%
dan(\0=
menjadi{16}/
(di dalam lingkaran). Setelah Anda melakukan semua itu, itu akan terlihat seperti ini:.,2%,\+-2/0\+{{16%}/2*.9>+++}*10%!
.Python,
7369 karaktersumber
D[-2::-2]
->D[1::2]
karena urutan jumlah tidak penting :)==0
dapat disingkat menjadi<1
Python 3, 77 byte
sumber
C # 119 karakter:
Tidak terlalu buruk untuk kode golf n00b dalam bahasa yang diketik secara statis, saya harap.
Ini dapat dikurangi menjadi 100 :
sumber
i%2<1?1:2
mundur. Terima kasih.Golfscript - 34 karakter
Contoh nomor dari halaman wikipedia 4992739871
sumber
.+(9%)
sangat inovatif (bagi saya, sih). Saya suka! +10(9%)
adalah 9 dan bukan 0).PHP, 108 byte
sumber
Ruby - 85 karakter
sumber
Haskell, 96 byte
Pasti ada cara yang lebih baik / lebih pendek, tapi inilah solusi Haskell saya dalam 96 karakter :
Sayangnya
digitToInt
fungsi ini hanya bisa digunakan jika Andaimport Data.Char
pertama kali. Kalau tidak, saya bisa turun ke 88 karakter dengan mengganti((+(-48)).fromEnum)
dengandigitToInt
.sumber
Windows PowerShell, 82
Sejarah:
+1 + +3
masih bisa dievaluasi.sumber
Q, 63
pemakaian
sumber
{0=mod[sum"J"$raze($)($)x*#:[x]#1 2]10}"I"$'(|)
cara berbeda untuk menggandakan indeks ganjil.D, 144 byte
Lebih jelas:
sumber
APL, 28 byte
Tampilan meledak
Contohnya
sumber
{0=10|+/⍎¨∊⍕¨⍵×⌽2-2|⍳⍴⍵}⍎¨
PowerShell 123
sumber
Perl,
464241 byteTermasuk +1 untuk
-p
Berikan masukan pada STDIN:
luhn.pl
:sumber
$=-=-$&-$&*/\G(..)+$/
?0..4
* 2 memberi0, 2, 4, 6, 8
tetapi5..9
memberikan10,12,14,16,18
jumlah1 3 5 7 9
yang memiliki angka terakhir11 13 15 17 19
yang sama dengan nilai yang sama seperti0..9 * 2.2
jika Anda memotong ke integer. Yang pertama$&
sudah berkontribusi faktor1
, sehingga koreksi oleh1.2
masih diperlukan.$=
hanya dapat menahan bilangan bulat dan dimulai dengan nilai yang berakhir pada 0 sehingga menangani pemotongan. Nilai-nilai negatif diperlukan karena/\G/
regex mengubah$&
masih pada tumpukan evaluasi sehingga mereka perlu diubahJavaScript (ES6), 61 byte
Non-bersaing, karena JavaScript sangat berbeda pada 2011.
Jumlah digit
2*n
adalah2*n
jikan in 0..4
,2*n-9
jikan in 5..9
. Yang mengatakan, semua jumlah dapat dihitung dalam satu langkah.sumber
Jelly ,
1211 byteCobalah online! (dengan semua kasus uji)
Bagaimana itu bekerja
Atau, untuk 12 byte:
sumber
x86-16 ASM , IBM PC DOS, 23 byte
Menggunakan (menyalahgunakan) instruksi BCD-ke-biner x86
AAM
untuk menangani pemisahan danmodulo 10
pengecekan digit individu .Masukkan num string pointer kartu
SI
, panjangCX
. Output:ZF
jika valid.Contoh hasil uji program:
Unduh program uji IBM PC DOS LUHN.COM .
sumber
Scala: 132
doa:
sumber
JavaScript 1.8: 106 karakter
Ini adalah solusi orisinal yang saya buat sebelum saya menemukan posting ini:
Formulir yang dapat dibaca:
sumber
K4, 35 byte
sumber
Retina ,
4342 byteRetina (jauh) lebih baru dari tantangan ini.
Baris kosong terkemuka adalah signifikan.
Mencetak
0
untuk hasil palsu dan1
untuk hasil yang benar.Cobalah online! (Sedikit dimodifikasi untuk menjalankan semua test case sekaligus.)
Penjelasan
Masukkan
;
di setiap posisi untuk memisahkan digit.Dari belakang
r
, kami berulang kali mencocokkan dua digit dan menggandakan yang kiri. Dengan cara ini kami menghindari pembalikan daftar yang mahal.Kami mencocokkan setiap digit dan mengonversinya menjadi banyak
1
(yaitu, kami mengonversi setiap digit menjadi unary).Ini cocok dengan masing-masing nomor unary dan mengubahnya kembali menjadi desimal dengan menggantinya dengan panjangnya. Bersama dengan tahap sebelumnya, ini menambahkan digit dua kali lipat.
Sekali lagi, kami mencocokkan setiap karakter dan mengubahnya menjadi banyak
1
. Yaitu kita mengonversi setiap digit secara individual kembali ke unary. Ini juga cocok dengan;
pemisah, yang diperlakukan sebagai nol dalam konversi, yang berarti mereka hanya dihapus. Karena semua angka unary sekarang terjepit bersama, kami secara otomatis telah menambahkan representasi unary dari semua angka.Pada akhirnya, kita memasukkan panjang seluruh string, yaitu representasi desimal dari checksum unary.
Akhirnya kami menghitung jumlah kecocokan dari regex ini, yaitu kami memeriksa apakah representasi desimal berakhir
0
, dicetak0
atau1
sesuai.sumber
Powershell, 74 byte
Penjelasan
Skrip uji
Keluaran
sumber
05AB1E ,
1210 byteCobalah online! atau sebagai Test Suite
Penjelasan
sumber
Haskell: 97
Untuk beberapa alasan ini tidak berfungsi untuk saya , jadi inilah versi saya
sumber
GNU sed, 140 byte
(termasuk +1 untuk
-r
bendera)Sed hampir tidak pernah merupakan bahasa yang paling alami untuk aritmatika, tetapi di sini kita mulai:
sumber
APL, 38 byte
mengharapkan angka sebagai angka, bukan string, tetapi itu hanya karena tryAPL (dimengerti) tidak diterapkan
⍎
lebih lanjut direduksi, saya yakin ...
sumber
PHP - 136 karakter
sumber
MATL ,
2320 byte (tidak bersaing)Cobalah online!
Output 1 untuk angka yang valid, 0 sebaliknya.
Disimpan tiga byte berkat saran Luis Mendo.
Penjelasan
sumber
Jelly , 14 byte
Cobalah online!
Penjelasan:
sumber