Damm algorithm: Difference between revisions

Add SETL
(Add MACRO-11)
(Add SETL)
(23 intermediate revisions by 12 users not shown)
Line 581:
 
=={{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>
<pre>
? 5724
PASS
? 5727
FAIL
? 112946
PASS
? 112949
FAIL
?
</pre>
 
==={{header|BASIC256}}===
<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
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
Line 599 ⟶ 730:
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}} ===
<pre>? 5724
{{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
Line 610 ⟶ 823:
? 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 dammDamm(ns) = valof
$( let dt = table
0,3,1,7,5,9,8,6,4,2,
Line 759 ⟶ 1,141:
 
=={{header|C++}}==
===Version 1===
{{trans|C#|C sharp}}
<syntaxhighlight lang="cpp">#include <sstreamstring>
 
#include <cstdio>
const int TABLE[][10] = {
 
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},
Line 775 ⟶ 1,160:
};
 
using[[nodiscard]] bool damm(std::string; s) noexcept {
bool damm(string s) {
int interim = 0;
for (charconst auto c : s) {
interim = TABLE[interim][c - '0'];
}
Line 785 ⟶ 1,169:
 
int main() {
for (const auto numbersnum =: { 5724, 5727, 112946, 112949 };) {
if (damm(std::to_string(num))) {
for (int num : numbers) {
std::printf("%6d is valid\n", num);
using std::stringstream;
}
stringstream ss;
else std::printf("%6d is invalid\n", num);
ss << num;
bool isValid = damm(ss.str());
if (isValid) {
printf("%6d is valid\n", num);
} else {
printf("%6d is invalid\n", num);
}
}
 
return 0;
}</syntaxhighlight>
{{out}}
Line 805 ⟶ 1,181:
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}}==
Line 1,098 ⟶ 1,522:
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#}}==
Line 1,238 ⟶ 1,704:
T 112946</pre>
 
=={{header|FreeBASICFōrmulæ}}==
<syntaxhighlight lang="freebasic">' version 04-07-2018
' compile with: fbc -s console
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Damm_algorithm}}
Function Damm(digit_str As String) As UInteger
 
'''Solution'''
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 } }
 
[[File:Fōrmulæ - Damm algorithm 01.png]]
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|Fōrmulæ}}==
 
'''Test cases'''
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
[[File:Fōrmulæ - Damm algorithm 02.png]]
Programs in Fōrmulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
[[File:Fōrmulæ - Damm algorithm 03.png]]
In '''[https://formulae.org/?example=Damm_algorithm this]''' page you can see the program(s) related to this task and their results.
 
=={{header|Go}}==
Line 1,620 ⟶ 2,035:
112946 is valid
112949 is invalid</pre>
 
=={{header|Liberty 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|Lua}}==
Line 1,875 ⟶ 2,245:
{{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}}==
Line 2,374 ⟶ 2,789:
112946 is valid
112949 is invalid
</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>
 
Line 2,597 ⟶ 2,968:
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}}==
Line 2,651 ⟶ 3,067:
=== static table ===
Using a static table is over four times faster than manufacturing it.
<syntaxhighlight lang="rexx">/*REXX pgm uses H. Michael Damm's algorithm to validate numbers with suffixed check sum. digit*/
@ a.0= 0317598642; @a.1= 7092154863; @a.2= 4206871359; @a.3= 1750983426; @a.4= 6123045978
@ a.5= 3674209581; @a.6= 5869720134; @a.7= 8945362017; @a.8= 9438617205; @a.9= 2581436790
callCall Damm 5724, 5727, 112946, 112940 112940 /*invoke Damm's algorithm forTo some #'s.*/
exit 0 Exit /*stick a forkTok in it, we're all doneDone. */
/*---------------------------------------------------------------------------------*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
Damm:
Damm: do j=1 for arg(); x= arg(j); $= 0; z= right(x, 1)
Do j=1 To arg() do p=1 for length(x); g=$; $= substr(@.$, 1 + substr(x, p,/* 1),loop over numbers 1) */
x=arg(j)
end /*p*/
d=0
if $==0 then say ' valid checksum digit ' z " for " x
Do p=1 To length(x)-1 else say ' invalid checksum digit ' z "/* forcompute "the checksum xdigit ' (should be' g")"*/
d=substr(a.d,substr(x,p,1)+1,1)
end /*j*/; return</syntaxhighlight>
end /*p*/
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>
Line 2,703 ⟶ 3,125:
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}}==
Line 2,795 ⟶ 3,262:
}</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}}==
Line 2,822 ⟶ 3,322:
112946: Checksum digit correct.</pre>
 
=={{header|uBasic/4tHTcl}}==
{{trans|Visual Basic .NETPerl}}
<syntaxhighlight lang="Tcl">proc damm {number} {
{{works with|v3.64}}
set digits [split $number ""]
<syntaxhighlight lang="text">Push 0, 3, 1, 7, 5, 9, 8, 6, 4, 2: i = FUNC(_Data(0))
set tbl {
Push 7, 0, 9, 2, 1, 5, 4, 8, 6, 3: i = FUNC(_Data(i))
Push 4, 2, 0, 6, 8, 7, 1, {0 3, 1 7 5, 9: i8 =6 FUNC(_Data(i))4 2}
Push 1, 7, 5, {7 0, 9, 8,2 3,1 5 4, 2,8 6: i = FUNC(_Data(i))3}
Push 6, 1, 2, 3, 0, {4, 5,2 9,0 7,6 8: i7 =1 FUNC(_Data(i))3 5 9}
Push 3, 6, 7, 4, 2, 0, 9, {1 7 5, 0 9 8, 1:3 i4 =2 FUNC(_Data(i))6}
Push 5, 8, 6, 9, 7, 2, 0, {6 1, 2 3, 0 4: i5 =9 FUNC(_Data(i))7 8}
Push 8, 9, 4, 5, {3, 6, 7 4 2, 0, 1,9 7:5 i8 = FUNC(_Data(i))1}
Push 9, 4, 3, {5 8, 6, 1,9 7, 2, 0, 5:1 i3 = FUNC(_Data(i))4}
Push 2, 5, {8, 1,9 4, 5 3, 6, 7, 9,2 0: i1 = FUNC(_Data(i))7}
{9 4 3 8 6 1 7 2 0 ' Read the table5}
Push 112949, 112946, 5727, 5724 {2 5 8 1 '4 Put3 numbers6 on7 the9 stack0}
}
 
set row 0
For i = 1 To Used() ' Read up to the number of stack items
foreach col $digits {
Print Using "______"; Tos();" is "; ' Print the header
set row [lindex $tbl $row $col]
If FUNC(_Damm (Str(Pop()))) Then Print "in";
}
Print "valid" ' invalid only if Damm() returns TRUE
return [expr {$row == 0 ? 1 : 0}]
Next ' Next stack item
}
 
foreach number {5724 5727 112946} {
End
set correct [damm $number]
puts "$number:\tChecksum digit [expr {$correct ? "" : "in"}]correct."
}</syntaxhighlight>
 
_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
5724: Checksum digit correct.
5727 is invalid
5727: Checksum digit incorrect.
112946 is valid
112946: Checksum digit correct.
112949 is invalid</pre>
</pre>
 
=={{header|V (Vlang)}}==
Line 2,986 ⟶ 3,398:
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "./fmt" for Fmt
 
var table = [
Line 3,008 ⟶ 3,420:
 
for (s in ["5724", "5727", "112946", "112949"]) {
SystemFmt.print("%(Fmt.$6s $s(6", s)), %(damm.call(s))")
}</syntaxhighlight>
 
2,094

edits