Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,2 @@
---
from: http://rosettacode.org/wiki/Damm_algorithm

View file

@ -0,0 +1,12 @@
The [[wp: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.
;Task:
Verify the checksum, stored as last digit of an input.
<!-- It's draft because I didn't specify it's requirements, see Wikipedia. -->
<br><br>

View file

@ -0,0 +1,21 @@
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))

View file

@ -0,0 +1,54 @@
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$'

View file

@ -0,0 +1,46 @@
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$'

View file

@ -0,0 +1,51 @@
BEGIN
# returns TRUE if the check digit of s is correct according to the Damm algorithm, #
# FALSE otherwise #
PROC has valid damm check digit = ( STRING s )BOOL:
BEGIN
# operation table - as per wikipedia example #
[,]INT operation table =
( [,]INT( ( 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 )
)
) [ AT 0, AT 0 ]
;
INT interim digit := 0;
FOR s pos FROM LWB s TO UPB s DO
INT next digit = ABS s[ s pos ] - ABS "0";
IF next digit < 0 OR next digit > 9 THEN
# invalid digit #
print( ( "Invalid damm digit: ", s[ s pos ], newline ) );
stop
ELSE
# have a valid digit #
interim digit := operation table[ interim digit, next digit ]
FI
OD;
interim digit = 0
END # has valid damm check digit # ;
# test the damm algorithm #
PROC test damm algorithm = ( STRING s, BOOL expected )VOID:
BEGIN
BOOL valid = has valid damm check digit( s );
print( ( "check digit of ", s, " is "
, IF valid THEN "valid" ELSE "invalid" FI
, IF valid = expected THEN "" ELSE " *** NOT AS EXPECTED" FI
, newline
)
)
END # test damm algorithm # ;
# test cases - as per other language samples #
test damm algorithm( "5724", TRUE );
test damm algorithm( "5727", FALSE );
test damm algorithm( "112946", TRUE )
END

View file

@ -0,0 +1,13 @@
damm{⎕IO0
tbl0 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,
}

View file

@ -0,0 +1,50 @@
.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"

View file

@ -0,0 +1,30 @@
# syntax: GAWK -f DAMM_ALGORITHM.AWK
BEGIN {
damm_init()
leng = split("5724,5727,112946",arr,",") # test cases
for (i=1; i<=leng; i++) {
n = arr[i]
printf("%s %s\n",damm_check(n),n)
}
exit(0)
}
function damm_check(n, a,i) {
a = 0
for (i=1; i<=length(n); i++) {
a = substr(damm[a],substr(n,i,1)+1,1)
}
return(a == 0 ? "T" : "F")
}
function damm_init() {
# 0123456789
damm[0] = "0317598642"
damm[1] = "7092154863"
damm[2] = "4206871359"
damm[3] = "1750983426"
damm[4] = "6123045978"
damm[5] = "3674209581"
damm[6] = "5869720134"
damm[7] = "8945362017"
damm[8] = "9438617205"
damm[9] = "2581436790"
}

View file

@ -0,0 +1,46 @@
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

View file

@ -0,0 +1,39 @@
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;

View file

@ -0,0 +1,41 @@
-- 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

View file

@ -0,0 +1 @@
{"5724 is valid", "57240 is valid", "572400 is valid", "87591 is invalid", "100 is invalid", "3922446 is valid"}

View file

@ -0,0 +1,37 @@
; 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

View file

@ -0,0 +1,16 @@
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])
}

View file

@ -0,0 +1,4 @@
result := ""
for i, num in [5724, 5727, 112946, 112949]
result .= num "`tis " (Damm(num) ? "valid" : "not valid") "`n"
MsgBox % result

View file

@ -0,0 +1,17 @@
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

View file

@ -0,0 +1,31 @@
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")
$)

View file

@ -0,0 +1,17 @@
table > 0317598642
7092154863
4206871359
1750983426
6123045978
3674209581
5869720134
8945362017
9438617205
2581436790
Digits 10{𝕗|÷𝕗(1+·𝕗1)}
Damm {0=0(table˜)˜´Digits 𝕩}
Damm¨57245727112946

View file

@ -0,0 +1 @@
1 0 1

View file

@ -0,0 +1,33 @@
#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);
}
}

View file

@ -0,0 +1,37 @@
// 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;
}

View file

@ -0,0 +1,39 @@
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);
}
}
}
}
}

View file

@ -0,0 +1,30 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
bool damm(unsigned char *input, size_t length) {
static const unsigned char 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},
};
unsigned char interim = 0;
for (size_t i = 0; i < length; i++) {
interim = table[interim][input[i]];
}
return interim == 0;
}
int main() {
unsigned char input[4] = {5, 7, 2, 4};
puts(damm(input, 4) ? "Checksum correct" : "Checksum incorrect");
return 0;
}

View file

@ -0,0 +1,43 @@
% 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

View file

@ -0,0 +1,14 @@
(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]
[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]])
(defn damm? [digits]
(= 0 (reduce #(nth (nth tbl %1) %2) 0
(map #(Character/getNumericValue %) (seq digits)))))

View file

@ -0,0 +1,40 @@
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");

View file

@ -0,0 +1,36 @@
import std.stdio;
auto 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(string s) {
int interim = 0;
foreach (c; s) {
interim = table[interim][c - '0'];
}
return interim == 0;
}
void main() {
import std.conv : to;
auto numbers = [5724, 5727, 112946, 112949];
foreach (number; numbers) {
bool isValid = damm(number.to!string());
writef("%6d is ", number);
if (isValid) {
writeln("valid");
} else {
writeln("invalid");
}
}
}

View file

@ -0,0 +1,36 @@
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

View file

@ -0,0 +1,30 @@
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")
}
}

View file

@ -0,0 +1,32 @@
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

View file

@ -0,0 +1,21 @@
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

View file

@ -0,0 +1,17 @@
: 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
;

View file

@ -0,0 +1,32 @@
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.
INTEGER*1 OPTABLE(0:9,0:9) !The special "Operation table" of the method.
PARAMETER (OPTABLE = (/ !A set of constants...
o 0, 3, 1, 7, 5, 9, 8, 6, 4, 2, ! CAREFUL!
1 7, 0, 9, 2, 1, 5, 4, 8, 6, 3, !Fortran stores arrays in column-major order.
2 4, 2, 0, 6, 8, 7, 1, 3, 5, 9, !Despite the manifest row and column layout apparent here
3 1, 7, 5, 0, 9, 8, 3, 4, 2, 6, !This sequence of consecutive items will go into storage order.
4 6, 1, 2, 3, 0, 4, 5, 9, 7, 8, !The table resulting from this sequence of constants
5 3, 6, 7, 4, 2, 0, 9, 5, 8, 1, !Will appear to be transposed if referenced as (row,column)
6 5, 8, 6, 9, 7, 2, 0, 1, 3, 4, !What appears to be row=6 column=1 (counting from zero)
7 8, 9, 4, 5, 3, 6, 2, 0, 1, 7, !is to be accessed as OPTABLE(1,6) = 8, not OPTABLE(6,1)
8 9, 4, 3, 8, 6, 1, 7, 2, 0, 5, !Storage order is (0,0), (1,0), (2,0), ... (9,0)
9 2, 5, 8, 1, 4, 3, 6, 7, 9, 0/)) !Followed by (0,1), (1,1), (2,1), ... (9,1)
INTEGER I,D,ID !Assistants.
ID = 0 !Here we go.
DO I = 1,LEN(DIGIT) !Step through the text.
D = ICHAR(DIGIT(I:I)) - ICHAR("0") !Convert to an integer. (ASCII or EBCDIC)
IF (D.LT.0 .OR. D.GT.9) STOP "DAMM! Not a digit!" !This shouldn't happen!
ID = OPTABLE(D,ID) !Transposed: D is the column index and ID the row.
END DO !On to the next.
DAMM = ID .EQ. 0 !Somewhere, a check digit should ensure this.
END FUNCTION DAMM !Simple, fast, and alas, rarely used.
LOGICAL DAMM !Not a default type.
WRITE (6,*) DAMM("5724"),"5724"
WRITE (6,*) DAMM("5727"),"5727"
WRITE (6,*) DAMM("112946"),"112946"
END

View file

@ -0,0 +1,51 @@
' 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

View file

@ -0,0 +1,30 @@
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))
}
}

View file

@ -0,0 +1,32 @@
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)
}
}
}
}

View file

@ -0,0 +1,21 @@
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]

View file

@ -0,0 +1,23 @@
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
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
)
getdigits=: 10&#.inv
getDamm=: verb define
row=. 0
for_digit. getdigits y do.
row=. OpTbl {~ <row,digit
end.
)
checkDamm=: 0 = getDamm

View file

@ -0,0 +1,2 @@
checkDamm&> 5724 5727 112946
1 0 1

View file

@ -0,0 +1,12 @@
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

View file

@ -0,0 +1,2 @@
checkdamm 5724 5727 112946
1 0 1

View file

@ -0,0 +1,32 @@
public 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'];
return interim == 0;
}
public 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);
}
}
}
}

View file

@ -0,0 +1,21 @@
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],
];
const lookup = (p, c) => table[p][parseInt(c, 10)]
const damm = input => [...input].reduce(lookup, 0) === 0;
// ----------------------------------------------------------[ Tests ]----
const test = () => ["5724", "5727", "112946", "112949"].forEach(e =>
console.log(`${e} => ${damm(e) ? 'Pass' : 'Fail'}`)
);
test();

View file

@ -0,0 +1,20 @@
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]

View file

@ -0,0 +1,4 @@
[5724,true]
[5727,false]
[112946,true]
[112949,false]

View file

@ -0,0 +1,20 @@
function 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
for d in string(n)
row = matrix[row + 1][d - '0' + 1]
end
return row
end
foreach(i -> println("$i validates as: ", checkdigit(string(i)) == 0), [5724, 5727, 112946])

View file

@ -0,0 +1,28 @@
// version 1.1.2
val table = arrayOf(
intArrayOf(0, 3, 1, 7, 5, 9, 8, 6, 4, 2),
intArrayOf(7, 0, 9, 2, 1, 5, 4, 8, 6, 3),
intArrayOf(4, 2, 0, 6, 8, 7, 1, 3, 5, 9),
intArrayOf(1, 7, 5, 0, 9, 8, 3, 4, 2, 6),
intArrayOf(6, 1, 2, 3, 0, 4, 5, 9, 7, 8),
intArrayOf(3, 6, 7, 4, 2, 0, 9, 5, 8, 1),
intArrayOf(5, 8, 6, 9, 7, 2, 0, 1, 3, 4),
intArrayOf(8, 9, 4, 5, 3, 6, 2, 0, 1, 7),
intArrayOf(9, 4, 3, 8, 6, 1, 7, 2, 0, 5),
intArrayOf(2, 5, 8, 1, 4, 3, 6, 7, 9, 0)
)
fun damm(s: String): Boolean {
var interim = 0
for (c in s) interim = table[interim][c - '0']
return interim == 0
}
fun main(args: Array<String>) {
val numbers = intArrayOf(5724, 5727, 112946, 112949)
for (number in numbers) {
val isValid = damm(number.toString())
println("${"%6d".format(number)} is ${if (isValid) "valid" else "invalid"}")
}
}

View file

@ -0,0 +1,34 @@
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

View file

@ -0,0 +1,24 @@
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},
{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 check( n )
local idx, a = 0, tonumber( n:sub( 1, 1 ) )
for i = 1, #n do
a = tonumber( n:sub( i, i ) )
if a == nil then return false end
idx = tab[idx + 1][a + 1]
end
return idx == 0
end
local n, r
while( true ) do
io.write( "Enter the number to check: " )
n = io.read(); if n == "0" then break end
r = check( n ); io.write( n, " is " )
if not r then io.write( "in" ) end
io.write( "valid!\n" )
end

View file

@ -0,0 +1,41 @@
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

View file

@ -0,0 +1,48 @@
.TITLE DAMMAL
.MCALL .GTLIN,.PRINT,.EXIT
DAMMAL::JMP DEMO
; VALIDATE DAMM STRING IN R0; ZERO FLAG SET IF VALID
DAMM: CLR R2 ; INTERIM DIGIT
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
MOV #5$,R0
TSTB (R0) ; EMPTY LINE?
BNE 1$
.EXIT ; IF SO, STOP
1$: JSR PC,DAMM ; TEST LINE
BNE 2$ ; FAIL?
.PRINT #3$
BR DEMO
2$: .PRINT #4$ ; PASS?
BR DEMO
3$: .ASCIZ /PASS/
4$: .ASCIZ /FAIL/
5$: .BLKB 200
.END DAMMAL

View file

@ -0,0 +1,38 @@
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

View file

@ -0,0 +1,16 @@
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}

View file

@ -0,0 +1,55 @@
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.

View file

@ -0,0 +1,40 @@
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.

View file

@ -0,0 +1,43 @@
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])

View file

@ -0,0 +1,37 @@
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;
}
}

View file

@ -0,0 +1,25 @@
<?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>";
}
?>

View file

@ -0,0 +1,56 @@
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

View file

@ -0,0 +1,53 @@
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.

View file

@ -0,0 +1,21 @@
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 my $col (@digits) { $row = $tbl[$row][$col] }
not $row
}
for (5724, 5727, 112946) {
print "$_:\tChecksum digit @{[damm($_) ? '' : 'in']}correct.\n"
}

View file

@ -0,0 +1,28 @@
(phixonline)-->
<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>
<!--

View file

@ -0,0 +1,21 @@
(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))

View file

@ -0,0 +1,25 @@
$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 Test-Damm([string]$s) {
$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
}

View file

@ -0,0 +1,31 @@
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

View file

@ -0,0 +1,22 @@
def damm(num: int) -> bool:
row = 0
for digit in str(num):
row = _matrix[row][int(digit)]
return row == 0
_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)
)
if __name__ == '__main__':
for test in [5724, 5727, 112946]:
print(f'{test}\t Validates as: {damm(test)}')

View file

@ -0,0 +1,23 @@
[ 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

View file

@ -0,0 +1,32 @@
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)
}

View file

@ -0,0 +1,43 @@
/* REXX */
Call init
Call test 5724
Call test 5727
Call test 112946
Call test 112940
Exit
test:
Parse Arg number
int_digit=0
Do p=1 To length(number)
d=substr(number,p,1)
int_digit=grid.int_digit.d
If p<length(number) Then cd=int_digit
End
If int_digit=0 Then
Say number 'is ok'
Else
Say number 'is not ok, check-digit should be' cd '(instead of' d')'
Return
init:
i=-2
Call setup '* 0 1 2 3 4 5 6 7 8 9'
Call setup '0 0 3 1 7 5 9 8 6 4 2'
Call setup '1 7 0 9 2 1 5 4 8 6 3'
Call setup '2 4 2 0 6 8 7 1 3 5 9'
Call setup '3 1 7 5 0 9 8 3 4 2 6'
Call setup '4 6 1 2 3 0 4 5 9 7 8'
Call setup '5 3 6 7 4 2 0 9 5 8 1'
Call setup '6 5 8 6 9 7 2 0 1 3 4'
Call setup '7 8 9 4 5 3 6 2 0 1 7'
Call setup '8 9 4 3 8 6 1 7 2 0 5'
Call setup '9 2 5 8 1 4 3 6 7 9 0'
Return
setup:
Parse Arg list
i=i+1
Do col=-1 To 9
grid.i.col=word(list,col+2)
End
Return

View file

@ -0,0 +1,12 @@
/*REXX pgm uses H. Michael Damm's algorithm to validate numbers with suffixed check sum.*/
@.0= 0317598642; @.1= 7092154863; @.2= 4206871359; @.3= 1750983426; @.4= 6123045978
@.5= 3674209581; @.6= 5869720134; @.7= 8945362017; @.8= 9438617205; @.9= 2581436790
call Damm 5724, 5727, 112946, 112940 /*invoke Damm's algorithm for some #'s.*/
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
Damm: do j=1 for arg(); x= arg(j); $= 0; z= right(x, 1)
do p=1 for length(x); g=$; $= substr(@.$, 1 + substr(x, p, 1), 1)
end /*p*/
if $==0 then say ' valid checksum digit ' z " for " x
else say ' invalid checksum digit ' z " for " x ' (should be' g")"
end /*j*/; return

View file

@ -0,0 +1,42 @@
#lang racket/base
(require racket/match)
(define 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)))
(define (integer->digit-list n)
(let loop ((n n) (a null))
(if (zero? n) a (let-values (([q r] (quotient/remainder n 10))) (loop q (cons r a))))))
(define/match (check-digit n)
[((list ds ...))
(foldl
(λ (d interim)
(vector-ref (vector-ref operation-table interim) d))
0 ds)]
[((? integer? i))
(check-digit (integer->digit-list i))])
(define/match (valid-number? n)
[((? integer? i))
(valid-number? (integer->digit-list i))]
[((list ds ...))
(zero? (check-digit ds))])
(module+ test
(require rackunit)
(check-equal? (integer->digit-list 572) '(5 7 2))
(check-equal? (check-digit 572) 4)
(check-equal? (check-digit '(5 7 2)) 4)
(check-true (valid-number? 5724))
(check-false (valid-number? 5274))
(check-true (valid-number? 112946)))

View file

@ -0,0 +1,20 @@
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."
}

View file

@ -0,0 +1,27 @@
# Project : Damm algorithm
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]]
see "5724" + encode(5724 ) + nl
see "5727" + encode(5727 ) + nl
see "112946" + encode(112946) + nl
func encode(n)
check = 0
for d in string(n)
check = matrix[check+1][d-'0'+1]
next
if check = 0
return " is valid"
else
return " is invalid"
ok

View file

@ -0,0 +1,11 @@
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]
]
def damm_valid?(n) = n.digits.reverse.inject(0){|idx, a| TABLE[idx][a] } == 0
[5724, 5727, 112946].each{|n| puts "#{n}: #{damm_valid?(n) ? "" : "in"}valid"}

View file

@ -0,0 +1,35 @@
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);
}
}
}

View file

@ -0,0 +1,29 @@
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)}.")
}

View file

@ -0,0 +1,20 @@
func damm(digits) {
static 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],
]
!digits.flip.reduce({|row,col| tbl[row][col] }, 0)
}
for n in [5724, 5727, 112946] {
say "#{n}:\tChecksum digit #{ damm(n.digits) ? '' : 'in'}correct."
}

View file

@ -0,0 +1,26 @@
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)}")
}
}

View file

@ -0,0 +1,36 @@
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

View file

@ -0,0 +1,24 @@
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"]) {
System.print("%(Fmt.s(6, s)) %(damm.call(s))")
}

View file

@ -0,0 +1,32 @@
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);
];
]

View file

@ -0,0 +1,14 @@
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,
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);
0 == digits.reduce(fcn(interim,digit){ tbl[interim*10 + digit] },0)
}

View file

@ -0,0 +1,3 @@
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