Reputation: 21
I have a little problem. I have written a program which asks for user for a code which contains 11 digits. I defined it as string but now I would like to use every digit from this code individually and make an equation.
for example if code is 37605030299
i need to do equation:
(1*3 + 2*7 + 3*6 + 4*0 + 5*5 + 6*0 + 7*3 + 8*0 + 9*2 + 1*9) / 11
and find out what's the MOD.
This is a calculation for an ISBN check digit.
Upvotes: 1
Views: 771
Reputation: 1558
char
values for the decimal digits 0
through 9
exist, are consecutive and in ascending order with respect to their numeric value.
Thus you can use char
values as input and evaluate expressions such as ord('4') – ord('0')
to obtain the integer
value 4
.
program checkDigit(input, output);
type
{ This is guaranteed to comprise exactly 10 `char` values. }
decimalDigit = '0'‥'9';
{ Valid index of a component in ISBN10identifier string. }
ISBN10identifierIndex = 1‥9;
{ Legacy 10‑digit ISBN without check digit. }
ISBN10identifier = array[ISBN10identifierIndex] of decimalDigit;
var
digit: ISBN10identifier;
checkDigitValue: 0‥10;
begin
{ This will crash if you do not enter 9 decimal digit characters. }
readLn(digit[ 1], digit[ 2], digit[ 3], digit[ 4], digit[ 5],
digit[ 6], digit[ 7], digit[ 8], digit[ 9]);
{ Obviously this “formula” may benefit from using a `for` loop. }
checkDigitValue ≔ (ord(digit[1]) * 1 + ord(digit[2]) * 2 +
ord(digit[3]) * 3 + ord(digit[4]) * 4 +
ord(digit[5]) * 5 + ord(digit[6]) * 6 +
ord(digit[7]) * 7 + ord(digit[8]) * 8 +
ord(digit[9]) * 9 − 45 * ord('0')) mod 11;
{ Select alternative character for `checkDigitValue` equaling ten. }
writeLn(('0123456789X')[checkDigitValue + 1])
end.
maxInt
≥ 999,999,999, you may want to use integer
.
Write expressions such as n div 10000 mod 10
to isolate individual digit values.
program checkDigit(input, output);
var
{ To ensure your algorithm isn’t totally wrong use sub‑ranges. }
ID: 0‥999999999;
{ The initial `value` construct is defined by Extended Pascal. }
weightedSum: 0‥729 value 0;
{ Exponent in 10⁰ = 1, 10¹ = 10, 10² = 100, …, 10⁸ = 100,000,000. }
i: 0‥8;
begin
{ NB: This accepts any valid Pascal `integer` literal (also +42). }
readLn(ID);
{ Accumulate `weightedSum`. }
for i ≔ 0 to 8 do
begin
{ The `pow` operator is defined by Extended Pascal. }
weightedSum ≔ weightedSum + ID div (10 pow i) mod 10 * (9 − i)
end;
{ Print the entire ISBN including the check digit (`X` for ten). }
writeLn(ID:9, ('0123456789X')[weightedSum mod 11 + 1])
end.
Upvotes: 0
Reputation: 125651
Use a loop instead. (I'm only showing the total value and check digit calculation - you need to get the user input first into a variable named UserISBN
yourself.)
function AddCheckDigit(const UserISBN: string): string;
var
i, Sum: Integer;
CheckDigit: Integer;
LastCharValue: string;
begin
Assert(Length(UserISBN) = 10, 'Invalid ISBN number.');
Sum := 0;
for i := 1 to 10 do
Sum := Sum + (Ord(UserISBN[i]) * i);
{ Calculate the check digit }
CheckDigit := 11 - (Sum mod 11);
{ Determine check digit character value }
if CheckDigit = 10 then
LastCharValue := 'X'
else
LastCharValue := IntToStr(CheckDigit);
{ Add to string for full ISBN Number }
Result := UserISBN + LastCharValue;
end;
Upvotes: 2