Dammアルゴリズムを使用してチェックディジットを計算する


17

Luhnなどの一般的なチェックディジットアルゴリズムがあり、次にDammアルゴリズムなどの良いものがあります。Luhnなどのアルゴリズムの人気の背後にある唯一の考えられる理由は、それらのコードゴルフ実装が存在することです。これは、より良いアルゴリズムのゴルフ実装を提供することにより、コミュニティとしての世界を変える力を持っていることを意味します。

したがって、この課題は、Dammアルゴリズムを使用してチェックディジットを計算する関数または選択した言語で完全なプログラムを作成することにより、世界を変えることです。数が最も少ないの答え文字(バイトではない)は、数週間のうちに勝者として選択されます。すべての補助機能と操作テーブルの宣言を文字カウントに含める必要があることに注意してください。同点の場合、最も人気のある回答が選択されます。

このアルゴリズムは、順序10の弱く完全に反対称な準グループでなければならない操作テーブルを中心に展開します。ダムアルゴリズムに関するWikipediaの記事にある操作テーブルは、この課題で使用されるものです。完全を期すために、以下に再現します。

    |   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

要するに(詳細については、Wikipediaの記事を参照)、アルゴリズムは次のように機能します。

  1. 処理する数字のリストと、0に設定された暫定数字から始めます。
  2. リスト内のすべての桁について、列インデックスとして桁を使用し、行インデックスとして前の中間桁を使用して、新しい中間桁を計算します。
  3. 最終的な暫定数字はチェック数字です。既にチェックディジットが追加されている番号を検証する場合、その番号が有効であれば、最終的な暫定数字は0です。

プログラムまたは関数は、null以外の任意の文字を含むことができる文字列を受け入れる必要がありますが、文字列内の数字のみを考慮する必要があります。計算されたチェックディジットが追加された元の文字列を印刷する(プログラムの場合)か、返す(関数の場合)必要があります。プログラムを作成することを選択した場合、プログラムは入力を引数または標準入力として受け入れる場合があります。入力文字列が空であるか、数字が含まれていない場合、ゼロを返すか追加する必要があります。

いくつかの例:

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

Pietのエントリーが勝利を主張するのを楽しみにしています。
アルキミスト

回答:


3

Pyth、49文字

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

神がどんなキャラクターを知っているかを含んでいるので、ここにあなたのマシンで正確に上記のプログラムを生成するPython3プログラムがあります:

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

説明:

+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文字

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

そこには印刷できない文字が1つあるため、以下のパーマリンクを使用することをお勧めします。

ここでテストしてください。

説明

で暫定数字が追跡されており T、CJamは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 141138文字

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

例:

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

合計11文字の削除を支援してくれた@MegaTomと@Siegに感謝


2
10 * int(a)+ int(i)はint(a + i)ですか?
メガトム

いい視点ね!ありがとう、5文字節約できます。
モノポール

1
単一のステートメントが続くForには、間に改行は必要ありません。(-3)
-seequ

2

ルビー、149文字

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

repl.itでテスト済み


2

J、117バイト

印刷可能なアスキーのみが含まれます。(Jとunicodeで苦労しました。)行の順列-インデックスから遷移表を生成します。

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

こちらからオンラインでお試しください。


2

Haskell、131文字

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

テスト走行:

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

0

k、36文字

/ 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と同等の実装)

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

1
私はルールに疑わしいループホールの使用を賞賛する必要がありますが、文字カウントに準グループの宣言とあらゆる種類の支援機能の宣言を含めることを強制するためにルールを明確にする必要があります。
フォルス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.