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

42 lines
1.9 KiB
Text

do -- Damm Algorithm
-- returns true if the check digit of s is correct according to the Damm algorithm,
-- false otherwise #
local function hasValidDammCheckDigit( s : string ) : boolean
local operationTable <const> = { { 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 = 1, # s do
local nextDigit <const> = string.byte( s[ sPos ] ) - string.byte( "0" )
if 0 <= nextDigit <= 9 then
interimDigit = operationTable[ interimDigit + 1 ][ nextDigit + 1 ]
else
error( $"Invalid Damm digit: [{s[ sPos ]}]" )
end
end
return interimDigit == 0
end
local function testDammAlgorithm( s : string, expectedResult : boolean ) : void
local isValid <const> = hasValidDammCheckDigit( s )
print( $"check digit of {s} is "
.. if isValid then "valid" else "invalid" end
.. if isValid == expectedResult then "" else " *** NOT AS EXPECTED" end
)
end
-- test cases
testDammAlgorithm( "5724", true )
testDammAlgorithm( "5727", false )
testDammAlgorithm( "112946", true )
end