loading...

re: Daily Challenge #222 - Parse Bank Account Numbers VIEW POST

FULL DISCUSSION
 

F# solution. The problem was badly specified, so here some assumptions:

  1. Input comes as a string array, with each element representing one row, top to bottom.
  2. Unrecognized characters will show up as ? in the output.
  3. I decided not to strip the leading zero in the 023056789 example because that seems odd for a bank account number.
module DailyChallenge

[<Literal>]
let DigitRows = 3

[<Literal>]
let DigitCols = 3

let private isValidInput (input : string list) =
    input.Length % DigitRows = 0
    && List.forall (fun (row : string) -> row.Length % DigitCols = 0) input

let private range current max =
    let rStart = current * max
    (rStart, rStart + max - 1)

let private parseChar =
    function
    | [ " _ "; "| |"; "|_|" ] -> "0"
    | [ "   "; "  |"; "  |" ] -> "1"
    | [ " _ "; " _|"; "|_ " ] -> "2"
    | [ " _ "; " _|"; " _|" ] -> "3"
    | [ "   "; "|_|"; "  |" ] -> "4"
    | [ " _ "; "|_ "; " _|" ] -> "5"
    | [ " _ "; "|_ "; "|_|" ] -> "6"
    | [ " _ "; "  |"; "  |" ] -> "7"
    | [ " _ "; "|_|"; "|_|" ] -> "8"
    | [ " _ "; "|_|"; " _|" ] -> "9"
    | _ -> "?"

let private parseInput (input : string list) =
    seq {
        for row in 0 .. input.Length / DigitRows - 1 do
            let rStart, rEnd = range row DigitRows
            for col in 0 .. input.[0].Length / DigitCols - 1 do
                let cStart, cEnd = range col DigitCols
                yield input.[rStart..rEnd]
                      |> List.map (fun (row : string) -> row.[cStart..cEnd])
                      |> parseChar
    }
    |> System.String.Concat

let convert input =
    if isValidInput input then Some(parseInput input) else None

Tests:

module DailyChallengeTests

open FsUnit.Xunit
open Xunit
open DailyChallenge

[<Fact>]
let ``023056789``() =
    let rows =
        [ " _  _  _  _  _  _  _  _  _ "
          "| | _| _|| ||_ |_   ||_||_|"
          "|_||_  _||_| _||_|  ||_| _|" ]
    convert rows |> should equal (Some "023056789")

[<Fact>]
let ``823856989``() =
    let rows =
        [ " _  _  _  _  _  _  _  _  _ "
          "|_| _| _||_||_ |_ |_||_||_|"
          "|_||_  _||_| _||_| _||_| _|" ]
    convert rows |> should equal (Some "823856989")

[<Fact>]
let ``123456789``() =
    let rows =
        [ "    _  _     _  _  _  _  _ "
          "  | _| _||_||_ |_   ||_||_|"
          "  ||_  _|  | _||_|  ||_| _|" ]
    convert rows |> should equal (Some "123456789")

[<Fact>]
let ``invalid``() =
    let rows =
        [ "    _  _     _  _  _  _  _ " ]
    convert rows |> should equal None

[<Fact>]
let ``uncrecognized character``() =
    let rows =
        [ "    _  _     _  _  _  _  _ "
          "|   _| _||_||_ |_   ||_||_|"
          "|  |_  _|  | _||_|  ||_| _|" ]
    convert rows |> should equal (Some "?23456789")
Code of Conduct Report abuse