Calculer un chiffre de contrôle à l'aide de l'algorithme Damm

17

Il existe des algorithmes de chiffres de contrôle populaires tels que Luhn, puis il y en a de bons , par exemple l'algorithme Damm. La seule raison possible de la popularité d'algorithmes tels que Luhn est qu'il existe des implémentations de code de golf. Cela signifie que nous, en tant que communauté, avons le pouvoir de changer le monde en fournissant des implémentations de meilleurs algorithmes.

Ce défi consiste donc à changer le monde en écrivant une fonction ou un programme complet dans la langue de votre choix qui calcule un chiffre de contrôle à l'aide de l' algorithme Damm . La réponse avec le plus petit nombre de caractères (pas d'octets) sera choisie comme gagnante dans quelques semaines. Notez que toutes les fonctions d'aide et la déclaration de la table d'opération doivent être incluses dans le nombre de caractères. En cas d'égalité, la réponse la plus populaire sera choisie.

Cet algorithme s'articule autour d'une table d'opération qui doit être un quasigroupe faiblement totalement anti-symétrique d'ordre 10. La table d'opération qui se trouve dans l'article Wikipédia sur l'algorithme Damm est celle qui doit être utilisée dans ce défi. Par souci d'exhaustivité, je vais le reproduire ci-dessous:

    |   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

En bref (pour plus de détails, voir l'article Wikipedia ), l'algorithme fonctionne comme suit:

  1. Vous commencez avec une liste de chiffres à traiter et un chiffre intermédiaire qui est défini sur 0.
  2. Pour chaque chiffre de la liste, vous calculez un nouveau chiffre intermédiaire en utilisant le chiffre comme index de colonne et le chiffre intermédiaire précédent comme index de ligne.
  3. Le dernier chiffre intermédiaire est le chiffre de contrôle. Si vous validez un numéro qui a déjà un chiffre de contrôle ajouté, le dernier chiffre intermédiaire est 0 si le numéro est valide.

Votre programme ou fonction doit accepter une chaîne qui peut contenir tous les caractères sauf null, mais elle ne doit concerner que les chiffres de la chaîne. Il doit soit imprimer (s'il s'agit d'un programme), soit renvoyer (s'il s'agit d'une fonction) la chaîne d'origine avec le chiffre de contrôle calculé ajouté. Si vous avez choisi d'écrire un programme, le programme peut accepter l'entrée comme argument ou comme entrée standard. Si la chaîne d'entrée est vide ou ne contient aucun chiffre, vous devez retourner ou ajouter un zéro.

Quelques exemples:

Input       |   Output
------------+-------------
42          |   427
427         |   4270
2 to 2      |   2 to 29
23 42 76-   |   23 42 76-5
-           |   -0
Fors
la source
J'ai hâte de voir les entrées Piet réclamer la victoire.
Alchymist du

Réponses:

3

Pyth, 49 caractères

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

Contient Dieu sait quels caractères, voici donc un programme Python3 pour générer le programme ci-dessus avec précision sur votre machine:

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

Explication:

+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
la source
3

CJam, 54 caractères

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

Il y a un caractère non imprimable là-dedans, vous pouvez donc utiliser le lien permanent ci-dessous.

Testez-le ici.

Explication

Le chiffre intermédiaire est suivi T, que CJam initialise à 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
la source
3

Python 3, 149 141 141 138 caractères

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

Exemples:

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

Merci à @MegaTom et @Sieg d'avoir aidé à supprimer un total de 11 caractères

monopole
la source
2
10 * int (a) + int (i) est int (a + i), n'est-ce pas?
MegaTom
Bon point! Merci, cela permet d'économiser 5 caractères.
monopole
1
Car suivi d'une seule déclaration n'a pas besoin d'une nouvelle ligne entre les deux. (-3)
voir
2

Rubis, 149 caractères

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

Testé sur repl.it

MegaTom
la source
2

J, 117 octets

Contient uniquement des ascii imprimables. (J'ai eu du mal avec J et unicode.) Génère la table de transition à partir des indices de permutation des lignes.

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'

Usage:

   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

Essayez-le en ligne ici.

randomra
la source
2

Haskell, 131 caractères

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

Essai:

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

k, 36 caractères

/ 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 caractères (implémentation équivalente à k)

 f:{x,string 0{M y+10*x}/"H"$'x inter .Q.n}
user38879
la source
1
Je dois dire que j'admire l'utilisation d'une boucle discutable dans les règles, mais je dois vraiment clarifier les règles pour imposer l'inclusion de la déclaration du quasi-groupe et la déclaration de toute sorte de fonction d'aide dans le nombre de caractères .
Fors