Tính toán một chữ số kiểm tra bằng thuật toán Damm


17

các thuật toán kiểm tra chữ số phổ biến như Luhn và sau đó có các thuật toán tốt , ví dụ như thuật toán Damm. Lý do duy nhất có thể đằng sau sự phổ biến của các thuật toán như Luhn là có tồn tại các mã triển khai đánh gôn của chúng. Điều này có nghĩa là chúng ta với tư cách là một cộng đồng có khả năng thay đổi thế giới bằng cách cung cấp các triển khai được đánh gôn bằng các thuật toán tốt hơn.

Vì vậy, thách thức này là thay đổi thế giới bằng cách viết một hàm hoặc một chương trình hoàn chỉnh bằng ngôn ngữ bạn chọn để tính toán một chữ số kiểm tra bằng thuật toán Damm . Câu trả lời có số lượng ký tự nhỏ nhất (không phải byte) sẽ được chọn là người chiến thắng trong một vài tuần. Lưu ý rằng tất cả các chức năng trợ giúp và khai báo của bảng thao tác phải được bao gồm trong số ký tự. Trong trường hợp hòa, câu trả lời phổ biến nhất sẽ được chọn.

Thuật toán này xoay quanh một bảng thao tác phải là một nhóm chuẩn đối xứng hoàn toàn yếu đối với thứ tự 10. Bảng thao tác có thể tìm thấy trong bài viết Wikipedia về thuật toán Damm là một thuật toán được sử dụng trong thử thách này. Để hoàn thiện, tôi sẽ sao chép nó dưới đây:

    |   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

Tóm lại (để biết chi tiết xem bài viết Wikipedia ) thuật toán hoạt động như sau:

  1. Bạn bắt đầu với một danh sách các chữ số sẽ được xử lý và một chữ số tạm thời được đặt thành 0.
  2. Đối với mỗi chữ số trong danh sách, bạn tính toán một chữ số tạm thời mới bằng cách sử dụng chữ số làm chỉ số cột và chữ số tạm thời trước đó làm chỉ số hàng.
  3. Chữ số tạm thời cuối cùng là chữ số kiểm tra. Nếu bạn đang xác thực một số đã có chữ số kiểm tra bổ sung, chữ số tạm thời cuối cùng là 0 nếu số đó hợp lệ.

Chương trình hoặc hàm của bạn phải chấp nhận một chuỗi có thể chứa bất kỳ ký tự nào ngoại trừ null, nhưng nó chỉ nên liên quan đến chính các chữ số trong chuỗi. Nó phải in (nếu là chương trình) hoặc trả về (nếu là hàm) chuỗi gốc với chữ số kiểm tra được tính toán được nối thêm. Nếu bạn chọn viết chương trình, chương trình có thể chấp nhận đầu vào là đối số hoặc là đầu vào tiêu chuẩn. Nếu chuỗi đầu vào trống hoặc không chứa bất kỳ chữ số nào, bạn phải trả về hoặc nối thêm số không.

Vài ví dụ:

Input       |   Output
------------+-------------
42          |   427
427         |   4270
2 to 2      |   2 to 29
23 42 76-   |   23 42 76-5
-           |   -0

Tôi mong muốn được nhìn thấy các mục của Piet tuyên bố chiến thắng.
Alchymist

Câu trả lời:


3

Pyth, 49 ký tự

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

Chứa thần biết những ký tự nào, vì vậy đây là chương trình Python3 để tạo chương trình trên một cách chính xác trên máy của bạn:

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)))

Giải trình:

+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.

3

CJam, 54 ký tự

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

Có một ký tự không thể in được trong đó, vì vậy bạn có thể muốn sử dụng permalink bên dưới.

Kiểm tra nó ở đây.

Giải trình

Chữ số tạm thời đang được theo dõi T, trong đó CJam khởi tạo thành 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.";

3

Python 3, 149 141 138 ký tự

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

Ví dụ:

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

Cảm ơn @MegaTom và @Sieg đã giúp xóa tổng cộng 11 ký tự


2
10 * int (a) + int (i) là int (a + i), phải không?
MegaTom 30/03/2015

Điểm tốt! Cảm ơn bạn, điều đó tiết kiệm 5 ký tự.
đơn cực

1
Để theo sau bởi một tuyên bố duy nhất không cần một dòng mới ở giữa. (-3)
xem

2

Ruby, 149 ký tự

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

Đã thử nghiệm trên repl.it


2

J, 117 byte

Chỉ chứa ascii có thể in. (Tôi đã có một thời gian khó khăn với J và unicode.) Tạo bảng chuyển đổi từ các chỉ số hoán vị của các hàng.

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'

Sử dụng:

   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

Hãy thử trực tuyến tại đây.


2

Haskell, 131 ký tự

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])

Chạy thử nghiệm:

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

0

k, 36 ký tự

/ 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 ký tự (thực hiện tương đương với k)

 f:{x,string 0{M y+10*x}/"H"$'x inter .Q.n}

1
Tôi phải nói rằng tôi ngưỡng mộ việc sử dụng lỗ hổng có thể nghi ngờ trong các quy tắc, nhưng tôi thực sự phải làm rõ các quy tắc để thực thi việc đưa vào khai báo của nhóm gần đúng và khai báo bất kỳ loại chức năng trợ giúp nào trong số lượng ký tự .
Dành cho
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.