Вычислить контрольную цифру, используя алгоритм Дамма


17

Существуют популярные алгоритмы контрольных цифр, такие как Luhn, а также хорошие , например алгоритм Damm. Единственная возможная причина популярности таких алгоритмов, как Luhn, заключается в том, что существует их реализация в виде кода. Это означает, что мы, как сообщество, можем изменить мир, предлагая лучшие алгоритмы.

Таким образом, эта задача состоит в том, чтобы изменить мир, написав функцию или полную программу на выбранном вами языке, которая вычисляет контрольную цифру с использованием алгоритма Дамма . Ответ с наименьшим количеством символов (не байтов) будет выбран победителем через несколько недель. Обратите внимание, что все вспомогательные функции и объявление таблицы операций должны быть включены в число символов. В случае ничьей будет выбран самый популярный ответ.

Этот алгоритм вращается вокруг операционного стола, который должен быть слабо полностью антисимметричной квазигруппой порядка 10. Операционный стол, который можно найти в статье в Википедии об алгоритме Дамма, является тем, который должен использоваться в этой задаче. Для полноты картины я воспроизведу его ниже:

    |   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

Вкратце (подробнее см. Статью в Википедии ) алгоритм работает следующим образом:

  1. Вы начинаете со списка цифр для обработки и промежуточной цифры, которая установлена ​​в 0.
  2. Для каждой цифры в списке вы вычисляете новую промежуточную цифру, используя цифру в качестве индекса столбца и предыдущую промежуточную цифру в качестве индекса строки.
  3. Последняя промежуточная цифра - контрольная цифра. Если вы проверяете номер, который уже имеет добавленную контрольную цифру, последняя промежуточная цифра будет 0, если номер действителен.

Ваша программа или функция должна принимать строку, которая может содержать любые символы, кроме нуля, но она должна касаться только цифр в строке. Он должен либо напечатать (если программа), либо вернуть (если функция) исходную строку с добавленной вычисленной контрольной цифрой. Если вы решили написать программу, программа может принять ввод в качестве аргумента или в качестве стандартного ввода. Если входная строка пуста или не содержит цифр, вы должны вернуть или добавить ноль.

Несколько примеров:

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

Я с нетерпением жду возможности увидеть записи Пайета, претендующие на победу.
Алхимик

Ответы:


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

Там есть один непечатаемый символ, поэтому вы можете использовать постоянную ссылку ниже.

Проверьте это здесь.

объяснение

Отслеживается промежуточная цифра 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 141 138 символов

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

Спасибо @MegaTom и @Sieg за помощь в удалении в общей сложности 11 символов


2
10 * int (a) + int (i) - это int (a + i), не так ли?
MegaTom

Хорошая точка зрения! Спасибо, что экономит 5 символов.
Монополь

1
За последующим единственным утверждением не требуется перевод строки между ними. (-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 байт

Содержит только для печати ASCII. (Мне было тяжело с J и юникодом.) Создает таблицу переходов из индексов перестановки строк.

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

Хаскель, 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

к, 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
Я должен сказать, что восхищаюсь использованием сомнительной лазейки в правилах, но я действительно должен разъяснить правила, чтобы обеспечить включение объявления квазигруппы и объявления любой вспомогательной функции в число символов ,
Форс
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.