OCR Numbers

1. Readme

OCR 号码

给定一个 3 x 4 ,由竖线符号,下划线和空格组成的网格,确定代表哪个数字,或者是否是乱码。

第一步

首先,将简单的二进制字体,转换为包含 0 或 1 的字符串。

二进制字体使用竖线符号和下划线,四行高,三列宽.

     _   #
    | |  # zero.
    |_|  #
         # 第 4 行总空着

转换为”0”

         #
      |  # one.
      |  #
         # (4行空)

转换为”1”

如果输入的大小正确,但无法识别,则程序应返回”?”

如果输入的大小不正确,程序应该返回错误。

第二步

更新您的程序以识别多二进制字符串,用 ? 替换乱码。

第三步

更新程序,以识别所有数字 0 到 9,既可以单独识别,也可以作为更大字符串的一部分识别。

 _
 _|
|_

转换为”2”

      _  _     _  _  _  _  _  _  #
    | _| _||_||_ |_   ||_||_|| | # 十进制数.
    ||_  _|  | _||_|  ||_| _||_| #
                                 # 第 4 行空着

被转换为”1234567890”

第四步

更新程序以处理多个数字,每 4 行。转换多行时,请使用逗号连接行.

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

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

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

被转换为”123,456,789”

资源

灵感来自银行 OCR katahttp://codingdojo.org/cgi-bin/wiki.pl?KataBankOCR

2. 开始你的表演

// The code below is a stub. Just enough to satisfy the compiler.
// In order to pass the tests you can add-to or change any of this code.

#[derive(Debug, PartialEq)]
pub enum Error {
   InvalidRowCount(usize),
   InvalidColumnCount(usize),
}

pub fn convert(input: &str) -> Result<String, Error> {
   unimplemented!("Convert the input '{}' to a string", input);
}

3. 测试代码查看


# #![allow(unused_variables)]
#fn main() {
#[test]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn input_with_lines_not_multiple_of_four_is_error() {
   let input = " _ \n".to_string() +
               "| |\n" +
               "   ";

   assert_eq!(Err(Error::InvalidRowCount(3)), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn input_with_columns_not_multiple_of_three_is_error() {
   let input = "    \n".to_string() +
               "   |\n" +
               "   |\n" +
               "    ";

   assert_eq!(Err(Error::InvalidColumnCount(4)), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn unrecognized_characters_return_question_mark() {
   let input = "   \n".to_string() +
               "  _\n" +
               "  |\n" +
               "   ";

   assert_eq!(Ok("?".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_0() {
   let input = " _ \n".to_string() +
               "| |\n" +
               "|_|\n" +
               "   ";

   assert_eq!(Ok("0".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_1() {
   let input = "   \n".to_string() +
               "  |\n" +
               "  |\n" +
               "   ";

   assert_eq!(Ok("1".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_2() {
   let input = " _ \n".to_string() +
               " _|\n" +
               "|_ \n" +
               "   ";

   assert_eq!(Ok("2".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_3() {
   let input = " _ \n".to_string() +
               " _|\n" +
               " _|\n" +
               "   ";

   assert_eq!(Ok("3".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_4() {
   let input = "   \n".to_string() +
               "|_|\n" +
               "  |\n" +
               "   ";

   assert_eq!(Ok("4".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_5() {
   let input = " _ \n".to_string() +
               "|_ \n" +
               " _|\n" +
               "   ";

   assert_eq!(Ok("5".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_6() {
   let input = " _ \n".to_string() +
               "|_ \n" +
               "|_|\n" +
               "   ";

   assert_eq!(Ok("6".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_7() {
   let input = " _ \n".to_string() +
               "  |\n" +
               "  |\n" +
               "   ";

   assert_eq!(Ok("7".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_8() {
   let input = " _ \n".to_string() +
               "|_|\n" +
               "|_|\n" +
               "   ";

   assert_eq!(Ok("8".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_9() {
   let input = " _ \n".to_string() +
               "|_|\n" +
               " _|\n" +
               "   ";

   assert_eq!(Ok("9".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_110101100() {
   let input = "       _     _        _  _ \n".to_string() +
               "  |  || |  || |  |  || || |\n" +
               "  |  ||_|  ||_|  |  ||_||_|\n" +
               "                           ";

   assert_eq!(Ok("110101100".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn replaces_only_garbled_numbers_with_question_mark() {
   let input = "       _     _           _ \n".to_string() +
               "  |  || |  || |     || || |\n" +
               "  |  | _|  ||_|  |  ||_||_|\n" +
               "                           ";

   assert_eq!(Ok("11?10?1?0".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn recognizes_string_of_decimal_numbers() {
   let input = "    _  _     _  _  _  _  _  _ \n".to_string() +
               "  | _| _||_||_ |_   ||_||_|| |\n" +
               "  ||_  _|  | _||_|  ||_| _||_|\n" +
               "                              ";

   assert_eq!(Ok("1234567890".to_string()), convert(&input));
}

#[test]
//#[ignore]
#[cfg_attr(rustfmt, rustfmt_skip)]
fn numbers_across_multiple_lines_are_joined_by_commas() {
   let input = "    _  _ \n".to_string() +
               "  | _| _|\n" +
               "  ||_  _|\n" +
               "         \n" +
               "    _  _ \n" +
               "|_||_ |_ \n" +
               "  | _||_|\n" +
               "         \n" +
               " _  _  _ \n" +
               "  ||_||_|\n" +
               "  ||_| _|\n" +
               "         ";
   assert_eq!(Ok("123,456,789".to_string()), convert(&input));
}

#}

4. 答案


# #![allow(unused_variables)]
#fn main() {
use std::collections::BTreeMap;

#[derive(Debug, PartialEq)]
pub enum Error {
   InvalidRowCount(usize),
   InvalidColumnCount(usize),
}

pub fn convert(input: &str) -> Result<String, Error> {
   let line_count = input.lines().count();
   if line_count % 4 != 0 {
       return Err(Error::InvalidRowCount(line_count));
   }
   for line in input.lines() {
       let char_count = line.chars().count();
       if char_count % 3 != 0 {
           return Err(Error::InvalidColumnCount(char_count));
       }
   }

   let y = input.lines().collect::<Vec<_>>();

   let mut converted_lines = vec![];

   for char_lines in y.chunks(4) {
       let mut unparsed_characters = BTreeMap::new();

       for line in char_lines {
           let line_chars = line.chars().collect::<Vec<_>>();

           for (char_number, char_chunk) in line_chars.chunks(3).enumerate() {
               let char_chars = unparsed_characters.entry(char_number).or_insert(vec![]);
               for c in char_chunk {
                   char_chars.push(*c);
               }
           }
       }

       let mut parsed_characters = String::new();

       for (_, v) in unparsed_characters {
           parsed_characters.push(convert_character(&v));
       }

       converted_lines.push(parsed_characters.to_string());
   }

   Ok(converted_lines.join(","))
}

fn convert_character(input: &Vec<char>) -> char {
   if &input[..] == [' ', '_', ' ', '|', ' ', '|', '|', '_', '|', ' ', ' ', ' '] {
       '0'
   } else if &input[..] == [' ', ' ', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', ' '] {
       '1'
   } else if &input[..] == [' ', '_', ' ', ' ', '_', '|', '|', '_', ' ', ' ', ' ', ' '] {
       '2'
   } else if &input[..] == [' ', '_', ' ', ' ', '_', '|', ' ', '_', '|', ' ', ' ', ' '] {
       '3'
   } else if &input[..] == [' ', ' ', ' ', '|', '_', '|', ' ', ' ', '|', ' ', ' ', ' '] {
       '4'
   } else if &input[..] == [' ', '_', ' ', '|', '_', ' ', ' ', '_', '|', ' ', ' ', ' '] {
       '5'
   } else if &input[..] == [' ', '_', ' ', '|', '_', ' ', '|', '_', '|', ' ', ' ', ' '] {
       '6'
   } else if &input[..] == [' ', '_', ' ', ' ', ' ', '|', ' ', ' ', '|', ' ', ' ', ' '] {
       '7'
   } else if &input[..] == [' ', '_', ' ', '|', '_', '|', '|', '_', '|', ' ', ' ', ' '] {
       '8'
   } else if &input[..] == [' ', '_', ' ', '|', '_', '|', ' ', '_', '|', ' ', ' ', ' '] {
       '9'
   } else {
       '?'
   }
}

#}



填充/相关