Damm algorithm: Difference between revisions

m
→‎{{header|ANSI BASIC}}: Unnecessary <pre> deleted.
m (typo)
m (→‎{{header|ANSI BASIC}}: Unnecessary <pre> deleted.)
 
(132 intermediate revisions by 61 users not shown)
Line 1:
{{draft task}}
 
The [https[wp://en.wikipedia.org/wiki/Damm_algorithm |'''Damm''' algorithm]] is a checksum algorithm which detects all single digit errors and adjacent transposition errors.
 
 
The algorithm is named after H. Michael Damm.
 
 
Line 9 ⟶ 12:
<!-- It's draft because I didn't specify it's requirements, see Wikipedia. -->
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
<syntaxhighlight lang="11l">V matrix = [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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]
]
 
F damm(Int num) -> Bool
V row = 0
L(digit) String(num)
row = :matrix[row][Int(digit)]
R row == 0
 
L(test) [5724, 5727, 112946]
print(test"\t Validates as: "damm(test))</syntaxhighlight>
{{out}}
<pre>
5724 Validates as: 1B
5727 Validates as: 0B
112946 Validates as: 1B
</pre>
 
 
=={{header|8080 Assembly}}==
 
<syntaxhighlight lang="8080asm"> org 100h
jmp demo
;;; Given an 0-terminated ASCII string containing digits in [DE],
;;; see if it matches its check digit. Returns with zero flag set
;;; if the string matches.
damm: mvi c,0 ; Interim digit in C, starts off at 0.
ldax d ; Get current byte from string
inx d ; Advance the pointer
ana a ; Is the byte zero?
jnz $+5 ; If not, go look up interim digit
cmp c ; But if so, see if the interim digit is also zero
ret ; And return whether this was the case
sui '0' ; Subtract ASCII 0
mov b,a ; Keep digit to be processed in B
mov a,c ; Calculate C*10 (interim digit row index)
add a ; * 2
add a ; * 4
add c ; * 5
add a ; * 10
add b ; Add column index
lxi h,dammit
add l ; Table lookup (assuming H doesn't change, i.e. it
mov l,a ; doesn't cross a page boundary).
mov c,m ; Get new interim digit from table
jmp damm+2 ; And check next character
;;; Table of interim digits
;;; NOTE: must not cross page boundary
dammit: db 0,3,1,7,5,9,8,6,4,2
db 7,0,9,2,1,5,4,8,6,3
db 4,2,0,6,8,7,1,3,5,9
db 1,7,5,0,9,8,3,4,2,6
db 6,1,2,3,0,4,5,9,7,8
db 3,6,7,4,2,0,9,5,8,1
db 5,8,6,9,7,2,0,1,3,4
db 8,9,4,5,3,6,2,0,1,7
db 9,4,3,8,6,1,7,2,0,5
db 2,5,8,1,4,3,6,7,9,0
;;; Demo code: see if the argument on the CP/M command line
;;; matches its input.
demo: lxi h,80h ; Zero-terminate input
mov e,m
mvi d,0
inx d
dad d
mov m,d
lxi d,82h ; Command line argument, skipping first space
call damm ; See if it validates
mvi c,9
lxi d,ok ; Print OK...
jz 5 ; ...if the checksum matches,
lxi d,no ; Print NOT OK otherwise.
jmp 5
no: db 'NOT '
ok: db 'OK$'</syntaxhighlight>
 
{{out}}
 
<pre>A>damm 5724
OK
A>damm 5727
NOT OK
A>damm 112946
OK
A>damm 112949
NOT OK</pre>
 
=={{header|8086 Assembly}}==
 
<syntaxhighlight lang="asm"> cpu 8086
bits 16
section .text
org 100h
jmp demo
;;; Given a 0-terminated ASCII string containing digits in
;;; [DS:SI], see if the check digit matches. Returns with zero flag
;;; set if it matches.
damm: xor cl,cl ; Interim digit starts out at 0
mov bx,.tab ; Index for table lookup
.dgt: lodsb ; Get next string byte
test al,al ; If it is zero, we're done
jz .out
sub al,'0' ; Make ASCII digit
mov ah,cl ; Table lookup, AH = interim digit
aad ; AL += AH * 10 (such handy instructions the 8086 has)
cs xlatb ; AL = CS:table[AL]
mov cl,al ; CL = new interim digit
jmp .dgt ; Get next string
.out: test cl,cl ; Interim digit should be zero at the end
ret
.tab: db 0,3,1,7,5,9,8,6,4,2 ; Table can be stored as part of the
db 7,0,9,2,1,5,4,8,6,3 ; code
db 4,2,0,6,8,7,1,3,5,9
db 1,7,5,0,9,8,3,4,2,6
db 6,1,2,3,0,4,5,9,7,8
db 3,6,7,4,2,0,9,5,8,1
db 5,8,6,9,7,2,0,1,3,4
db 8,9,4,5,3,6,2,0,1,7
db 9,4,3,8,6,1,7,2,0,5
db 2,5,8,1,4,3,6,7,9,0
;;; Demo: see if the argument on the MS-DOS command line is valid
demo: xor bh,bh ; Zero-terminate the input
mov bl,[80h]
mov [bx+81h],bh
mov si,82h ; Start of input skipping first space
call damm ; Is it valid?
mov dx,ok ; If so, print OK
jz .print
mov dx,no ; Otherwise, print NOT OK
.print: mov ah,9
int 21h
ret
section .data
no: db 'NOT '
ok: db 'OK$'</syntaxhighlight>
 
{{out}}
 
<pre>C:\>damm86 5724
OK
C:\>damm86 5725
NOT OK
C:\>damm86 112946
OK
C:\>damm86 112949
NOT OK</pre>
 
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">BYTE FUNC Damm(CHAR ARRAY a)
BYTE ARRAY table=[
0 3 1 7 5 9 8 6 4 2
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]
BYTE i,x,c
 
x=0
FOR i=1 TO a(0)
DO
c=a(i)
IF c<'0 OR c>'9 THEN
RETURN (0)
FI
c==-'0
x=table(x*10+c)
OD
IF x=0 THEN
RETURN (1)
FI
RETURN (0)
 
PROC Test(CHAR ARRAY a)
BYTE i
 
Print(a) Print(" -> ")
IF Damm(a)=1 THEN
PrintE("valid")
ELSE
PrintE("invalid")
FI
RETURN
 
PROC Main()
Test("5724")
Test("5727")
Test("112946")
Test("112949")
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Damm_algorithm.png Screenshot from Atari 8-bit computer]
<pre>
5724 -> valid
5727 -> invalid
112946 -> valid
112949 -> invalid
</pre>
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_IO;
 
procedure Damm_Algorithm is
 
function Damm (Input : in String) return Boolean
is
subtype Digit is Character range '0' .. '9';
 
Table : constant array (Digit, Digit) of Digit :=
(('0', '3', '1', '7', '5', '9', '8', '6', '4', '2'),
('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'));
Intern : Digit := '0';
begin
for D of Input loop
Intern := Table (Intern, D);
end loop;
return Intern = '0';
end Damm;
 
procedure Put_Damm (Input : in String) is
use Ada.Text_IO;
begin
Put_Line ("Damm of " & Input & " validates as " & Damm (Input)'Image);
end Put_Damm;
 
begin
Put_Damm ("5724");
Put_Damm ("5727");
Put_Damm ("112946");
Put_Damm ("112949");
end Damm_Algorithm;</syntaxhighlight>
 
{{out}}
<pre>Damm of 5724 validates as TRUE
Damm of 5727 validates as FALSE
Damm of 112946 validates as TRUE
Damm of 112949 validates as FALSE
</pre>
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68">BEGIN
# returns TRUE if the check digit of s is correct according to the Damm algorithm, #
# FALSE otherwise #
Line 61 ⟶ 328:
test damm algorithm( "5727", FALSE );
test damm algorithm( "112946", TRUE )
END</langsyntaxhighlight>
{{out}}
<pre>check digit of 5724 is valid
<pre>
check digit of 5724 is valid
check digit of 5727 is invalid
check digit of 112946 is valid</pre>
 
</pre>
=={{header|APL}}==
{{works with|Dyalog APL}}
 
This is a function that takes a vector of digits and returns a boolean.
 
<syntaxhighlight lang="apl"> damm←{⎕IO←0
tbl←⍉⍪0 3 1 7 5 9 8 6 4 2
tbl⍪← 7 0 9 2 1 5 4 8 6 3
tbl⍪← 4 2 0 6 8 7 1 3 5 9
tbl⍪← 1 7 5 0 9 8 3 7 2 6
tbl⍪← 6 1 2 3 0 4 5 9 7 8
tbl⍪← 3 6 7 4 2 0 9 5 8 1
tbl⍪← 5 8 6 9 7 2 0 1 3 4
tbl⍪← 8 9 4 5 3 6 2 0 1 7
tbl⍪← 9 4 3 8 6 1 7 2 0 5
tbl⍪← 2 5 8 1 4 3 6 7 9 0
0={tbl[⍵;⍺]}/⌽0,⍵
}</syntaxhighlight>
 
{{out}}
 
<pre> damm 5 7 2 4
1
damm 5 7 2 5
0
damm 1 1 2 9 4 6
1
damm 1 1 2 9 4 9
0</pre>
 
=={{header|AppleScript}}==
 
<syntaxhighlight lang="applescript">-- Return a check digit value for the given integer value or numeric string.
-- The result is 0 if the input's last digit is already a valid check digit for it.
on damm(n)
set digits to {n mod 10}
set n to n div 10
repeat until (n is 0)
set beginning of digits to n mod 10
set n to n div 10
end repeat
script o
property table : {0, 3, 1, 7, 5, 9, 8, 6, 4, 2, ¬
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}
end script
set interim to 0
repeat with d in digits
set interim to item (interim * 10 + d + 1) of o's table -- AppleScript indices are 1-based.
end repeat
return interim
end damm
 
-- Task code:
local testNumbers, possibilities, output, n
set testNumbers to {5724, 57240, 572400, 87591, 100}
-- Include a number with a check digit actually generated by the handler.
tell (random number 1000000) to set end of testNumbers to it * 10 + (my damm(it))
set possibilities to {" is invalid", " is valid"}
set output to {}
repeat with n in testNumbers
set end of output to (n as text) & item (((damm(n) is 0) as integer) + 1) of possibilities
end repeat
return output</syntaxhighlight>
 
{{output}}
<syntaxhighlight lang="applescript">{"5724 is valid", "57240 is valid", "572400 is valid", "87591 is invalid", "100 is invalid", "3922446 is valid"}</syntaxhighlight>
 
=={{header|ARM Assembly}}==
<syntaxhighlight lang="text">.text
.global _start
@@@ Check if the zero-terminated ASCII string in [r0],
@@@ which should contain a decimal number, has a
@@@ matching check digit. Zero flag set if true,
@@@ check digit returned in r0.
damm: mov r1,#0 @ R1 = interim digit
ldr r2,=3f @ R2 = table base address
1: ldrb r3,[r0],#1 @ Load byte
tst r3,r3 @ Zero yet?
beq 2f @ If so, stop
sub r3,r3,#'0 @ Subtract ASCII 0
lsl r1,r1,#1 @ Table lookup
add r1,r1,r1,lsl#2 @ R3 = R1*10 + R3
add r3,r1,r3
ldrb r1,[r2,r3] @ R1 = new interim digit
b 1b @ Next value
2: movs r0,r1 @ Set flag according to r0.
bx lr
3: .byte 0,3,1,7,5,9,8,6,4,2 @ Since the table is constant,
.byte 7,0,9,2,1,5,4,8,6,3 @ it can be stored as part of
.byte 4,2,0,6,8,7,1,3,5,9 @ the subroutine.
.byte 1,7,5,0,9,8,3,4,2,6 @ This way the OS will even mark
.byte 6,1,2,3,0,4,5,9,7,8 @ it as read-only, so we can
.byte 3,6,7,4,2,0,9,5,8,1 @ be sure nothing changes it.
.byte 5,8,6,9,7,2,0,1,3,4
.byte 8,9,4,5,3,6,2,0,1,7
.byte 9,4,3,8,6,1,7,2,0,5
.byte 2,5,8,1,4,3,6,7,9,0
.align 4 @ Instructions must be word-aligned
@@@ Grab the argument from the command line, and see
@@@ if it matches.
_start: pop {r0} @ Is there even an argument?
cmp r0,#2
movne r7,#1 @ If not, exit immediately
swine #0
add sp,sp,#4 @ Discard program name
pop {r0} @ Grab argument
bl damm @ Check if it matches
ldreq r1,=pass @ If yes, say 'pass'
ldrne r1,=fail @ If not, say 'fail'
mov r0,#1 @ Print string to stdout
mov r2,#5 @ Both are 5 characters
mov r7,#4 @ Write syscall = 4
swi #0
mov r0,#0 @ Exit
mov r7,#1
swi #0
pass: .ascii "Pass\n"
fail: .ascii "Fail\n"</syntaxhighlight>
 
{{out}}
 
<pre>$ for x in 5724 5725 112946 112949; do echo -n $x:; ./damm $x; done
5724:Pass
5725:Fail
112946:Pass
112949:Fail</pre>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">; by @Krenium
 
table: [
[0 3 1 7 5 9 8 6 4 2]
[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]
]
 
damm?: function [z][zero? fold digits to :integer z .seed: 0 [x y]-> table\[x]\[y] ]
 
; Or, being more explicit:
digits2: function [str][
chars: split str
result: map chars 'ch -> to :integer ch
return result
]
 
damm2?: function [str][
d: digits2 str
r: fold d .seed: 0 [x y] -> get get table x y
return r = 0
]
 
test: function [str][
result: switch damm? str -> "valid"
-> "invalid"
print [str "is" result]
]
 
loop ["5724" "5727" "112946" "112949"] => test</syntaxhighlight>
 
{{out}}
 
<pre>5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">Damm(num){
row := 1, Damm := [[0,3,1,7,5,9,8,6,4,2]
,[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]]
for i, v in StrSplit(SubStr(num, 1, -1)){
++row := Damm[row, v+1]
}
return (SubStr(num, 0)=row-1 && !Damm[row, row])
}</syntaxhighlight>
Examples:<syntaxhighlight lang="autohotkey">result := ""
for i, num in [5724, 5727, 112946, 112949]
result .= num "`tis " (Damm(num) ? "valid" : "not valid") "`n"
MsgBox % result</syntaxhighlight>
Outputs:<pre>5724 is valid
5727 is not valid
112946 is valid
112949 is not valid</pre>
 
=={{header|AWK}}==
<syntaxhighlight lang="awk"># syntax: GAWK -f DAMM_ALGORITHM.AWK
<lang AWK>
# syntax: GAWK -f DAMM_ALGORITHM.AWK
BEGIN {
damm_init()
Line 99 ⟶ 574:
damm[8] = "9438617205"
damm[9] = "2581436790"
}</syntaxhighlight>
}
</lang>
{{out}}
<pre>T 5724
T 5724
F 5727
T 112946</pre>
 
=={{header|BASIC}}==
==={{header|ANSI BASIC}}===
{{trans|GW-BASIC}}
{{works with|Decimal BASIC}}
<syntaxhighlight lang="basic">
100 REM Damm algorithm
110 OPTION BASE 0
120 DIM DT(9, 9)
130 FOR Y = 0 TO 9
140 FOR X = 0 TO 9
150 READ DT(X, Y)
160 NEXT X
170 NEXT Y
180 INPUT N$
190 DO WHILE N$ <> ""
200 LET D = 0
210 FOR I = 1 TO LEN(N$)
220 LET D = DT(VAL(MID$(N$, I, 1)), D)
230 NEXT I
240 IF D <> 0 THEN PRINT "FAIL" ELSE PRINT "PASS"
250 INPUT N$
260 LOOP
270 DATA 0, 3, 1, 7, 5, 9, 8, 6, 4, 2
280 DATA 7, 0, 9, 2, 1, 5, 4, 8, 6, 3
290 DATA 4, 2, 0, 6, 8, 7, 1, 3, 5, 9
300 DATA 1, 7, 5, 0, 9, 8, 3, 4, 2, 6
310 DATA 6, 1, 2, 3, 0, 4, 5, 9, 7, 8
320 DATA 3, 6, 7, 4, 2, 0, 9, 5, 8, 1
330 DATA 5, 8, 6, 9, 7, 2, 0, 1, 3, 4
340 DATA 8, 9, 4, 5, 3, 6, 2, 0, 1, 7
350 DATA 9, 4, 3, 8, 6, 1, 7, 2, 0, 5
360 DATA 2, 5, 8, 1, 4, 3, 6, 7, 9, 0
370 END
</syntaxhighlight>
{{out}}
<pre>
? 5724
PASS
? 5727
FAIL
? 112946
PASS
? 112949
FAIL
?
</pre>
 
==={{header|CBASIC256}}===
<syntaxhighlight lang="vb">arraybase 1
global matrix
matrix = {{0, 3, 1, 7, 5, 9, 8, 6, 4, 2}, {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}}
test = {5724, 5727, 112946}
 
for i = 1 to 3
<lang c>#include <stdbool.h>
print "Checksum test: "; rjust(string(test[i]),8); encode(test[i])
next i
end
 
function encode(n)
cad = string(n)
check = 0
for d = 1 to length(cad)
check = matrix[int(mid(cad, d, 1)), d]
next d
if check = 0 then
return " is valid"
else
return " is invalid"
end if
end function</syntaxhighlight>
{{out}}
<pre>Similar to FreeBASIC entry.</pre>
 
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">' version 04-07-2018
' compile with: fbc -s console
 
Function Damm(digit_str As String) As UInteger
 
Dim As UInteger table(10,10) => { { 0, 3, 1, 7, 5, 9, 8, 6, 4, 2 } , _
{ 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 } }
 
Dim As UInteger i, col_i, old_row_i, new_row_i
 
For i = 0 To Len(digit_str) -1
col_i = digit_str[i] - Asc("0")
new_row_i = table(old_row_i, col_i)
old_row_i = new_row_i
Next
 
Return new_row_i
 
End Function
 
' ------=< MAIN >=------
 
Data "5724", "5727", "112946", ""
 
Dim As UInteger checksum, t
Dim As String test_string
 
Do
 
Read test_string
If test_string = "" Then Exit Do
Print "Checksum test: ";test_string;
 
checksum = Damm(test_string)
If checksum = 0 Then
Print " is valid"
Else
Print " is invalid"
End If
 
Loop
 
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End</syntaxhighlight>
{{out}}
<pre>Checksum test: 5724 is valid
Checksum test: 5727 is invalid
Checksum test: 112946 is valid</pre>
 
==={{header|GW-BASIC}}===
{{works with|BASICA}}
<syntaxhighlight lang="basic">10 DEFINT D,I,X,Y: DIM DT(9,9)
20 FOR Y=0 TO 9: FOR X=0 TO 9: READ DT(X,Y): NEXT X,Y
30 INPUT N$: IF N$="" THEN END
40 D=0
50 FOR I=1 TO LEN(N$): D=DT(VAL(MID$(N$,I,1)),D): NEXT I
60 IF D THEN PRINT "FAIL" ELSE PRINT "PASS"
70 GOTO 30
100 DATA 0,3,1,7,5,9,8,6,4,2
110 DATA 7,0,9,2,1,5,4,8,6,3
120 DATA 4,2,0,6,8,7,1,3,5,9
130 DATA 1,7,5,0,9,8,3,4,2,6
140 DATA 6,1,2,3,0,4,5,9,7,8
150 DATA 3,6,7,4,2,0,9,5,8,1
160 DATA 5,8,6,9,7,2,0,1,3,4
170 DATA 8,9,4,5,3,6,2,0,1,7
180 DATA 9,4,3,8,6,1,7,2,0,5
190 DATA 2,5,8,1,4,3,6,7,9,0</syntaxhighlight>
{{out}}
<pre>? 5724
PASS
? 5727
FAIL
? 112946
PASS
? 112949
FAIL</pre>
 
==={{header|Liberty BASIC}}===
{{works with|Just BASIC}}
<syntaxhighlight lang="liberty basic">Dim DT(9, 9)
 
For y = 0 To 9
For x = 0 To 9
Read val
DT(x, y) = val
Next x
Next y
 
Input check$
While (check$ <> "")
D = 0
For i = 1 To Len(check$)
D = DT(Val(Mid$(check$, i, 1)), D)
Next i
If D Then
Print "Invalid"
Else
Print "Valid"
End If
Input check$
Wend
End
 
DATA 0,3,1,7,5,9,8,6,4,2
DATA 7,0,9,2,1,5,4,8,6,3
DATA 4,2,0,6,8,7,1,3,5,9
DATA 1,7,5,0,9,8,3,4,2,6
DATA 6,1,2,3,0,4,5,9,7,8
DATA 3,6,7,4,2,0,9,5,8,1
DATA 5,8,6,9,7,2,0,1,3,4
DATA 8,9,4,5,3,6,2,0,1,7
DATA 9,4,3,8,6,1,7,2,0,5
DATA 2,5,8,1,4,3,6,7,9,0</syntaxhighlight>
{{out}}
<pre>?5724
Valid
?5727
Invalid
?112946
Valid
?112949
Invalid</pre>
 
=== {{header|Nascom BASIC}} ===
{{trans|GW-BASIC}}
{{works with|Nascom ROM BASIC|4.7}}
<syntaxhighlight lang="basic">10 REM Damm algorithm
20 DIM DT(9,9)
30 FOR Y=0 TO 9:FOR X=0 TO 9
40 READ DT(X,Y)
50 NEXT X:NEXT Y
60 N$="":INPUT N$:IF N$="" THEN 130
70 D=0
80 FOR I=1 TO LEN(N$)
90 D=DT(VAL(MID$(N$,I,1)),D)
100 NEXT I
110 IF D THEN PRINT "FAIL":GOTO 60
120 PRINT "PASS":GOTO 60
130 END
140 DATA 0,3,1,7,5,9,8,6,4,2
150 DATA 7,0,9,2,1,5,4,8,6,3
160 DATA 4,2,0,6,8,7,1,3,5,9
170 DATA 1,7,5,0,9,8,3,4,2,6
180 DATA 6,1,2,3,0,4,5,9,7,8
190 DATA 3,6,7,4,2,0,9,5,8,1
200 DATA 5,8,6,9,7,2,0,1,3,4
210 DATA 8,9,4,5,3,6,2,0,1,7
220 DATA 9,4,3,8,6,1,7,2,0,5
230 DATA 2,5,8,1,4,3,6,7,9,0
</syntaxhighlight>
{{out}}
<pre>
? 5724
PASS
? 5727
FAIL
? 112946
PASS
? 112949
FAIL
?
</pre>
 
==={{header|PureBasic}}===
<syntaxhighlight lang="purebasic">DataSection
DT_Start:
Data.b 0,3,1,7,5,9,8,6,4,2
Data.b 7,0,9,2,1,5,4,8,6,3
Data.b 4,2,0,6,8,7,1,3,5,9
Data.b 1,7,5,0,9,8,3,4,2,6
Data.b 6,1,2,3,0,4,5,9,7,8
Data.b 3,6,7,4,2,0,9,5,8,1
Data.b 5,8,6,9,7,2,0,1,3,4
Data.b 8,9,4,5,3,6,2,0,1,7
Data.b 9,4,3,8,6,1,7,2,0,5
Data.b 2,5,8,1,4,3,6,7,9,0
EndDataSection
 
Procedure.i Adr(Row,Col) : ProcedureReturn ?DT_Start+Row+10*Col : EndProcedure
 
Procedure.b CheckDamm(Value.s)
*ipc.Character=@Value : it=0
While *ipc\c
it=PeekB(Adr(*ipc\c-'0',it)) : *ipc+SizeOf(Character)
Wend
ProcedureReturn Bool(it)
EndProcedure
 
If OpenConsole()
Repeat
Print("Check Damm: ") : i$=Input()
If CheckDamm(i$) : PrintN(Space(12)+"FALSE") : Else : PrintN(Space(12)+"TRUE") : EndIf
Until i$=""
EndIf
End</syntaxhighlight>
{{out}}
<pre>Check Damm: 5724
TRUE
Check Damm: 5727
FALSE
Check Damm: 112946
TRUE
Check Damm: 112949
FALSE
Check Damm:
</pre>
 
==={{header|uBasic/4tH}}===
{{trans|Visual Basic .NET}}
{{works with|v3.64}}
<syntaxhighlight lang="text">Push 0, 3, 1, 7, 5, 9, 8, 6, 4, 2: i = FUNC(_Data(0))
Push 7, 0, 9, 2, 1, 5, 4, 8, 6, 3: i = FUNC(_Data(i))
Push 4, 2, 0, 6, 8, 7, 1, 3, 5, 9: i = FUNC(_Data(i))
Push 1, 7, 5, 0, 9, 8, 3, 4, 2, 6: i = FUNC(_Data(i))
Push 6, 1, 2, 3, 0, 4, 5, 9, 7, 8: i = FUNC(_Data(i))
Push 3, 6, 7, 4, 2, 0, 9, 5, 8, 1: i = FUNC(_Data(i))
Push 5, 8, 6, 9, 7, 2, 0, 1, 3, 4: i = FUNC(_Data(i))
Push 8, 9, 4, 5, 3, 6, 2, 0, 1, 7: i = FUNC(_Data(i))
Push 9, 4, 3, 8, 6, 1, 7, 2, 0, 5: i = FUNC(_Data(i))
Push 2, 5, 8, 1, 4, 3, 6, 7, 9, 0: i = FUNC(_Data(i))
' Read the table
Push 112949, 112946, 5727, 5724 ' Put numbers on the stack
 
For i = 1 To Used() ' Read up to the number of stack items
Print Using "______"; Tos();" is "; ' Print the header
If FUNC(_Damm (Str(Pop()))) Then Print "in";
Print "valid" ' invalid only if Damm() returns TRUE
Next ' Next stack item
 
End
 
_Data Param (1) ' Reads data in reverse order,
Local (2) ' starting with A@
c@ = a@ + Used() ' Calculate next offset
 
For b@ = c@-1 To a@ Step -1 ' Now place the elements
@(b@) = Pop() ' that are retrieved from the stack
Next b@ ' Next item
 
Return (c@) ' Return new offset
 
 
_Damm Param (1) ' Perform the Damm algorithm
Local (2)
 
c@ = 0 ' Reset the flag
For b@ = 0 To Len(a@) - 1 ' Check all characters in the string
c@ = @(c@*10 + peek(a@, b@) - ord("0"))
Next ' Next character
 
Return (c@) ' Return Flag</syntaxhighlight>
{{Out}}
<pre> 5724 is valid
5727 is invalid
112946 is valid
112949 is invalid
 
0 OK, 0:984</pre>
Although the output of this version is virtually identical, it uses uBasic/4tH features consistently and is consequently much shorter.
<syntaxhighlight lang="text">Proc _IsDamm (5724)
Proc _IsDamm (5727)
Proc _IsDamm (112946)
Proc _IsDamm (112949)
 
End
 
_Damm
Param (1)
Local (1)
 
b@ := "0317598642709215486342068713591750983426612304597836742095815869720134894536201794386172052581436790"
 
Do Until a@ = 0 ' until number is consumed
Push a@ % 10 : a@ = a@ / 10 ' extract digit and put on stack
Loop
 
Do While Used () ' last number retrieved?
a@ = Peek(b@, (a@ * 10) + Pop ()) - Ord ("0")
Loop ' calculate checksum
Return (a@) ' return checksum
 
_IsDamm ' evaluate and print checksum
Param (1)
Print Using "______";a@;" is ";Show (Iif (Func (_Damm (a@)), "invalid", "valid"))
Return</syntaxhighlight>
 
==={{header|Visual Basic .NET}}===
{{trans|C#}}
<syntaxhighlight lang="vbnet">Module Module1
 
ReadOnly table = {
{0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
{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}
}
 
Function Damm(s As String) As Boolean
Dim interim = 0
For Each c In s
interim = table(interim, AscW(c) - AscW("0"))
Next
Return interim = 0
End Function
 
Sub Main()
Dim numbers = {5724, 5727, 112946, 112949}
For Each number In numbers
Dim isvalid = Damm(number.ToString())
If isvalid Then
Console.WriteLine("{0,6} is valid", number)
Else
Console.WriteLine("{0,6} is invalid", number)
End If
Next
End Sub
 
End Module</syntaxhighlight>
{{out}}
<pre> 5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
 
=={{header|BCPL}}==
<syntaxhighlight lang="bcpl">get "libhdr"
 
let Damm(ns) = valof
$( let dt = table
0,3,1,7,5,9,8,6,4,2,
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
let idgt = 0
for i=1 to ns%0
test '0' <= ns%i <= '9'
do idgt := dt!(ns%i-'0' + 10*idgt)
or resultis false
resultis idgt = 0
$)
 
let check(ns) be
writef("%S: %S*N", ns, damm(ns) -> "pass", "fail")
let start() be
$( check("5724")
check("5727")
check("112946")
check("112949")
$)</syntaxhighlight>
{{out}}
<pre>5724: pass
5727: fail
112946: pass
112949: fail</pre>
 
=={{header|BQN}}==
 
'''Translation of:''' [[J]]
 
<syntaxhighlight lang="bqn">table ← >⟨ 0‿3‿1‿7‿5‿9‿8‿6‿4‿2
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 ⟩
 
 
Digits ← 10{⌽𝕗|⌊∘÷⟜𝕗⍟(↕1+·⌊𝕗⋆⁼1⌈⊢)}
 
Damm ← {0=0(table⊑˜⋈)˜´⌽Digits 𝕩}
 
Damm¨5724‿5727‿112946</syntaxhighlight>
<syntaxhighlight lang="text">⟨ 1 0 1 ⟩</syntaxhighlight>
 
[https://mlochbaum.github.io/BQN/try.html#code=dGFibGUg4oaQID7in6ggMOKAvzPigL8x4oC/N+KAvzXigL854oC/OOKAvzbigL804oC/MgogICAgICAgICAgIDfigL8w4oC/OeKAvzLigL8x4oC/NeKAvzTigL844oC/NuKAvzMKICAgICAgICAgICA04oC/MuKAvzDigL824oC/OOKAvzfigL8x4oC/M+KAvzXigL85CiAgICAgICAgICAgMeKAvzfigL814oC/MOKAvznigL844oC/M+KAvzTigL8y4oC/NgogICAgICAgICAgIDbigL8x4oC/MuKAvzPigL8w4oC/NOKAvzXigL854oC/N+KAvzgKICAgICAgICAgICAz4oC/NuKAvzfigL804oC/MuKAvzDigL854oC/NeKAvzjigL8xCiAgICAgICAgICAgNeKAvzjigL824oC/OeKAvzfigL8y4oC/MOKAvzHigL8z4oC/NAogICAgICAgICAgIDjigL854oC/NOKAvzXigL8z4oC/NuKAvzLigL8w4oC/MeKAvzcKICAgICAgICAgICA54oC/NOKAvzPigL844oC/NuKAvzHigL834oC/MuKAvzDigL81CiAgICAgICAgICAgMuKAvzXigL844oC/MeKAvzTigL8z4oC/NuKAvzfigL854oC/MCDin6kKCgpEaWdpdHMg4oaQIDEwe+KMvfCdlZd84oyK4oiYw7fin5zwnZWX4o2fKOKGlTErwrfijIrwnZWX4ouG4oG8MeKMiOKKoil9CgpEYW1tIOKGkCB7MD0wKHRhYmxl4oqRy5zii4gpy5zCtOKMvURpZ2l0cyDwnZWpfQoKRGFtbcKoNTcyNOKAvzU3MjfigL8xMTI5NDY= Try It!]
 
=={{header|C}}==
<syntaxhighlight lang="c">#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
Line 139 ⟶ 1,086:
puts(damm(input, 4) ? "Checksum correct" : "Checksum incorrect");
return 0;
}</langsyntaxhighlight>
 
{{out}}
=={{header|Clojure}}==
 
<pre>Checksum correct</pre>
<lang clojure>(def tbl [[0 3 1 7 5 9 8 6 4 2]
 
=={{header|C sharp|C#}}==
{{trans|Java}}
<syntaxhighlight lang="csharp">using System;
 
namespace DammAlgorithm {
class Program {
static int[,] table = {
{0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
{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},
};
 
static bool Damm(string s) {
int interim = 0;
foreach (char c in s) {
interim = table[interim, c - '0'];
}
return interim == 0;
}
 
static void Main(string[] args) {
int[] numbers = { 5724, 5727, 112946, 112949 };
foreach (int number in numbers) {
bool isValid = Damm(number.ToString());
if (isValid) {
Console.WriteLine("{0,6} is valid", number);
}
else {
Console.WriteLine("{0,6} is invalid", number);
}
}
}
}
}</syntaxhighlight>
{{out}}
<pre> 5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
 
=={{header|C++}}==
===Version 1===
{{trans|C#|C sharp}}
<syntaxhighlight lang="cpp">#include <string>
 
#include <cstdio>
 
inline constexper int TABLE[][10] = {
{0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
{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},
};
 
[[nodiscard]] bool damm(std::string s) noexcept {
int interim = 0;
for (const auto c : s) {
interim = TABLE[interim][c - '0'];
}
return interim == 0;
}
 
int main() {
for (const auto num : { 5724, 5727, 112946, 112949 }) {
if (damm(std::to_string(num))) {
std::printf("%6d is valid\n", num);
}
else std::printf("%6d is invalid\n", num);
}
}</syntaxhighlight>
{{out}}
<pre> 5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
 
===Version 2===
<syntaxhighlight lang="cpp">
// Compile with:
// g++ -std=c++20 -Wall -Wextra -pedantic damm.cpp -o damm
 
#include <iostream>
#include <array> // for std::array
#include <string> // for std::string, std::to_string and std::string::find
 
const std::array<std::array<int, 10>, 10> table = {{ // Operation table
{0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
{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}
}};
 
bool damm(int input) {
int interim = 0; // initialise to 0
const std::string digit = "0123456789";
for (const auto c : std::to_string(input))
interim = table[interim][digit.find(c)];
// Process the number digit by digit:
// 1. The column index = number's digit
// 2. The row index = interim digit
// 3. Replace interim digit with table entry (table[<interim digit>][<number's digit>])
return interim == 0; // Is interim digit equals zero? If so, the input is valid, invalid otherwise.
}
 
int main() {
for (const auto num : {5724, 5727, 112946, 112949})
std::cout << num << "\t" << "Checksum is " << (damm(num) ? "valid" : "invalid") << std::endl;
return 0;
}
</syntaxhighlight>
{{out}}
<pre>
5724 Checksum is valid
5727 Checksum is invalid
112946 Checksum is valid
112949 Checksum is invalid
</pre>
 
=={{header|Caché ObjectScript}}==
 
<syntaxhighlight lang="cos">Class Utils.Check [ Abstract ]
{
 
ClassMethod Damm(num As %Integer, mode As %Integer = 1) As %Integer
{
TRY {
I mode=0 RETURN ..Damm(num,2)=0
S res=0, str=num
S table=[
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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]
]
F i=1:1:$L(str) S res=table.%Get(res).%Get($E(str,i))
I mode=1 S res=num_res
} CATCH {
S res=""
}
Q res
}
 
}</syntaxhighlight>
{{out|Examples}}
<pre>USER>For { Read n Quit:n="" Write ": "_##class(Utils.Check).Damm(n, 0), ! }
5724: 1
5727: 0
112946: 1
112949: 0
 
USER>w ##class(Utils.Check).Damm(11294)
112946
USER></pre>
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(def tbl [[0 3 1 7 5 9 8 6 4 2]
[7 0 9 2 1 5 4 8 6 3]
[4 2 0 6 8 7 1 3 5 9]
Line 156 ⟶ 1,285:
(defn damm? [digits]
(= 0 (reduce #(nth (nth tbl %1) %2) 0
(map #(Character/getNumericValue %) (seq digits)))))</langsyntaxhighlight>
 
{{Out}}
<pre>=> (damm? "5724")
=> (damm? "5724")
true
=> (damm? "5727")
false
=> (damm? "112946")
true</pre>
 
</pre>
=={{header|CLU}}==
<syntaxhighlight lang="clu">% 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</syntaxhighlight>
{{out}}
<pre>5724: pass
5727: fail
112946: pass
112949: fail</pre>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
 
# Damm test on number given as ASCII string
# Returns check digit
sub damm(num: [uint8]): (chk: uint8) is
var table: uint8[] := {
0,3,1,7,5,9,8,6,4,2,
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
};
chk := 0;
while [num] != 0 loop
chk := table[(chk<<1) + (chk<<3) + ([num] - '0')];
num := @next num;
end loop;
end sub;
 
# Test and print
sub test(num: [uint8]) is
print(num);
print(":");
if damm(num) == 0 then
print("Pass\n");
else
print("Fail\n");
end if;
end sub;
 
test("5724");
test("5727");
test("112946");
test("112949");</syntaxhighlight>
 
{{out}}
 
<pre>5724:Pass
5727:Fail
112946:Pass
112949:Fail</pre>
 
=={{header|D}}==
<langsyntaxhighlight Dlang="d">import std.stdio;
 
auto table = [
Line 204 ⟶ 1,429:
}
}
}</langsyntaxhighlight>
{{out}}
<pre> 5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
 
=={{header|Delphi}}==
See [[#Pascal|Pascal]].
 
=={{header|Dyalect}}==
 
<syntaxhighlight lang="dyalect">let table = [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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]
]
 
func damm(s) {
var interim = 0
for c in s {
interim = table[interim][Integer(c)]
}
return interim == 0;
}
 
let numbers = [5724, 5727, 112946, 112949]
for number in numbers {
let isValid = damm(number.ToString())
if isValid {
print("\(number) is valid")
} else {
print("\(number) is invalid")
}
}</syntaxhighlight>
 
{{out}}
 
<pre>5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
 
=={{header|Draco}}==
<syntaxhighlight lang="draco">proc damm(*char str) bool:
[10][10]byte dammtbl = (
(0,3,1,7,5,9,8,6,4,2),
(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)
);
byte interim;
char c;
channel input text ch;
interim := 0;
open(ch, str);
while read(ch; c) do
interim := dammtbl[interim][c-'0']
od;
close(ch);
interim = 0
corp
 
proc check(*char str) void:
writeln(str, ": ", if damm(str) then "pass" else "fail" fi)
corp
 
proc main() void:
check("5724");
check("5727");
check("112946");
check("112949");
corp</syntaxhighlight>
{{out}}
<pre>5724: pass
5727: fail
112946: pass
112949: fail</pre>
 
=={{header|EasyLang}}==
{{trans|Java}}
<syntaxhighlight>
func damm inp$ .
table[][] = [ [ 0 3 1 7 5 9 8 6 4 2 ] [ 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 ] ]
inp[] = number strchars inp$
for v in inp[]
inter = table[inter + 1][v + 1]
.
return if inter = 0
.
nums[] = [ 5724 5727 112946 112949 ]
for v in nums[]
write v & " is "
if damm v = 1
print "valid"
else
print "invalid"
.
.
</syntaxhighlight>
 
=={{header|Excel|Excel}}==
 
Place your number in A1 and the formula at any cell.
 
<syntaxhighlight lang="excel">
=REDUCE(0,MID(A1,SEQUENCE(1,LEN(A1)),1),LAMBDA(i,j,INDEX({0,3,1,7,5,9,8,6,4,2;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},i+1,j+1)))
</syntaxhighlight>
 
For Google Sheets, you need to use arrayformula
 
<syntaxhighlight lang="excel">
=REDUCE(0,arrayformula(MID(A1,SEQUENCE(1,LEN(A1)),1)),lambda(i,j,INDEX({0,3,1,7,5,9,8,6,4,2;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},i+1,j+1)))
</syntaxhighlight>
 
For countries that uses comma as a decimal divisor, use:
 
<syntaxhighlight lang="excel">
=REDUCE(0;MID(A2;SEQUENCE(1;LEN(A2));1);lambda(i;j;INDEX({0\3\1\7\5\9\8\6\4\2;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};i+1;j+1)))
</syntaxhighlight>
 
=={{header|F Sharp|F#}}==
<syntaxhighlight lang="fsharp">open System
 
let TABLE = [|
[|0; 3; 1; 7; 5; 9; 8; 6; 4; 2|];
[|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|];
|]
 
let damm str =
let rec helper (v:string) interim =
if v.Length = 0 then 0 = interim
else helper (v.Substring(1)) (TABLE.[interim].[(int (v.[0])) - (int '0')])
helper str 0
[<EntryPoint>]
let main _ =
let numbers = [|5724; 5727; 112946; 112949|]
for number in numbers do
let isValid = damm (number.ToString())
if isValid then
printfn "%6d is valid" number
else
printfn "%6d is invalid" number
 
0 // return an integer exit code
</syntaxhighlight>
{{out}}
<pre> 5724 is valid
Line 211 ⟶ 1,603:
112946 is valid
112949 is invalid</pre>
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: interpolate kernel math math.parser qw sequences ;
 
CONSTANT: table
{
{ 0 3 1 7 5 9 8 6 4 2 }
{ 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 }
}
 
: damm? ( str -- ? )
0 [ digit> swap table nth nth ] reduce zero? ;
 
qw{ 5724 5727 112946 112949 }
[ dup damm? "" "in" ? [I ${} is ${}validI] nl ] each</syntaxhighlight>
{{out}}
<pre>
5724 is valid
5727 is invalid
112946 is valid
112949 is invalid
</pre>
 
 
=={{header|Forth}}==
 
{{works with|gforth|0.7.3}}
 
<syntaxhighlight lang="forth">: newdigit ( col row -- u ) 10 * + C" 0317598642709215486342068713591750983426612304597836742095815869720134894536201794386172052581436790" 1+ + c@ 48 - ;
: nextdigit ( addr -- addr+1 u ) dup c@ 48 - swap 1+ swap ;
 
: damm ( c u -- u )
0 rot rot
0 do
nextdigit
rot newdigit swap
loop drop
;
 
: isdamm? damm 0= if ." yes" else ." no" then ;
 
: .damm
2dup damm
rot rot type 48 + emit
;</syntaxhighlight>
 
{{out}}
<pre>s" 5724" isdamm? yes ok
s" 5727" isdamm? no ok
s" 572" .damm 5724 ok
</pre>
 
=={{header|Fortran}}==
Thanks to the ability standardised in F90 to define an array with a lower bound other than one, this can be achieved without the need for annoying offsets, as in A(i + 1) instead of just A(i). However, right from the start, Fortran has stored arrays in column-major order, so statements that initialise two-dimensional arrays via a list of consecutive values can look odd when they are nicely laid out, because they will have to be be in transposed order. Alternatively, if the layout is the same as the expected (row,column) usage, the actual usage of the array will have to be (column,row). Rather than transpose a ten by ten matrix, this is the approach here. The continuation column has the (apparent) row count, but row zero can't have the digit zero in the continuation column as this is taken to be equivalent to a space (meaning "no continuation") just in case it is used for the first line of a statement to be continued. However, the letter o will do instead. A capital O looks too much like a 0...
Possibly a more useful function would be one that returned the check digit that must be appended to a sequence to provide the full sequence, as when preparing a checksummed sequence for output. For checking input, such a function would be applied to all but the last digit of the suspect sequence, and its result compared to the supplied last digit. But for simplicity here, all that is reported is "good" or "bad", without hints as to what would have been good. <langsyntaxhighlight Fortranlang="fortran"> LOGICAL FUNCTION DAMM(DIGIT) !Check that a sequence of digits checks out..
Calculates according to the method of H. Michael Damm, described in 2004.
CHARACTER*(*) DIGIT !A sequence of digits only.
Line 246 ⟶ 1,697:
WRITE (6,*) DAMM("112946"),"112946"
END </langsyntaxhighlight>
Output:
<pre> T 5724
T 5724
F 5727
T 112946</pre>
 
</pre>
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Damm_algorithm}}
 
'''Solution'''
 
[[File:Fōrmulæ - Damm algorithm 01.png]]
 
'''Test cases'''
 
[[File:Fōrmulæ - Damm algorithm 02.png]]
 
[[File:Fōrmulæ - Damm algorithm 03.png]]
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import "fmt"
 
var table = [10][10]byte{
{0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
{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},
}
 
func damm(input string) bool {
var interim byte
for _, c := range []byte(input) {
interim = table[interim][c-'0']
}
return interim == 0
}
 
func main() {
for _, s := range []string{"5724", "5727", "112946", "112949"} {
fmt.Printf("%6s %t\n", s, damm(s))
}
}</syntaxhighlight>
{{out}}
<pre> 5724 true
5727 false
112946 true
112949 false</pre>
 
=={{header|Groovy}}==
{{trans|Java}}
<syntaxhighlight lang="groovy">class DammAlgorithm {
private static final int[][] TABLE = [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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],
]
 
private static boolean damm(String s) {
int interim = 0
for (char c : s.toCharArray()) interim = TABLE[interim][c - ('0' as Character)]
return interim == 0
}
 
static void main(String[] args) {
int[] numbers = [5724, 5727, 112946, 112949]
for (Integer number : numbers) {
boolean isValid = damm(number.toString())
if (isValid) {
System.out.printf("%6d is valid\n", number)
} else {
System.out.printf("%6d is invalid\n", number)
}
}
}
}</syntaxhighlight>
{{out}}
<pre> 5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">import Data.Char (digitToInt)
import Text.Printf (printf)
 
damm :: String -> Bool
damm = (==0) . foldl (\r -> (table !! r !!) . digitToInt) 0
where
table =
[ [0, 3, 1, 7, 5, 9, 8, 6, 4, 2]
, [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] ]
 
main :: IO ()
main = mapM_ (uncurry(printf "%6s is valid: %s\n") . ((,) <*> show . damm) . show)
[5724, 5727, 112946, 112949]</syntaxhighlight>
{{out}}
<pre> 5724 is valid: True
5727 is valid: False
112946 is valid: True
112949 is valid: False</pre>
 
=={{header|J}}==
'''Solution:'''
<langsyntaxhighlight lang="j">OpTbl=: _99 ". ];._2 noun define
0 3 1 7 5 9 8 6 4 2
7 0 9 2 1 5 4 8 6 3
Line 278 ⟶ 1,845:
)
 
checkDamm=: 0 = getDamm</langsyntaxhighlight>
'''Example Usage:'''
<langsyntaxhighlight lang="j"> checkDamm&> 5724 5727 112946
1 0 1</langsyntaxhighlight>
 
Or,
 
<syntaxhighlight lang="j">checkdamm=: {{0=((".;._2{{)n
0 7 4 1 6 3 5 8 9 2
3 0 2 7 1 6 8 9 4 5
1 9 0 5 2 7 6 4 3 8
7 2 6 0 3 4 9 5 8 1
5 1 8 9 0 2 7 3 6 4
9 5 7 8 4 0 2 6 1 3
8 4 1 3 5 9 0 2 7 6
6 8 3 4 9 5 1 0 2 7
4 6 5 2 7 8 3 1 0 9
2 3 9 6 8 1 4 7 5 0
}}){~<@,)/|.0,10#.inv y}}"0</syntaxhighlight>
 
<syntaxhighlight lang="j"> checkdamm 5724 5727 112946
1 0 1</syntaxhighlight>
 
We could probably replace that embedded table with something more concise if the description of the math behind the algorithm on the wikipedia page was more complete. (See talk page.)
 
=={{header|Java}}==
{{trans|Kotlin}}
<langsyntaxhighlight Javalang="java">public class DammAlgorithm {
private static final int[][] table = {
{0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
Line 316 ⟶ 1,903:
}
}
}</langsyntaxhighlight>
{{out}}
<pre> 5724 is valid
Line 323 ⟶ 1,910:
112949 is invalid</pre>
 
=={{header|JuliaJavaScript}}==
<syntaxhighlight lang="javascript">const table = [
{{works with|Julia|0.6}}
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
{{trans|Python}}
[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],
];
 
const lookup = (p, c) => table[p][parseInt(c, 10)]
<lang julia>function checkdigit(input::AbstractString)
const damm = input => [...input].reduce(lookup, 0) === 0;
all(isnumber, input) || throw(ArgumentError("input must be all digits"))
 
// ----------------------------------------------------------[ Tests ]----
const test = () => ["5724", "5727", "112946", "112949"].forEach(e =>
console.log(`${e} => ${damm(e) ? 'Pass' : 'Fail'}`)
);
test();
</syntaxhighlight>
{{out}}
<pre>
5724 => Pass
5727 => Fail
112946 => Pass
112949 => Fail
</pre>
 
=={{header|jq}}==
<syntaxhighlight lang="jq">def checkdigit:
[[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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]]
as $m
| tostring | explode
# "0" is 48
| 0 == reduce (.[] - 48) as $d (0; $m[.][$d] );
# The task:
5724, 5727, 112946, 112949
| checkdigit as $d
| [., $d]
</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">
[5724,true]
[5727,false]
[112946,true]
[112949,false]
</syntaxhighlight>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">function checkdigit(n)
matrix = (
(0, 3, 1, 7, 5, 9, 8, 6, 4, 2),
Line 342 ⟶ 1,985:
(2, 5, 8, 1, 4, 3, 6, 7, 9, 0))
row = 0
for d in inputstring(n)
row = matrix[row + 1][d - '0' + 1]
end
return row
end</lang>
 
foreach(i -> println("$i validates as: ", checkdigit(string(i)) == 0), [5724, 5727, 112946])
</syntaxhighlight>{{output}}
<pre>
5724 validates as: true
5727 validates as: false
112946 validates as: true
</pre>
 
=={{header|Kotlin}}==
<langsyntaxhighlight lang="scala">// version 1.1.2
 
val table = arrayOf(
Line 376 ⟶ 2,027:
println("${"%6d".format(number)} is ${if (isValid) "valid" else "invalid"}")
}
}</langsyntaxhighlight>
 
{{out}}
<pre> 5724 is valid
5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">local tab = {
<lang lua>
local tab = {
{0,3,1,7,5,9,8,6,4,2}, {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},
Line 411 ⟶ 2,059:
if not r then io.write( "in" ) end
io.write( "valid!\n" )
end</syntaxhighlight>
end
{{out}}
</lang>
<pre>Enter the number to check: 5724
{{out}}<pre>
Enter the number to check: 5724
5724 is valid!
Enter the number to check: 5727
Line 420 ⟶ 2,067:
Enter the number to check: 112946
112946 is valid!
Enter the number to check: 0</pre>
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Damm_Algorithm{
Function Prepare {
function OperationTable {
data (0, 3, 1, 7, 5, 9, 8, 6, 4, 2)
data (7, 0, 9, 2, 1, 5, 4, 8, 6, 3)
data (4, 2, 0, 6, 8, 7, 1, 3, 5, 9)
data (1, 7, 5, 0, 9, 8, 3, 4, 2, 6)
data (6, 1, 2, 3, 0, 4, 5, 9, 7, 8)
data (3, 6, 7, 4, 2, 0, 9, 5, 8, 1)
data (5, 8, 6, 9, 7, 2, 0, 1, 3, 4)
data (8, 9, 4, 5, 3, 6, 2, 0, 1, 7)
data (9, 4, 3, 8, 6, 1, 7, 2, 0, 5)
data (2, 5, 8, 1, 4, 3, 6, 7, 9, 0)
=array([])
}
Digits= Lambda (d) ->{
d$=str$(d,"")
for i=1 to len(d$)
data val(mid$(d$,i,1))
next
=Array([])
}
=Lambda a()=OperationTable(), Digits (N) -> {
dim b()
b()=Digits(N)
m=0
for i=0 to len(b())-1
m=a(m)(b(i))
next i
=m
}
}
Damm=Prepare()
Data 5724, 5727, 112946, 112940
while not empty
over ' double the top of stack
over
Print number, Damm(number), Damm(number)=0
End While
}
Damm_Algorithm
</syntaxhighlight>
{{out}}
<pre>
5724 0 True
5727 9 False
112946 0 True
112940 5 False
</pre>
=={{header|MACRO-11}}==
<syntaxhighlight lang="macro11"> .TITLE DAMMAL
.MCALL .GTLIN,.PRINT,.EXIT
DAMMAL::JMP DEMO
 
; VALIDATE DAMM STRING IN R0; ZERO FLAG SET IF VALID
=={{header|Perl 6}}==
DAMM: CLR R2 ; INTERIM DIGIT
{{works with|Rakudo|2017.05}}
BR 2$
1$: SUB #60,R1 ; DIGIT?
BCS 3$ ; IF NOT, NOT VALID
CMP R1,#^D9
BGT 3$
MOV R2,R3 ; CALCULATE DAMM TABLE INDEX
ASL R3
ASL R3
ADD R2,R3
ASL R3
ADD R1,R3
MOVB 4$(R3),R2 ; GET NEW INTERIM DIGIT FROM TABLE
2$: MOVB (R0)+,R1 ; NEXT CHAR
BNE 1$ ; END OF STRING?
TST R2 ; IF SO, CHECK IF INTERIM DIGIT IS 0
3$: RTS PC
4$: .BYTE ^D0,^D3,^D1,^D7,^D5,^D9,^D8,^D6,^D4,^D2
.BYTE ^D7,^D0,^D9,^D2,^D1,^D5,^D4,^D8,^D6,^D3
.BYTE ^D4,^D2,^D0,^D6,^D8,^D7,^D1,^D3,^D5,^D9
.BYTE ^D1,^D7,^D5,^D0,^D9,^D8,^D3,^D4,^D2,^D6
.BYTE ^D6,^D1,^D2,^D3,^D0,^D4,^D5,^D9,^D7,^D8
.BYTE ^D3,^D6,^D7,^D4,^D2,^D0,^D9,^D5,^D8,^D1
.BYTE ^D5,^D8,^D6,^D9,^D7,^D2,^D0,^D1,^D3,^D4
.BYTE ^D8,^D9,^D4,^D5,^D3,^D6,^D2,^D0,^D1,^D7
.BYTE ^D9,^D4,^D4,^D8,^D6,^D1,^D7,^D2,^D0,^D5
.BYTE ^D2,^D5,^D8,^D1,^D4,^D3,^D6,^D7,^D9,^D0
 
DEMO: .GTLIN #5$ ; READ LINE
<lang perl6>sub damm ( *@digits ) {
my @tbl = [0, 3,MOV 1, 7, 5, 9, 8, 6, 4, 2]#5$,R0
TSTB (R0) [7, 0, 9, 2, 1, 5, 4, 8, 6, 3], ; EMPTY LINE?
BNE [4, 2, 0, 6, 8, 7, 1, 3, 5, 9],$
.EXIT [1, 7, 5, 0, 9, 8, 3, 4, 2 ; IF SO, 6],STOP
1$: JSR PC,DAMM [6, 1, 2, 3, 0, 4,; 5,TEST 9, 7, 8],LINE
BNE 2$ [3, 6, 7, 4, 2, 0, 9, 5, 8,; 1],FAIL?
.PRINT [5, 8, 6, 9, 7, 2, 0, 1, #3, 4],$
BR [8, 9, 4, 5, 3, 6, 2, 0, 1, 7],DEMO
2$: .PRINT #4$ [9, 4, 3, 8, 6, 1, 7, 2, 0,; 5],PASS?
BR [2, 5, 8, 1, 4, 3, 6, 7, 9, 0];DEMO
3$: .ASCIZ /PASS/
4$: .ASCIZ /FAIL/
5$: .BLKB 200
.END DAMMAL</syntaxhighlight>
{{out}}
<pre>5724
PASS
5727
FAIL
112946
PASS
112949
FAIL</pre>
=={{header|MAD}}==
<syntaxhighlight lang="mad"> NORMAL MODE IS INTEGER
 
R VERIFY DAMM CHECKSUM OF NUMBER
INTERNAL FUNCTION(CKNUM)
VECTOR VALUES DAMMIT =
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
DIMENSION DAMDGT(10)
ENTRY TO DAMM.
TMP=CKNUM
THROUGH GETDGT, FOR NDGT=0, 1, TMP.E.0
DAMDGT(NDGT) = TMP-TMP/10*10
GETDGT TMP = TMP/10
INTRM = 0
THROUGH CKDGT, FOR NDGT=NDGT, -1, NDGT.L.0
CKDGT INTRM = DAMMIT(INTRM*10 + DAMDGT(NDGT))
FUNCTION RETURN INTRM.E.0
END OF FUNCTION
R TEST SOME NUMBERS
THROUGH TEST, FOR VALUES OF N = 5724,5727,112946,112949
WHENEVER DAMM.(N)
PRINT FORMAT VALID,N
OTHERWISE
PRINT FORMAT INVAL,N
TEST END OF CONDITIONAL
VECTOR VALUES VALID = $I9,S1,5HVALID*$
VECTOR VALUES INVAL = $I9,S1,7HINVALID*$
END OF PROGRAM
</syntaxhighlight>
 
{{out}}
 
<pre> 5724 VALID
5727 INVALID
112946 VALID
112949 INVALID</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">matrix = {{0, 3, 1, 7, 5, 9, 8, 6, 4, 2}, {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}};
Damm[num_Integer] := Module[{row},
row = 0;
Do[
row = matrix[[row + 1, d + 1]]
,
{d, IntegerDigits[num]}
];
row == 0
]
Damm /@ {5724, 5727, 112946}</syntaxhighlight>
{{out}}
<pre>{True, False, True}</pre>
 
=={{header|MATLAB}}==
{{trans|Julia}}
<syntaxhighlight lang="MATLAB}}">
clear all;close all;clc;
 
% Test the function with the provided numbers
numbers = [5724, 5727, 112946];
for i = 1:length(numbers)
if checkdigit(numbers(i))
fprintf('%d validates as: true\n', numbers(i));
else
fprintf('%d validates as: false\n', numbers(i));
end
end
 
function isValid = checkdigit(n)
matrix = [
0, 3, 1, 7, 5, 9, 8, 6, 4, 2;
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
];
 
row = 0;
nString = num2str(n);
for i = 1:length(nString)
d = str2double(nString(i));
row = matrix(row+1, d + 1);
end
isValid = (row == 0);
end
</syntaxhighlight>
{{out}}
<pre>
5724 validates as: true
5727 validates as: false
112946 validates as: true
</pre>
 
=={{header|Modula-2}}==
{{Output?}}
<syntaxhighlight lang="modula2">MODULE DammAlgorithm;
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
 
TYPE TA = ARRAY[0..9],[0..9] OF INTEGER;
CONST table = TA{
{0, 3, 1, 7, 5, 9, 8, 6, 4, 2},
{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}
};
 
PROCEDURE Damm(s : ARRAY OF CHAR) : BOOLEAN;
VAR interim,i : INTEGER;
BEGIN
interim := 0;
 
i := 0;
WHILE s[i] # 0C DO
interim := table[interim,INT(s[i])-INT('0')];
INC(i);
END;
RETURN interim=0;
END Damm;
 
PROCEDURE Print(number : INTEGER);
VAR
isValid : BOOLEAN;
buf : ARRAY[0..16] OF CHAR;
BEGIN
FormatString("%i", buf, number);
isValid := Damm(buf);
WriteString(buf);
IF isValid THEN
WriteString(" is valid");
ELSE
WriteString(" is invalid");
END;
WriteLn;
END Print;
 
BEGIN
Print(5724);
Print(5727);
Print(112946);
Print(112949);
 
ReadChar;
END DammAlgorithm.</syntaxhighlight>
 
=={{header|Modula-3}}==
<syntaxhighlight lang="modula3">MODULE DammAlgorithm EXPORTS Main;
 
IMPORT IO, Text;
 
VAR
Numbers:ARRAY[0..3] OF TEXT := ARRAY OF TEXT{"5724", "5727", "112946", "112949"};
PROCEDURE Damm(READONLY Str:TEXT):BOOLEAN =
TYPE
TTable = ARRAY[0..9],[0..9] OF INTEGER;
VAR
Table := TTable
{ARRAY OF INTEGER{0,3,1,7,5,9,8,6,4,2},
ARRAY OF INTEGER{7,0,9,2,1,5,4,8,6,3},
ARRAY OF INTEGER{4,2,0,6,8,7,1,3,5,9},
ARRAY OF INTEGER{1,7,5,0,9,8,3,4,2,6},
ARRAY OF INTEGER{6,1,2,3,0,4,5,9,7,8},
ARRAY OF INTEGER{3,6,7,4,2,0,9,5,8,1},
ARRAY OF INTEGER{5,8,6,9,7,2,0,1,3,4},
ARRAY OF INTEGER{8,9,4,5,3,6,2,0,1,7},
ARRAY OF INTEGER{9,4,3,8,6,1,7,2,0,5},
ARRAY OF INTEGER{2,5,8,1,4,3,6,7,9,0}};
Interim,I:INTEGER := 0;
BEGIN
WHILE I <= Text.Length(Str)-1 DO
Interim := Table[Interim, ORD(Text.GetChar(Str, I)) - ORD('0')];
INC(I);
END;
RETURN Interim = 0;
END Damm;
 
BEGIN
FOR I := FIRST(Numbers) TO LAST(Numbers) DO
IF Damm(Numbers[I]) THEN
IO.Put(Numbers[I] & " is valid\n");
ELSE
IO.Put(Numbers[I] & " is invalid\n");
END;
END;
END DammAlgorithm.</syntaxhighlight>
{{out}}
<pre>5724 is valid
5727 is invalid
112946 is valid
112949 is invalid</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">
from algorithm import reverse
 
const Table = [[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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]]
 
type Digit = range[0..9]
 
func isValid(digits: openArray[Digit]): bool =
## Apply Damm algorithm to check validity of a digit sequence.
var interim = 0
for d in digits:
interim = Table[interim][d]
result = interim == 0
 
proc toDigits(n: int): seq[Digit] =
## Return the digits of a number.
var n = n
while true:
result.add(n mod 10)
n = n div 10
if n == 0:
break
result.reverse()
 
proc checkData(digits: openArray[Digit]) =
## Check if a digit sequence if valid.
if isValid(digits):
echo "Sequence ", digits, " is valid."
else:
echo "Sequence ", digits, " is invalid."
 
checkData(5724.toDigits)
checkData(5727.toDigits)
checkData([Digit 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 6, 7, 8, 9, 0, 1])
checkData([Digit 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 6, 7, 8, 9, 0, 8])
</syntaxhighlight>
{{out}}
<pre>
Sequence [5, 7, 2, 4] is valid.
Sequence [5, 7, 2, 7] is invalid.
Sequence [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 6, 7, 8, 9, 0, 1] is valid.
Sequence [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 6, 7, 8, 9, 0, 8] is invalid.
</pre>
 
=={{header|Objeck}}==
{{trans|C#}}
<syntaxhighlight lang="objeck">class DammAlgorithm {
@table : static : Int[,];
 
function : Main(args : String[]) ~ Nil {
@table := [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2]
[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]];
 
numbers := [ 5724, 5727, 112946, 112949 ];
each (i : numbers) {
number := numbers[i];
isValid := Damm(number->ToString());
if (isValid) {
"{$number} is valid"->PrintLine();
}
else {
"{$number} is invalid"->PrintLine();
};
};
}
 
function : Damm(s : String) ~ Bool {
interim := 0;
each (i : s) {
interim := @table[interim, s->Get(i) - '0'];
};
return interim = 0;
}
}</syntaxhighlight>
 
{{out}}
<pre>
5724 is valid
5727 is invalid
112946 is valid
112949 is invalid
</pre>
 
=={{header|Pascal}}==
{{works with|Free Pascal}} {{trans|Modula-2}} nearly copy&paste
<syntaxhighlight lang="pascal">program DammAlgorithm;
uses
sysutils;
 
TYPE TA = ARRAY[0..9,0..9] OF UInt8;
CONST table : TA =
((0,3,1,7,5,9,8,6,4,2),
(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));
 
function Damm(s : string) : BOOLEAN;
VAR
interim,i : UInt8;
BEGIN
interim := 0;
i := 1;
WHILE i <= length(s) DO
Begin
interim := table[interim,ORD(s[i])-ORD('0')];
INC(i);
END;
Damm := interim=0;
END;
 
PROCEDURE Print(number : Uint32);
VAR
isValid : BOOLEAN;
buf :string;
BEGIN
buf := IntToStr(number);
isValid := Damm(buf);
Write(buf);
IF isValid THEN
Write(' is valid')
ELSE
Write(' is invalid');
WriteLn;
END;
 
BEGIN
Print(5724);
Print(5727);
Print(112946);
Print(112949);
Readln;
END.</syntaxhighlight>
{{out}}
<pre>
5724 is valid
5727 is invalid
112946 is valid
112949 is invalid
</pre>
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">sub damm {
my(@digits) = split '', @_[0];
my @tbl =([< 0 3 1 7 5 9 8 6 4 2 >],
[< 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 >]
);
my $row = 0;
for @digits ->my $col (@digits) { $row = @$tbl[$row][$col] }
not $row
}
 
for (5724, 5727, 112946) {
# Testing
print "$_:\tChecksum digit @{[damm($_) ? '' : 'in']}correct.\n"
for 5724, 5727, 112946 {
}</syntaxhighlight>
say "$_:\tChecksum digit { damm( $_.comb ) ?? '' !! 'in' }correct."
}</lang>
{{out}}
<pre>5724: Checksum digit correct.
Line 451 ⟶ 2,587:
112946: Checksum digit correct.</pre>
 
=={{header|PythonPhix}}==
As phix uses 1-based indexes, 1 must be added to the operation table,
<lang Python>
and validity is given by ending on one, rather than zero.
#!/usr/bin/env python2
<!--<syntaxhighlight lang="phix">(phixonline)-->
matrix = (
<span style="color: #008080;">constant</span> <span style="color: #000000;">tbl</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,{{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">},</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">}})</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">damm</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">interim</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nxt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">nxt</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">nxt</span><span style="color: #0000FF;">></span><span style="color: #000000;">10</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">interim</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tbl</span><span style="color: #0000FF;">[</span><span style="color: #000000;">interim</span><span style="color: #0000FF;">][</span><span style="color: #000000;">nxt</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">interim</span> <span style="color: #0000FF;">==</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"5724"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"5727"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"112946"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"112949"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%7s is %svalid\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">damm</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"in"</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
5724 is valid
5727 is invalid
112946 is valid
112949 is invalid
</pre>
 
=={{header|PHP}}==
<syntaxhighlight lang="php"><?php
function lookup($r,$c) {
$table = array(
array(0, 3, 1, 7, 5, 9, 8, 6, 4, 2),
array(7, 0, 9, 2, 1, 5, 4, 8, 6, 3),
array(4, 2, 0, 6, 8, 7, 1, 3, 5, 9),
array(1, 7, 5, 0, 9, 8, 3, 4, 2, 6),
array(6, 1, 2, 3, 0, 4, 5, 9, 7, 8),
array(3, 6, 7, 4, 2, 0, 9, 5, 8, 1),
array(5, 8, 6, 9, 7, 2, 0, 1, 3, 4),
array(8, 9, 4, 5, 3, 6, 2, 0, 1, 7),
array(9, 4, 3, 8, 6, 1, 7, 2, 0, 5),
array(2, 5, 8, 1, 4, 3, 6, 7, 9, 0),
);
return $table[$r][$c];
}
 
function isDammValid($input) {
return array_reduce(str_split($input), "lookup", 0) == 0;
}
 
foreach(array("5724", "5727", "112946", "112949") as $i) {
echo "{$i} is ".(isDammValid($i) ? "valid" : "invalid")."<br>";
}
?></syntaxhighlight>
{{out}}
<pre>
5724 is valid
5727 is invalid
112946 is valid
112949 is invalid
</pre>
 
=={{header|PicoLisp}}==
<syntaxhighlight lang="picolisp">(setq *D
(quote
(0 3 1 7 5 9 8 6 4 2)
(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) ) )
(de damm? (N)
(let R 1
(for N (mapcar format (chop N))
(setq R (inc (get *D R (inc N)))) )
(= 1 R) ) )
(println (damm? 5724))
(println (damm? 5727))
(println (damm? 112946))
(println (damm? 112940))</syntaxhighlight>
{{out}}
<pre>
T
NIL
T
NIL
</pre>
 
=={{header|PL/M}}==
<syntaxhighlight lang="plm">100H:
 
/* DAMM CHECKSUM FOR DECIMAL NUMBER IN GIVEN STRING */
CHECK$DAMM: PROCEDURE (PTR) BYTE;
DECLARE PTR ADDRESS, CH BASED PTR BYTE;
DECLARE DAMM DATA
( 0,3,1,7,5,9,8,6,4,2,
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 );
DECLARE I BYTE;
I = 0;
DO WHILE CH <> '$';
I = DAMM((I*10) + (CH-'0'));
PTR = PTR + 1;
END;
RETURN I = 0;
END CHECK$DAMM;
 
/* CP/M BDOS CALLS */
BDOS: PROCEDURE (FN, ARG);
DECLARE FN BYTE, ARG ADDRESS;
GO TO 5;
END BDOS;
 
PRINT: PROCEDURE (STR);
DECLARE STR ADDRESS;
CALL BDOS(9, STR);
END PRINT;
 
/* TESTS */
DECLARE TEST (4) ADDRESS;
TEST(0) = .'5724$';
TEST(1) = .'5727$';
TEST(2) = .'112946$';
TEST(3) = .'112949$';
 
DECLARE N BYTE;
DO N = 0 TO LAST(TEST);
CALL PRINT(TEST(N));
CALL PRINT(.': $');
IF CHECK$DAMM(TEST(N)) THEN
CALL PRINT(.'PASS$');
ELSE
CALL PRINT(.'FAIL$');
CALL PRINT(.(13,10,'$'));
END;
 
CALL BDOS(0,0);
EOF</syntaxhighlight>
{{out}}
<pre>5724: PASS
5727: FAIL
112946: PASS
112949: FAIL</pre>
 
=={{header|PowerShell}}==
{{trans|C#}}
<syntaxhighlight lang="powershell">
$table = (
(0, 3, 1, 7, 5, 9, 8, 6, 4, 2),
(7, 0, 9, 2, 1, 5, 4, 8, 6, 3),
Line 466 ⟶ 2,768:
(2, 5, 8, 1, 4, 3, 6, 7, 9, 0)
)
 
input = raw_input()
function Test-Damm([string]$s) {
def checkdigit(input):
$interim = 0
foreach ($c in $s.ToCharArray()) {
$interim = $table[$interim][[int]$c - [int][char]'0']
}
return $interim -eq 0
}
 
foreach ($number in 5724, 5727, 112946, 112949) {
$validity = if (Test-Damm $number) {'valid'} else {'invalid'}
'{0,6} is {1}' -f $number, $validity
}
</syntaxhighlight>
{{out}}
<pre>
5724 is valid
5727 is invalid
112946 is valid
112949 is invalid
</pre>
 
=={{header|Python}}==
<syntaxhighlight lang="python">def damm(num: int) -> bool:
row = 0
for eachdigitdigit in inputstr(num):
row = matrix_matrix[row][int(eachdigitdigit)]
return row == 0
 
output = checkdigit(input)
_matrix = (
print str(input)+str(output)
(0, 3, 1, 7, 5, 9, 8, 6, 4, 2),
</lang>
(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)
)
 
if __name__ == '__main__':
for test in [5724, 5727, 112946]:
print(f'{test}\t Validates as: {damm(test)}')</syntaxhighlight>
{{out}}
<pre>5724 Validates as: True
5727 Validates as: False
112946 Validates as: True</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ 0 swap witheach
[ char 0 - dip
[ table
[ 0 3 1 7 5 9 8 6 4 2 ]
[ 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 ] ]
peek ] ] is damm ( $ --> n )
 
[ damm 0 = ] is dammvalid ( $ --> b )
 
[ dup echo$ say " is "
dammvalid not if [ say "not " ]
say "valid." cr ] is validate ( & --> )
 
$ "5724 5725 112946 112949"
nest$ witheach validate</syntaxhighlight>
 
{{out}}
 
<pre>5724 is valid.
5725 is not valid.
112946 is valid.
112949 is not valid.</pre>
 
=={{header|R}}==
<syntaxhighlight lang="r">Damm_algo <- function(number){
row_i = 0
iterable = strsplit(toString(number), "")[[1]]
validation_matrix =
matrix(
c(
0, 3, 1, 7, 5, 9, 8, 6, 4, 2,
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),
nrow = 10, ncol = 10, byrow = T
)
for(digit in as.integer(iterable)){
row_i = validation_matrix[row_i + 1, digit + 1] #in R indexes start from 1 and not from zero
}
test <- ifelse(row_i == 0, "VALID", "NOT VALID")
message(paste("Number", number, "is", test))
}
 
for(number in c(5724, 5727, 112946, 112949)){
Damm_algo(number)
}</syntaxhighlight>
 
{{out}}
<pre>
Number 5724 is VALID
Number 5727 is NOT VALID
Number 112946 is VALID
Number 112949 is NOT VALID
</pre>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">#lang racket/base
(require racket/match)
 
Line 518 ⟶ 2,935:
(check-true (valid-number? 5724))
(check-false (valid-number? 5274))
(check-true (valid-number? 112946)))</langsyntaxhighlight>
 
No output from checks means that all tests passed.
 
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2017.05}}
 
<syntaxhighlight lang="raku" line>sub damm ( *@digits ) {
my @tbl = [0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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];
my $row = 0;
for @digits -> $col { $row = @tbl[$row][$col] }
not $row
}
 
# Testing
for 5724, 5727, 112946 {
say "$_:\tChecksum digit { damm( $_.comb ) ?? '' !! 'in' }correct."
}</syntaxhighlight>
{{out}}
<pre>5724: Checksum digit correct.
5727: Checksum digit incorrect.
112946: Checksum digit correct.</pre>
 
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Test '5724'>
<Test '5727'>
<Test '112946'>
<Test '112949'>;
};
 
Test {
e.Ds = <Prout e.Ds ': ' <Damm e.Ds>>;
};
 
Damm {
('0') = Pass;
(s.Int) = Fail;
(s.Int) s.D e.Ds,
<Item <Numb s.Int> <DammTable>>: (e.Row),
<Item <Numb s.D> e.Row>: s.Next
= <Damm (s.Next) e.Ds>;
e.Ds = <Damm ('0') e.Ds>;
};
 
DammTable {
= ('0317598642')
('7092154863')
('4206871359')
('1750983426')
('6123045978')
('3674209581')
('5869720134')
('8945362017')
('9438617205')
('2581436790')
};
 
Item {
0 t.I e.X = t.I;
s.N t.I e.X = <Item <- s.N 1> e.X>;
};</syntaxhighlight>
{{out}}
<pre>5724: Pass
5727: Fail
112946: Pass
112949: Fail</pre>
 
=={{header|REXX}}==
===manufactured table===
<syntaxhighlight lang="rexx">/* REXX */
<lang rexx>Call init
Call init
Call test 5724
Call test 5727
Line 565 ⟶ 3,057:
grid.i.col=word(list,col+2)
End
Return</langsyntaxhighlight>
{{out}}
<pre>5724 is ok
Line 572 ⟶ 3,064:
112940 is not ok, check-digit should be 6 (instead of 0)</pre>
 
=== static table ===
Using a static table is over four times faster than manufacturing it.
<lang rexx>/*REXX pgm uses H. Michael Damm's algorithm to validate numbers with suffixed check dig.*/
<syntaxhighlight lang="rexx">/*REXX pgm uses H. Michael Damm's algorithm to validate numbers with suffixed check sum. digit*/
@.0= 0317598642; @.1= 7092154863; @.2= 4206871359; @.3= 1750983426; @.4= 6123045978
@ a.50= 36742095810317598642; @a.61= 58697201347092154863; @a.72= 89453620174206871359; @a.83= 94386172051750983426; @a.94= 25814367906123045978
a.5= 3674209581; a.6= 5869720134; a.7= 8945362017; a.8= 9438617205; a.9= 2581436790
call Damm 5724 5727 112946 112940 /*invoke Damm's algorithme for some #'s*/
Call Damm 5724, 5727, 112946, 112940 /*invoke Damm's algorithm To some #'s.*/
exit /*stick a fork in it, we're all done. */
Exit /*stick a Tok in it, we're all Done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*---------------------------------------------------------------------------------*/
Damm: arg z; do j=1 for words(z); x=word(z, j); L=length(x)
Damm:
$=0; VCD= 'valid check digit'
Do j=1 To arg() do p=1 for L; g=$; /* $=substr(@.$,loop 1over +numbers substr(x, p, 1), 1) */
x=arg(j)
end /*p*/
d=0
if $==0 then say ' ' VCD right(x,1) " for " x
Do p=1 To length(x)-1 else say 'in'VCD/* compute right(x,1)the checksum digit " for " x ' (should be' g")"*/
d=substr(a.d,substr(x,p,1)+1,1)
end /*j*/
return< end /*p*/lang>
z=right(x,1) /* the given digit */
If z=d Then Say ' valid checksum digit ' z " for " x
Else Say ' invalid checksum digit ' z " for " x ' (should be' d")"
End /*j*/
Return /syntaxhighlight>
{{out|output|text=&nbsp; when using the (internal) default inputs:}}
<pre>
valid checkchecksum digit 4 for 5724
invalid checkchecksum digit 7 for 5727 (should be 4)
valid checkchecksum digit 6 for 112946
invalid checkchecksum digit 0 for 112940 (should be 6)
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring"># Project : Damm algorithm
<lang ring>
# Project : Damm algorithm
# Date : 2017/11/05
# Author : Gal Zsolt [~ CalmoSoft ~]
# Email : <calmosoft@gmail.com>
 
matrix = [[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
Line 626 ⟶ 3,119:
else
return " is invalid"
ok</syntaxhighlight>
</lang>
Output:
<pre>5724 is valid
5724 is valid
5727 is invalid
112946 is valid</pre>
 
=={{header|RPL}}==
{{trans|Python}}
'''Array version'''
≪ →STR
[[ 0 3 1 7 5 9 8 6 4 2 ]
[ 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 ]]
→ num table
≪ 0
1 num SIZE '''FOR''' d
1 + num d DUP SUB STR→ 1 +
2 →LIST table SWAP GET
'''NEXT'''
NOT
≫ ≫ '<span style="color:blue">DAMM?</span>' STO
'''String version'''
 
Program flow is quite the same, but storing the table needs only 210 nibbles of RAM, instead of 1625 with a 2-dimensional array.
≪ →STR "0317598642709215486342068713591750983426612304597836742095815869720134894536201794386172052581436790"
→ num table
≪ 0
1 num SIZE '''FOR''' d
10 * num d DUP SUB STR→ 1 + +
table SWAP DUP SUB STR→
'''NEXT'''
NOT
≫ ≫ '<span style="color:blue">DAMM?</span>' STO
 
≪ { 5724 5727 112946 } { }
1 3 PICK SIZE '''FOR''' j
OVER j GET '<span style="color:blue">DAMM?</span>' STO "True" "False" IFTE '''NEXT'''
≫ EVAL
{{out}}
<pre>
2: { 5724 5727 112946 }
1: { "True" "False" True" }
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">TABLE = [
<lang ruby>
[0,3,1,7,5,9,8,6,4,2], [7,0,9,2,1,5,4,8,6,3],
def dammCheck( nbr )
[4,2,0,6,8,7,1,3,5,9], [1,7,5,0,9,8,3,4,2,6],
idx = 0
[6,1,2,3,0,4,5,9,7,8], [3,6,7,4,2,0,9,5,8,1],
for i in 0 .. nbr.length - 1
[5,8,6,9,7,2,0,1,3,4], [8,9,4,5,3,6,2,0,1,7],
a = nbr[i].to_i
[9,4,3,8,6,1,7,2,0,5], [2,5,8,1,4,3,6,7,9,0]
if a == nil then return false end
]
idx = @table[idx][a]
end
print( "this number is " )
if idx == 0; print( "valid!" )
else print( "invalid!" )
end
puts
end
 
def damm_valid?(n) = n.digits.reverse.inject(0){|idx, a| TABLE[idx][a] } == 0
@table = Array.new(
[
[0,3,1,7,5,9,8,6,4,2], [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]
]
)
 
[5724, 5727, 112946].each{|n| puts "#{n}: #{damm_valid?(n) ? "" : "in"}valid"}
while true
</syntaxhighlight>
print( "Number to check: " )
{{out}}<pre>5724: valid
dammCheck( gets.chomp )
5727: invalid
end
112946: valid
</lang>
{{out}}<pre>
Number to check: 5724
this number is valid!
Number to check: 5727
this number is invalid!
Number to check: 112940
this number is invalid!
Number to check: 112946
this number is valid!
Number to check: 1321
this number is valid!
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn damm(number: &str) -> u8 {
static TABLE: [[u8; 10]; 10] = [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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],
];
 
number.chars().fold(0, |row, digit| {
let digit = digit.to_digit(10).unwrap();
TABLE[row as usize][digit as usize]
})
}
 
fn damm_validate(number: &str) -> bool {
damm(number) == 0
}
 
fn main() {
let numbers = &["5724", "5727", "112946"];
for number in numbers {
let is_valid = damm_validate(number);
if is_valid {
println!("{:>6} is valid", number);
} else {
println!("{:>6} is invalid", number);
}
}
}</syntaxhighlight>
{{out}}
<pre> 5724 is valid
5727 is invalid
112946 is valid</pre>
 
=={{header|Scala}}==
===Functional, (tail) recursive, concise and clean===
<syntaxhighlight lang="scala">import scala.annotation.tailrec
 
object DammAlgorithm extends App {
 
private val numbers = Seq(5724, 5727, 112946, 112949)
 
@tailrec
private def damm(s: String, interim: Int): String = {
def table =
Vector(
Vector(0, 3, 1, 7, 5, 9, 8, 6, 4, 2),
Vector(7, 0, 9, 2, 1, 5, 4, 8, 6, 3),
Vector(4, 2, 0, 6, 8, 7, 1, 3, 5, 9),
Vector(1, 7, 5, 0, 9, 8, 3, 4, 2, 6),
Vector(6, 1, 2, 3, 0, 4, 5, 9, 7, 8),
Vector(3, 6, 7, 4, 2, 0, 9, 5, 8, 1),
Vector(5, 8, 6, 9, 7, 2, 0, 1, 3, 4),
Vector(8, 9, 4, 5, 3, 6, 2, 0, 1, 7),
Vector(9, 4, 3, 8, 6, 1, 7, 2, 0, 5),
Vector(2, 5, 8, 1, 4, 3, 6, 7, 9, 0)
)
 
if (s.isEmpty) if (interim == 0) "✔" else "✘"
else damm(s.tail, table(interim)(s.head - '0'))
}
 
for (number <- numbers) println(f"$number%6d is ${damm(number.toString, 0)}.")
 
}</syntaxhighlight>
{{Out}}See it running in your browser by [https://scalafiddle.io/sf/d25pzoH/0 ScalaFiddle (JavaScript, non JVM)] or by [https://scastie.scala-lang.org/8t9RuipwRHGGoczFXPvT5A Scastie (remote JVM)].
 
=={{header|SETL}}==
<syntaxhighlight lang="setl">program damm_algorithm;
tests := [5724, 5727, 112946, 112949];
 
loop for test in tests do
print(str test + ': ' + if damm test then 'Pass' else 'Fail' end);
end loop;
 
op damm(n);
dt := [[0,3,1,7,5,9,8,6,4,2],
[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,3,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]];
 
i := 0;
loop for d in str n do
i := dt(i+1)(val d+1);
end loop;
return i=0;
end op;
end program;</syntaxhighlight>
{{out}}
<pre>5724: Pass
5727: Fail
112946: Pass
112949: Fail</pre>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang="ruby">func damm(digits) {
static tbl = [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
Line 694 ⟶ 3,310:
]
 
!digits.flip.reduce({|row,col| tbl[row][col] }, 0)
}
 
for n in [5724, 5727, 112946] {
say "#{n}:\tChecksum digit #{ damm(n.digits) ? '' : 'in'}correct."
}</langsyntaxhighlight>
{{out}}
<pre>5724: Checksum digit correct.
5727: Checksum digit incorrect.
112946: Checksum digit correct.</pre>
 
=={{header|Tcl}}==
{{trans|Perl}}
<syntaxhighlight lang="Tcl">proc damm {number} {
set digits [split $number ""]
set tbl {
{0 3 1 7 5 9 8 6 4 2}
{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}
}
 
set row 0
foreach col $digits {
set row [lindex $tbl $row $col]
}
return [expr {$row == 0 ? 1 : 0}]
}
 
foreach number {5724 5727 112946} {
set correct [damm $number]
puts "$number:\tChecksum digit [expr {$correct ? "" : "in"}]correct."
}</syntaxhighlight>
 
{{out}}
<pre>
Line 705 ⟶ 3,355:
5727: Checksum digit incorrect.
112946: Checksum digit correct.
</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">const table = [
[u8(0), 3, 1, 7, 5, 9, 8, 6, 4, 2],
[u8(7), 0, 9, 2, 1, 5, 4, 8, 6, 3],
[u8(4), 2, 0, 6, 8, 7, 1, 3, 5, 9],
[u8(1), 7, 5, 0, 9, 8, 3, 4, 2, 6],
[u8(6), 1, 2, 3, 0, 4, 5, 9, 7, 8],
[u8(3), 6, 7, 4, 2, 0, 9, 5, 8, 1],
[u8(5), 8, 6, 9, 7, 2, 0, 1, 3, 4],
[u8(8), 9, 4, 5, 3, 6, 2, 0, 1, 7],
[u8(9), 4, 3, 8, 6, 1, 7, 2, 0, 5],
[u8(2), 5, 8, 1, 4, 3, 6, 7, 9, 0],
]
fn damm(input string) bool {
mut interim := u8(0)
for c in input.bytes() {
interim = table[interim][c-'0'[0]]
}
return interim == 0
}
fn main() {
for s in ["5724", "5727", "112946", "112949"] {
println("${s:6} ${damm(s)}")
}
}</syntaxhighlight>
 
{{out}}
<pre>
5724 true
5727 false
112946 true
112949 false
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var table = [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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]
]
 
var damm = Fn.new { |input|
var interim = 0
for (c in input.bytes) interim = table[interim][c-48]
return interim == 0
}
 
for (s in ["5724", "5727", "112946", "112949"]) {
Fmt.print("$6s $s", s, damm.call(s))
}</syntaxhighlight>
 
{{out}}
<pre>
5724 true
5727 false
112946 true
112949 false
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">string 0; \use zero-terminated strings
 
func Damm(Input); \Return 'true' if checksum is correct
char Input;
int Interim, Table;
[Table:= [
[0, 3, 1, 7, 5, 9, 8, 6, 4, 2],
[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] ];
Interim:= 0;
while Input(0) do
[Interim:= Table(Interim, Input(0)-^0);
Input:= Input+1;
];
return Interim = 0;
];
 
int String, I;
[String:= ["5724", "5727", "112946", "112949"];
for I:= 0 to 4-1 do
[Text(0, String(I)); ChOut(0, 9\tab\);
Text(0, if Damm(String(I)) then "true" else "false");
CrLf(0);
];
]</syntaxhighlight>
{{out}}
<pre>
5724 true
5727 false
112946 true
112949 false
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn damm(digits){ // digits is something that supports an iterator of integers
var [const] tbl=Data(0,Int, // 10x10 byte bucket
0, 3, 1, 7, 5, 9, 8, 6, 4, 2,
Line 721 ⟶ 3,485:
2, 5, 8, 1, 4, 3, 6, 7, 9, 0);
0 == digits.reduce(fcn(interim,digit){ tbl[interim*10 + digit] },0)
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">damm(List(5,7,2,4)).println(); // True
damm(Data(0,Int,5,7,2,7).howza(0)).println(); // stream bytes, False
damm((112946).split()).println(); // True</langsyntaxhighlight>
{{out}}
<pre>True
True
False
True</pre>
</pre>
512

edits