using System; using System.Collections.Generic; using System.Linq; public static class OcrNumbers { private const int CharacterWidth = 3; private const int CharacterHeight = 4; public static string Convert(string input) { var lines = input.Split('\n'); if (lines.Length > CharacterHeight) lines = GetTransformedInput(lines); return Positions(lines).Aggregate("", (str, pos) => str + ConvertCharacter(lines, pos.Item1, pos.Item2)); } /// /// Transform multilines input into one line digits separate by comma /// /// /// private static string[] GetTransformedInput(string[] lines) { string[] transformedLines = new string[CharacterHeight]; for (int x = 0, characterRow = 0; x < lines.Length; x++, characterRow++) { if (characterRow > 3) characterRow = 0; for (int y = 0; y < lines[x].Length; y++) transformedLines[characterRow] += lines[x][y]; //for empty & last line add comma if (string.IsNullOrWhiteSpace(lines[x]) && lines.Length - 1 != x) { for (int i = 0; i < CharacterHeight; i++) transformedLines[i] += i == CharacterWidth - 1 ? " ," : " "; } } return transformedLines; } private static IEnumerable> Positions(string[] lines) { return from x in Enumerable.Range(0, Rows(lines)) from y in Enumerable.Range(0, Cols(lines)) select Tuple.Create(x, y); } private static int Cols(string[] lines) { return lines[0].Length % CharacterWidth == 0 ? lines[0].Length / CharacterWidth : throw new ArgumentException(); } private static int Rows(string[] lines) { return lines.Length % CharacterHeight == 0 ? lines.Length / CharacterHeight : throw new ArgumentException(); } private static bool IsEmptyLine(string line) { return string.IsNullOrWhiteSpace(line); } private static char ConvertCharacter(string[] input, int row, int col) => MatchCharacter(Character(input, row, col)); private static string Character(string[] input, int row, int col) { return Enumerable.Range(row, CharacterHeight) .Aggregate("", (str, offset) => str + input[row * CharacterHeight + offset].Substring(col * CharacterWidth, CharacterWidth)); } private static char MatchCharacter(string character) { return CharactersMap.ContainsKey(character) ? CharactersMap[character] : '?'; } private static readonly IReadOnlyDictionary CharactersMap = new Dictionary { { " _ " + "| |" + "|_|" + " ", '0' }, { " " + " |" + " |" + " ", '1' }, { " _ " + " _|" + "|_ " + " ", '2' }, { " _ " + " _|" + " _|" + " ", '3' }, { " " + "|_|" + " |" + " ", '4' }, { " _ " + "|_ " + " _|" + " ", '5' }, { " _ " + "|_ " + "|_|" + " ", '6' }, { " _ " + " |" + " |" + " ", '7' }, { " _ " + "|_|" + "|_|" + " ", '8' }, { " _ " + "|_|" + " _|" + " ", '9' }, { " " + " " + " ," + " ", ',' } }; }