Hitung digit periksa menggunakan algoritma Damm

17

Ada algoritma memeriksa digit populer seperti Luhn dan kemudian ada yang bagus , misalnya algoritma Damm. Satu-satunya alasan yang mungkin di balik popularitas algoritma seperti Luhn adalah bahwa ada implementasi kode golf dari mereka. Ini berarti bahwa kita sebagai komunitas memiliki kekuatan untuk mengubah dunia dengan menyediakan implementasi algoritme yang lebih baik.

Jadi tantangan ini adalah untuk mengubah dunia dengan menulis fungsi atau program lengkap dalam bahasa pilihan Anda yang menghitung digit periksa menggunakan algoritma Damm . Jawaban dengan jumlah karakter terkecil (bukan byte) akan dipilih sebagai pemenang dalam beberapa minggu. Perhatikan bahwa semua fungsi bantuan dan deklarasi tabel operasi harus dimasukkan dalam jumlah karakter. Dalam kasus seri, jawaban yang paling populer akan dipilih.

Algoritma ini berputar di sekitar tabel operasi yang harus menjadi kuasigroup orde 10. yang benar-benar anti-simetris yang lemah. Tabel operasi yang dapat ditemukan di artikel Wikipedia tentang algoritma Damm adalah yang akan digunakan dalam tantangan ini. Demi kelengkapan saya akan mereproduksi di bawah ini:

    |   0   1   2   3   4   5   6   7   8   9
----+----------------------------------------
0   |   0   3   1   7   5   9   8   6   4   2
1   |   7   0   9   2   1   5   4   8   6   3
2   |   4   2   0   6   8   7   1   3   5   9
3   |   1   7   5   0   9   8   3   4   2   6
4   |   6   1   2   3   0   4   5   9   7   8
5   |   3   6   7   4   2   0   9   5   8   1
6   |   5   8   6   9   7   2   0   1   3   4
7   |   8   9   4   5   3   6   2   0   1   7
8   |   9   4   3   8   6   1   7   2   0   5
9   |   2   5   8   1   4   3   6   7   9   0

Singkatnya (untuk detail lihat artikel Wikipedia ) algoritme berfungsi sebagai berikut:

  1. Anda mulai dengan daftar digit yang akan diproses dan digit sementara yang ditetapkan ke 0.
  2. Untuk setiap digit dalam daftar Anda menghitung angka sementara baru dengan menggunakan angka sebagai indeks kolom dan angka sementara sebelumnya sebagai indeks baris.
  3. Digit interim final adalah digit periksa. Jika Anda memvalidasi angka yang sudah memiliki digit periksa ditambahkan, angka interim akhir adalah 0 jika angka tersebut valid.

Program atau fungsi Anda harus menerima string yang dapat berisi karakter apa pun kecuali nol, tetapi itu harus hanya menyangkut dirinya sendiri dengan digit dalam string. Ia harus mencetak (jika suatu program) atau mengembalikan (jika suatu fungsi) string asli dengan digit periksa yang dihitung ditambahkan. Jika Anda memilih untuk menulis program, program dapat menerima input sebagai argumen atau sebagai input standar. Jika string input kosong atau tidak mengandung digit apa pun, Anda harus mengembalikan atau menambahkan nol.

Beberapa contoh:

Input       |   Output
------------+-------------
42          |   427
427         |   4270
2 to 2      |   2 to 29
23 42 76-   |   23 42 76-5
-           |   -0
Untuk S
sumber
Saya berharap melihat entri Piet mengklaim menang.
Alchymist

Jawaban:

3

Pyth, 49 karakter

+z`u@sm>+0jCdT_6"Ľ򒉲򭉟񶯆𐱩򐞆󰆂򕟐򑽌򵋏󇋽򯴆󚙈𱑂񞑼쵥񪨶"+*TGvH:z"\D"k0

Berisi tuhan yang tahu karakter apa, jadi inilah program Python3 untuk menghasilkan program di atas secara akurat di komputer Anda:

N = 317598642709215486342068713591750983426612304597836742095815869720134894536201794386172052581436790
M = 1000000
l = []
while N:
    l.insert(0, N % M)
    N //= M

n = "".join(chr(c) for c in l)

s = '+z`u@sm>+0jCdT_6"' + n + '"+*TGvH:z"\D"k0'

with open("golf.pyth", "wb") as f:
    f.write(s.encode("utf-8"))

print("Program length is {} characters.".format(len(s)))

Penjelasan:

+z`                                     Output the input followed by a
                                        stringified...
   u                         :z"\D"k0   Reduction starting with 0 of digits
                                        in input...
    @                  +*TGvH           Indexing ... by 10*prev + int(next).
     sm         "ZALGO"                 Sum all digits created by ... over the
                                        unicode garbage.
       >+0     6                        Prepend 0 if needed to...
          jCdT_                         Codepoint converted to sequence of
                                        digits.
orlp
sumber
3

CJam, 54 karakter

q_o{A,s&},{~0"끼´慜䪝膞䝮芜㮜ꡞ靓渏縰蒆㣉倔쵶"2G#bAb+A/T==:T;}/T

Ada satu karakter yang tidak patut dicetak di sana, jadi Anda mungkin ingin menggunakan permalink di bawah ini.

Uji di sini.

Penjelasan

Digit sementara sedang dilacak T, yang diinisialisasi CJam menjadi 0

q_o                                  "Read STDIN, duplicate it and print it.";
   {A,s&},                           "Filter out all non-digit characters.";
          {                     }/   "For each digit character.";
           ~                         "Eval to get the digit itself.";
            0                        "Push a zero.";
             "..."2G#b               "Push that long string and interpret the character
                                      codes as the digits of a base-2^16 number.";
                      Ab+            "Get base-10 digits and prepend the 0.";
                         A/          "Split into rows of 10.";
                           T=        "Select row based on interim digit.";
                             =       "Select column based on current digit.";
                              :T;    "Store in T and discard.";
                                   T "Push the interim digit to be printed.";
Martin Ender
sumber
3

Python 3, 149 141 138 karakter

import re
l=""
for c in"ĽᝢႮ⏿ዿၮ∉᜝Ꮺൢ៫Njẜ᳼╭᛭ᰡඡᆸߡⓞ᠜ȍ῏᪆":l+="%04d"%ord(c)
def D(b):
 a="0"
 for i in re.sub("\D","",b):a=l[int(a+i)]
 return b+a

Contoh:

 Input | Output
-------+--------
    42 | 427
   427 | 4270
2 to 2 | 2 to 29
   123 | 1234
  1234 | 12340
     - | -0

Terima kasih kepada @MegaTom dan @Sieg karena telah membantu menghapus total 11 karakter

satu-satunya
sumber
2
10 * int (a) + int (i) is int (a + i), bukan?
MegaTom
Poin bagus! Terima kasih, itu menghemat 5 karakter.
monopole
1
Untuk diikuti oleh satu pernyataan tidak perlu baris baru di antaranya. (-3)
seequ
2

Ruby, 149 karakter

i="0";t="0#{'2uleblnnz0nbpv3kqkaufbjqebm57jdj6ubaba1mc2fyucqff69tbllrcvw393li'.to_i 36}";puts(gets.chomp.each_char{|c|i=(c=~/\d/?t[(i+c).to_i]:i)}+i)

Diuji pada repl.it

MegaTom
sumber
2

J, 117 byte

Hanya mengandung ascii yang dapat dicetak. (Saya mengalami kesulitan dengan J dan unicode.) Menghasilkan tabel transisi dari permutasi-indeks dari baris.

3 :'y,":(((_4(87)&#:inv\40-~a.i.''(3/3+wGf*Dl:(zaW+Hhw*(1p+;~.,y>m-<MZ)JCs'')A.i.10){~<@,~)/|.0,(#~10>])(1":i.10)i.y'

Pemakaian:

   damm=.3 :'y,":(((_4(87)&#:inv\40-~a.i.''(3/3+wGf*Dl:(zaW+Hhw*(1p+;~.,y>m-<MZ)JCs'')A.i.10){~<@,~)/|.0,(#~10>])(1":i.10)i.y'

   damm '23 42 76-'
23 42 76-5

   damm ''
0

Cobalah online di sini.

randomra
sumber
2

Haskell, 131 karakter

import Data.Char
f n=n++(show$foldl(\x y->read[('0':(show.ord=<<"౧⚈ક×ዿၮ∉ɏᵕₖ᧔İɕSʢ凞㷽ᰡ衎텴䘗↩倭῏᪆"))!!(x*10+y)])0[read[i]|i<-n,isDigit i])

Uji coba:

> mapM_ (putStrLn.f) ["42", "427", "2 to 2", "23 42 76-", "-"]
427
4270
2 to 29
23 42 76-5
-0
nimi
sumber
0

k, 36 karakter

/ declare quasi-group  
M:"H"$'"0317598642709215486342068713591750983426612304597836742095815869720134894536201794386172052581436790"

/ declare function
  f:{x,$0{M y+10*x}/"H"$'x@&x in .Q.n}

/ get length of function
  #$f
36

/ execute function against test input
  .q.show f@'{x!x}("42";"427";"2 to 2";"23 42 76-";,"-")
"42"       | "427"
"427"      | "4270"
"2 to 2"   | "2 to 29"
"23 42 76-"| "23 42 76-5"
,"-"       | "-0"

q, 40 karakter (implementasi setara dengan k)

 f:{x,string 0{M y+10*x}/"H"$'x inter .Q.n}
pengguna38879
sumber
1
Saya harus mengatakan saya mengagumi penggunaan loop-hole yang dipertanyakan dalam aturan, tetapi saya benar-benar harus mengklarifikasi aturan untuk menegakkan dimasukkannya deklarasi kuasi-kelompok dan deklarasi segala jenis fungsi bantuan dalam jumlah karakter .
Fors