RosettaCodeData/Task/SEDOLs/Modula-3/sedols.mod3

45 lines
1.2 KiB
Plaintext

MODULE SEDOL EXPORTS Main;
IMPORT IO, Fmt, Text, Stdio;
EXCEPTION BadSedol(TEXT);
VAR test := ARRAY [1..10] OF TEXT {"710889", "B0YBKJ", "406566", "B0YBLH",
"228276", "B0YBKL", "557910", "B0YBKR",
"585284", "B0YBKT" };
PROCEDURE Check(sed: TEXT): INTEGER RAISES {BadSedol}=
VAR
weights := ARRAY [0..5] OF INTEGER {1, 3, 1, 7, 3, 9};
result, d: INTEGER;
char: CHAR;
BEGIN
IF Text.Length(sed) # 6 THEN
RAISE BadSedol("ERROR: Must be 6 digits.");
END;
result := 0;
FOR i := 0 TO 5 DO
char := Text.GetChar(sed, i);
CASE char OF
| '0'..'9' => d := ORD(char) - ORD('0');
| 'B'..'D', 'F'..'H', 'J'..'N', 'P'..'T', 'V'..'Z'
=> d := ORD(char) - ORD('A') + 10;
ELSE
RAISE BadSedol("ERROR: Must be numbers or (non-vowel) letters.");
END;
INC(result, d * weights[i]);
END;
result := (10 - (result MOD 10)) MOD 10;
RETURN result;
END Check;
BEGIN
TRY
FOR i := FIRST(test) TO LAST(test) DO
IO.Put(test[i] & Fmt.Char(VAL(ORD('0') + Check(test[i]), CHAR)) & "\n");
END;
EXCEPT
| BadSedol(text) => IO.Put(text & "\n", Stdio.stderr);
END;
END SEDOL.