Bank (Not Quite O.C.R.)

(Solved, coded, and written by Ryan Rice)

The problem was tortuously simulating an OCR (Optical Character Recognition) system on official banking documents.  It had sample input consisting of arrays of '|' and '_' characters like so:

The input always consists of a 9-digit number with a certain checksum to account for errors that goes by the equation (d1+2 * d2 + 3 * d3 + ... + 9 * d9) mod 11 = 0 with the '1' in this example representing d9 and counting down to d1 in a similar fashion.  Your assumptions are that:

Examples:

Input:
    _  _     _  _  _  _  _
  | _| _||_||_ |_   ||_||_|
  | _  _|  | _||_|  ||_| _|
Output:

123456789

Input:
    _  _  _  _  _  _     _
|_||_|| || ||_   |  |  ||_ 
  | _||_||_||_|  |  |  | _|
    
Output:

ambiguous

Input:
 _  _  _  _  _  _  _  _  _
|_||_||_||_||_||_||_||_||_|
|_||_||_||_||_||_||_||_||_|
Output:

failure

Input:
 _     _  _  _  _  _  _  _
|_|  ||_||_||_||_||_||_||_|
|_|  ||_||_||_||_||_||_||_|
Output:

878888888

Our Solution:

The code is in black text and the comments are in bright blue.

#include <iostream.h>
#include <fstream.h>

The readFile() reads the file into a dynamic matrix and then splits the numbers off of the matrix and then feeds them into the goDigital() routine for conversion.
void readFile(int numcol, int numrows, char file[20])
{
   int Nash=0; // FIXME
   ifstream Bring;
   int row=0, col=0;
   char dummy; //for all your stupid std library needs
   char Array[80];
   char Digits[3][3]; //to hold ascii numbers for passing
   int* M=NULL; //Array of translated integers
   char** Matrix=NULL; //allows for dynamic memory wrap around
   int numofaccounts;

   cout << "Matrix of ASCII characters as read in:" << endl;
   M = new int[9];
   Bring.open(file);

   Bring>>numofaccounts; //bring in the num of lines to be read
   numrows=(numofaccounts*3)-1;
   Bring.get(dummy); //kills the endline character before we read in more
   Matrix=new char*[numrows]; //Matrix to hold ascii's
   for (int t=0;t<=numrows;t++)
      Matrix[t]=new char[numcol];
   for (int i=0;i<=numrows;i++)
   {
      Bring.getline(Array,80,'\n');
      for(int j=0;j<numcol;j++)
      {
         Matrix[i][j]=Array[j];
         cout <<Matrix[i][j];
      }
      cout <<endl;
   }
   cout<<"rows "<<numrows<<"columns "<<numcol<<endl;

   cout <<"Digital conversion-->"<<endl;
   for (int y=0;y<=numrows;y++)
   {
      Nash=0;
      for(int q=0;q<numcol;q++)
      {
         row =0;
         col =0;
         Digits[row][col]=Matrix[y][q];
         Digits[row][++col]=Matrix[y][++q];
         Digits[row][++col]=Matrix[y][++q];
         col=col-2;
         q=q-2;
         Digits[++row][col]=Matrix[++y][q];
         Digits[row][++col]=Matrix[y][++q];
         Digits[row][++col]=Matrix[y][++q];
         q=q-2;
         col=col-2;
         Digits[++row][col]=Matrix[++y][q];
         Digits[row][++col]=Matrix[y][++q];
         Digits[row][++col]=Matrix[y][++q];
         M[Nash]= goDigital(Digits); //converts from ascii to int
         Nash++;

         y=y-2;
      }
      y=y+2;
      cout<<endl;
      M=confirm(M);
      cout<<M[0]<<M[1]<<M[2]<<M[3]<<M[4]<<M[5]<<M[6]<<M[7]<<M[8];
   }
}
The goDigital() subroutine changes the ASCII character matrix to an array of integers.
int goDigital(char Digits[3][3])
{
   if(Digits[0][1] == '_')
   {
      if(Digits[1][1] == ' ')
      {
         if(Digits[1][0] == ' ')
            return 7;
         else
            return 0;
      }
      if(Digits[2][0] == '|')
      {
         if(Digits[1][2] == '|')
            return 8;
         if(Digits[1][2] == ' ')
            return 6;
      }
      if(Digits[1][2] == ' ')
         return 5;
      if(Digits[1][0] == '|')
         return 9;
      if(Digits[2][2] == '|')
         return 3;
      else
         return 2;
   }
   else
   {
      if(Digits[1][0] == '|')
         return 4;
      else
         return 1;
   }
}
The confirm() function runs through the digits and computes the possible bank account numbers and labels them.
int* confirm(int* M)
{
   int count =0;
   int change;
   int number;
   int galbladder;
   galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] + 6*M[3] +
                 7*M[2] + 8*M[1] + 9*M[0]) % 11;
   if(galbladder == 0)
      return M;
   else
   {
      for(int k=0;k<9;k++)
      {
         if (M[k]==1)
         {
            M[k]=7;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder == 0)
            {
               count++;
               change=k;
               number=7;
            }
            M[k]=1;
         }
         if (M[k]==2)
         {
            M[k]=3;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder == 0)
            {
               count++;
               change=k;
               number=3;
            }
            M[k]=2;
         }
         if (M[k]==3)
         {
            M[k]=9;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder== 0)
            {
               count++;
               change=k;
               number=9;
            }
            M[k]=3;
         }
         if (M[k]==5)
         {
            M[k]=9;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder == 0)
            {
               count++;
               change=k;
               number=9;
            }
            M[k]=6;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder == 0)
            {
               count++;
               change=k;
               number=6;
            }
            M[k]=5;
         }
         if(M[k]==6)
         {
            M[k]=8;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder == 0)
            {
               count++;
               change=k;
               number=8;
            }
            M[k]=6;
         }
         if(M[k]==9)
         {
            M[k]=8;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder == 0)
            {
               count++;
               change=k;
               number=8;
            }
            M[k]=9;
         }
         if(M[k]==0)
         {
            M[k]=8;
            galbladder = (M[8] + 2*M[7] + 3*M[6] + 4*M[5] + 5*M[4] +
                          6*M[3] + 7*M[2] + 8*M[1] + 9*M[0]) % 11;
            if (galbladder == 0)
            {
               count++;
               change=k;
               number=8;
            }
            M[k]=0;
         }
      }//----------------end of for loop-----------------

      if(count==1)
         M[change] = number; //change the one number needed
      if( count > 1)
         cout << "AMBIGUOUS -";
      if (count ==0)
         cout << "Failure - ";
      return M;
   }
}
 
This is just main().
void main()
{
   char file[20];
   cout << "Welcome, tell me the file" << endl << "$";
   cin >> file;
   // in this case, we know that the incoming data will have 27 columns and
   // 7 rows so we can hardcode them in the function call...
   readFile(27, 7, file);
}