RosettaCodeData/Task/Damm-algorithm/Agena/damm-algorithm.agena
2026-04-30 12:34:36 -04:00

43 lines
1.7 KiB
Text

scope # Damm Algorithm
# returns true if the check digit of s is correct according to the Damm algorithm,
# false otherwise #
local proc hasValidDammCheckDigit( s :: string ) :: boolean
local constant operationTable
:= seq( (/ 0, 3, 1, 7, 5, 9, 8, 6, 4, 2 \) # as per wikipedia example
, (/ 7, 0, 9, 2, 1, 5, 4, 8, 6, 3 \)
, (/ 4, 2, 0, 6, 8, 7, 1, 3, 5, 9 \)
, (/ 1, 7, 5, 0, 9, 8, 3, 4, 2, 6 \)
, (/ 6, 1, 2, 3, 0, 4, 5, 9, 7, 8 \)
, (/ 3, 6, 7, 4, 2, 0, 9, 5, 8, 1 \)
, (/ 5, 8, 6, 9, 7, 2, 0, 1, 3, 4 \)
, (/ 8, 9, 4, 5, 3, 6, 2, 0, 1, 7 \)
, (/ 9, 4, 3, 8, 6, 1, 7, 2, 0, 5 \)
, (/ 2, 5, 8, 1, 4, 3, 6, 7, 9, 0 \)
);
local interimDigit := 0;
for sPos to size s do
local constant nextDigit := abs s[ sPos ] - abs "0";
if 0 <= nextDigit and nextDigit <= 9 then
interimDigit := operationTable[ interimDigit + 1, nextDigit + 1 ]
else
error( "Invalid Damm digit: [" & s[ sPos ] & "]" )
fi
od;
return interimDigit = 0
end;
local proc testDammAlgorithm( s :: string, expectedResult :: boolean )
local constant isValid := hasValidDammCheckDigit( s );
printf( "check digit of %s is %s%s\n", s
, if isValid then "valid" else "invalid" fi
, if isValid == expectedResult then "" else " *** NOT AS EXPECTED" fi
)
end;
# test cases
testDammAlgorithm( "5724", true );
testDammAlgorithm( "5727", false );
testDammAlgorithm( "112946", true )
end