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

One thought on “Coding challenge: Reading an LCD display

  1. leeoades September 16, 2012 at 7:14 am Reply

    This a cool challenge. Simple enough to grok whilst complex enough to make solutions different and subtly interesting.

    Whilst the solution I was just formulating in my head was quite different from this, a couple of suggestions for your code.

    Rather than the linear search of your dictionary values, simply place the lcd string as the key and the single number. This is after all the direction of lookup that you want.

    Also, there are lots of strings being made here. Because of the fixed nature of the lcd strings, one could use char arrays and replace the chars in place. Or stringbuilder obviously.

    I’m going to have a go at this 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: