fred
fred

Reputation: 21

How to use Pascal string in equation

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

Answers (2)

Kai Burghardt
Kai Burghardt

Reputation: 1558

  • In Pascal it is guaranteed that the 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.
    
  • If your implementation supports a 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

Ken White
Ken White

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

Related Questions