Bank OCR

Level: Intermediate 30–60 min

Concepts: AlgorithmsParsingValidationEdge Cases


You work at a bank that has just purchased a machine to read account numbers from paper documents. The machine scans the documents and produces a file of ASCII art digits.

Step 1: Parse Digits

Each account number is 9 digits long, written using pipes and underscores in a 3x3 grid:

    _  _     _  _  _  _  _
  | _| _||_||_ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _|

The above represents: 123456789

Each digit occupies exactly 3 columns and 3 rows:

 _     _  _     _  _  _  _  _
| |  | _| _||_||_ |_   ||_||_|
|_|  ||_  _|  | _||_|  ||_| _|

 0  1  2  3  4  5  6  7  8  9

Write a function that takes the 3-line string representation and returns the account number as a string (e.g. "123456789").

Step 2: Validate Checksum

Each account number has a checksum. Given account number d1 d2 d3 d4 d5 d6 d7 d8 d9:

checksum = (d1*9 + d2*8 + d3*7 + d4*6 + d5*5 + d6*4 + d7*3 + d8*2 + d9*1) mod 11 == 0

Example: 345882865(3*9 + 4*8 + 5*7 + 8*6 + 8*5 + 2*4 + 8*3 + 6*2 + 5*1) = 231231 mod 11 = 0 → valid

Report the status of each account:

  • Valid account: just the number (e.g. 345882865)
  • Invalid checksum: append ERR (e.g. 345882866 ERR)
  • Illegible digit: append ILL (e.g. 34588286? ILL)

Step 3: Error Correction

For accounts with a single illegible digit (?) or invalid checksum, try correcting by finding the closest valid account number. A “close” account number differs by a single pipe or underscore in the ASCII representation (one segment added or removed).

If exactly one valid alternative exists, use it. If multiple alternatives exist, report them all.

Test Cases

Input (ASCII)ParsedStatus
All zeros (9x " _ | ||_|")000000000Valid
All ones (9x " | |")111111111ERR
123456789 pattern123456789Valid
One garbled digit12345678?ILL

Hint

Start with parsing a single digit. Get all 10 digits working, then combine into a 9-digit parser. Checksums and error correction are separate concerns — build them as independent layers.