Calcola una cifra di controllo usando l'algoritmo Damm


17

Esistono algoritmi di cifre di controllo popolari come Luhn e poi ce ne sono di buoni , ad esempio l'algoritmo Damm. L'unica ragione possibile dietro la popolarità di algoritmi come Luhn è che esistono implementazioni codificate di golf. Ciò significa che come comunità abbiamo il potere di cambiare il mondo fornendo implementazioni golfizzate di algoritmi migliori.

Quindi questa sfida è cambiare il mondo scrivendo una funzione o un programma completo nella tua lingua preferita che calcola una cifra di controllo usando l' algoritmo Damm . La risposta con il minor numero di caratteri (non byte) verrà scelta come vincente in poche settimane. Si noti che tutte le funzioni di aiuto e la dichiarazione della tabella delle operazioni devono essere incluse nel conteggio dei caratteri. In caso di pareggio verrà scelta la risposta più popolare.

Questo algoritmo ruota attorno a una tabella operativa che deve essere un quasigroup debolmente totalmente anti-simmetrico dell'ordine 10. La tabella operativa che può essere trovata nell'articolo di Wikipedia sull'algoritmo Damm è quella che deve essere usata in questa sfida. Per completezza, lo riprodurrò di seguito:

    |   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

In breve (per i dettagli vedi l' articolo di Wikipedia ) l'algoritmo funziona come segue:

  1. Si inizia con un elenco di cifre da elaborare e una cifra intermedia impostata su 0.
  2. Per ogni cifra nell'elenco si calcola una nuova cifra provvisoria utilizzando la cifra come indice di colonna e la precedente cifra provvisoria come indice di riga.
  3. L'ultima cifra provvisoria è la cifra di controllo. Se si sta convalidando un numero che ha già una cifra di controllo aggiunta, la cifra intermedia finale è 0 se il numero è valido.

Il programma o la funzione deve accettare una stringa che può contenere qualsiasi carattere tranne null, ma dovrebbe riguardare solo le cifre nella stringa. Deve stampare (se un programma) o restituire (se una funzione) la stringa originale con la cifra di controllo calcolata allegata. Se si sceglie di scrivere un programma, il programma può accettare l'input come argomento o come input standard. Se la stringa di input è vuota o non contiene cifre, è necessario restituire o aggiungere uno zero.

Qualche esempio:

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

Non vedo l'ora di vedere le voci Piet reclamare la vittoria.
Alchymist

Risposte:


3

Pyth, 49 caratteri

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

Contiene dio sa quali personaggi, quindi ecco un programma Python3 per generare accuratamente il programma sopra sul tuo computer:

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

Spiegazione:

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

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

C'è un carattere non stampabile lì dentro, quindi potresti voler usare il permalink qui sotto.

Provalo qui.

Spiegazione

La cifra provvisoria viene tracciata T, che CJam inizializza a 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 caratteri

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

Esempi:

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

Grazie a @MegaTom e @Sieg per aver contribuito a rimuovere un totale di 11 caratteri


2
10 * int (a) + int (i) è int (a + i), no?
MegaTom

Buon punto! Grazie, questo consente di risparmiare 5 caratteri.
monopolo,

1
Per seguito da una singola istruzione non è necessaria una nuova riga in mezzo. (-3)
seequ

2

Rubino, 149 caratteri

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

Testato su repl.it


2

J, 117 byte

Contiene solo ASCII stampabili. (Ho avuto difficoltà con J e Unicode.) Genera la tabella di transizione dagli indici di permutazione delle righe.

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'

Uso:

   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

Provalo online qui.


2

Haskell, 131 caratteri

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

Prova:

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

0

k, 36 caratteri

/ 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 caratteri (implementazione equivalente a k)

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

1
Devo dire che ammiro l'uso di un loop discutibile nelle regole, ma devo davvero chiarire le regole per imporre l'inclusione della dichiarazione del quasi-gruppo e la dichiarazione di qualsiasi tipo di funzione di aiuto nel conteggio dei personaggi .
Fors
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.