The Damm algorithm is a checksum algorithm which detects all single digit errors and adjacent transposition errors.



The algorithm is named after H. Michael Damm.



Task

Verify the checksum, stored as last digit of an input.



% Verify that the Damm check digit of a string of digits is correct.
% Signals 'bad_format' if the string contains non-digits.
damm = proc (s: string) returns (bool) signals (bad_format)
    ai = array[int]
    aai = array[ai]
    own damm_table: aai := aai$[0: 
        ai$[0: 0,3,1,7,5,9,8,6,4,2],
        ai$[0: 7,0,9,2,1,5,4,8,6,3],
        ai$[0: 4,2,0,6,8,7,1,3,5,9],
        ai$[0: 1,7,5,0,9,8,3,4,2,6],
        ai$[0: 6,1,2,3,0,4,5,9,7,8],
        ai$[0: 3,6,7,4,2,0,9,5,8,1],
        ai$[0: 5,8,6,9,7,2,0,1,3,4],
        ai$[0: 8,9,4,5,3,6,2,0,1,7],
        ai$[0: 9,4,3,8,6,1,7,2,0,5],
        ai$[0: 2,5,8,1,4,3,6,7,9,0]
    ]
 
    interim: int := 0
    for c: char in string$chars(s) do
        d: int := int$parse(string$c2s(c)) resignal bad_format
        interim := damm_table[interim][d]
    end
 
    return(interim = 0)
end damm
 
% Checks
start_up = proc ()
    po: stream := stream$primary_output()
    tests: sequence[string] := sequence[string]$[
        "5724", "5727", "112946", "112949"
    ]
 
    for test: string in sequence[string]$elements(tests) do
        stream$puts(po, test || ": ")
        if damm(test) then
            stream$putl(po, "pass")
        else
            stream$putl(po, "fail")
        end
    end
end start_up