DEV Community

dev.to staff
dev.to staff

Posted on

Daily Challenge #222 - Parse Bank Account Numbers

You work for a bank, which has recently purchased an ingenious machine to assist in reading letters and faxes sent in by branch offices.

The machine scans the paper documents, and produces a string with a bank account that looks like this:

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

... why did we buy this machine?

Anyway, your task is to write a function that can take bank account string and parse it into actual account numbers.

Example

 _  _  _  _  _  _  _  _  _ 
| | _| _|| ||_ |_   ||_||_|     => 23056789
|_||_  _||_| _||_|  ||_| _|

Tests

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

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

Good luck!


This challenge comes from arhigod on CodeWars. Thank you to CodeWars, who has licensed redistribution of this challenge under the 2-Clause BSD License!

Want to propose a challenge idea for a future post? Email yo+challenge@dev.to with your suggestions!

Top comments (3)

Collapse
 
qm3ster profile image
Mihail Malo • Edited

Rust. Who needs error checking when you can support multiline instead?

use itertools::{izip, Itertools}; // 0.9.0
fn smol(big: &str) -> String {
    big.lines()
        .tuples()
        .flat_map(|(l1, l2, l3)| {
            izip!(l1.chars(), l2.chars(), l3.chars())
                .tuples()
                .map(|digit| match digit {
                    ((' ', ' ', ' '), (' ', ' ', ' '), (' ', '|', '|')) => '1',
                    ((' ', ' ', '|'), ('_', '_', '_'), (' ', '|', ' ')) => '2',
                    ((' ', ' ', ' '), ('_', '_', '_'), (' ', '|', '|')) => '3',
                    ((' ', '|', ' '), (' ', '_', ' '), (' ', '|', '|')) => '4',
                    ((' ', '|', ' '), ('_', '_', '_'), (' ', ' ', '|')) => '5',
                    ((' ', '|', '|'), ('_', '_', '_'), (' ', ' ', '|')) => '6',
                    ((' ', ' ', ' '), ('_', ' ', ' '), (' ', '|', '|')) => '7',
                    ((' ', '|', '|'), ('_', '_', '_'), (' ', '|', '|')) => '8',
                    ((' ', '|', ' '), ('_', '_', '_'), (' ', '|', '|')) => '9',
                    x => unreachable!(),
                })
        })
        .collect()
}

fn main() {
    println!(
        "{}",
        smol(
            r"    _  _     _  _  _  _  _ 
  | _| _||_||_ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _|
    _  _     _  _  _  _  _ 
  | _| _||_||_ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _|
    _  _     _  _  _  _  _ 
  | _| _||_||_ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _|"
        )
    );
}

Look at it go

Collapse
 
vidit1999 profile image
Vidit Sarkar • Edited

Python solution

# stores the modified string representation of a digit
digitStringDict = {
    " _ | ||_|" : "0",
    "     |  |" : "1",
    " _  _||_ " : "2",
    " _  _| _|" : "3",
    "   |_|  |" : "4",
    " _ |_  _|" : "5",
    " _ |_ |_|" : "6",
    " _   |  |" : "7",
    " _ |_||_|" : "8",
    " _ |_| _|" : "9"
}

# takes a multiline string as input
# outputs the int representation of that
def stringToAccountNumber(account: str) -> int:
    account = account.strip("\n")
    parts = account.split("\n") # split the actual string into three strings based on new-line character
    numberStr = "" # stores the string representation of the number

    for i in range(0,len(parts[0]),3):
        numberStr += digitStringDict[parts[0][i:i+3]+parts[1][i:i+3]+parts[2][i:i+3]]

    return int(numberStr)

Output,

test1 = '''
 _  _  _  _  _  _  _  _  _ 
|_| _| _||_||_ |_ |_||_||_|
|_||_  _||_| _||_| _||_| _|

'''

test2 = '''
    _  _     _  _  _  _  _ 
  | _| _||_||_ |_   ||_||_|
  ||_  _|  | _||_|  ||_| _|

'''

test3 = '''
 _  _  _  _  _  _  _  _  _ 
| | _| _|| ||_ |_   ||_||_|
|_||_  _||_| _||_|  ||_| _|

'''

print(stringToAccountNumber(test1)) # output -> 823856989
print(stringToAccountNumber(test2)) # output -> 123456789
print(stringToAccountNumber(test3)) # output -> 23056789
Collapse
 
peritract profile image
Dan Keefe • Edited

This is a rather hacky Python solution that relies on a dictionary of strings mapping to digits. I made the assumption that input would come as an array of strings, one for each level of the digits.

Code

digit_dict = {" _ | | _ ": 0, "     |  |": 1,
              " _  _||_ ": 2, " _  _| _|": 3,
              "   |_|  |": 4, " _ |_  _|": 5,
              " _ |_ |_|": 6, " _   |  |": 7,
              " _ |_||_|": 8, " _ |_| _|" : 9}

def parse_bank_code(str_list, digit_dict):
  """
  Function that takes awkward digit string and and digit dict;
  returns a normal string of digits.
  """

  digits = []  # Holder for digits

  # Loop through three places at a time
  for i in range(0, len(str_list[0]), 3):

    # Take three characters from each level as a list
    digit = [x[i:i+3] for x in str_list]

    # Join the characters together and get the dict value
    digit = digit_dict["".join(digit)]

    # Add the digit as a string to the list
    digits.append(str(digit))

  # Return the final code
  return "".join(digits)