Daily Archives: July 25, 2012

Coding challenge: Reading an LCD display

If you read my previous post “Coding challenge: Creating an LCD display” then you will remember I was set a challenge by a friend of mine to create a function that would take an integer and produce a LCD display inside of a console window.

Well I got a follow up challenge from him this week which went like this.

This week’s kata is simply the inverse of last week’s … instead of taking a number and producing a “LCD display”, the task this week is to accept an LCD display and produce a number.  Numbers will always be 3 lines high and 3 characters wide: The easy version: accept a single digit in a single and return the numeric value. The harder version: accept a multi-digit display and return the numeric value.

So with the challenge set it was time to attack the problem.  Again the real difficulty that presents itself in this challenge is the fact that the data must be read line by line.  Therefore you must track the pattern of each digit as you move down through the data and only once you have that data can you start to make some decisions.  First however I still set myself some base rules for this challenge. I have listed them below.

  • All numbers through 0-9 must be matched.
  • Each number must be easily encoded in order to compare with the input data.
  • Extracting the number of digits from the input data can be worked out given the fixed size of the challenge.
  • Each digit being pattern matched must be encoded in the same way as the list we will compare against.
  • We will need to avoid the blank lines in the data.

Given all these, here is my code below. Lucky for me I could seed my function by using the draw method from previous post so made it easier to test.

First I created a unique encoding of all the numerals from 0-9 using a simple read of each line and concatenating the strings together.  This pre-computer value saves time and should be easy to compare against.

        private static Dictionary<string, string> GetMatchPatterns()
        {
           return new Dictionary<string, string>
                        {
                            {"0", " - | |   | | - "},
                            {"1", "     |     |   "},
                            {"2", " -   | - |   - "},
                            {"3", " -   | -   | - "},
                            {"4", "   | | -   |   "},
                            {"5", " - |   -   | - "},
                            {"6", " - |   - | | - "},
                            {"7", " -   |     |   "},
                            {"8", " - | | - | | - "},
                            {"9", " - | | -   | - "}
                        };
        }

And below is the main Read method that actually does the pattern matching.  It’s fairly concise this time round.

        private static string Read(string number)
        {
            var patterns = GetMatchPatterns();
            var stringReader = new StringReader(number);
            var line = stringReader.ReadLine();
            var nCount = (line.Length / 4) + 1;
            var chars = new string[nCount];

            while (line != null)
            {
                for (int i = 0; i < nCount; i++)
                {
                    var currentPos = (i * 3) + i;
                    var data = new string(line.Skip(currentPos)
                                               .Take(3)
                                               .ToArray());
                    chars[i]= chars[i] + data;
                }

                line = stringReader.ReadLine();
            }

            return chars.Select(c => patterns.First(kc => kc.Value.Equals(c)).Key)
                        .Aggregate((a, b) => a + b);
        }

Performance seems good with rendering of the LCD representation of 1234567890 in around 140 ticks.

Advertisements