Thursday, 8 May 2008

LINQ-to-Console

In the last episode we made a heady brew of Attributes, Reflection and LINQ to discover all the Problem-solving classes in my Project Euler Console App. The aim was to be able present the user with a list of the problems we'd solved, so they could choose one to run.

I showed the beginning of the process - discovering the classes - and the end - running the solution chosen by the user; I thought there would be nothing interesting about the middle part - displaying the list, and getting the user's choice, but I was wrong. C#3.0 makes even Console programming interesting again!

In the first place we've got the task of taking the meta-data about each problem, and making, not a meal out of it, but a menu. If you remember, we have a list of EulerProblemSolverMetadata objects, each containing the problem number, its title, and the information need by the Reflection APIs to invoke the Solve method in the class. What we need is a nicely formatted string that we can display in the Console.

For that we can use the Enumerable.Aggregate method. This, as you know, works its way through a sequence, combining each item with earlier items in whatever way you specify. We'll use it to add a line for each item to a StringBuilder:

var problemsSummary = solversMetaData.Aggregate(
                       new StringBuilder(),
                       (sb, solverData) =>
                         sb.AppendFormat("{0}: {1}\n", solverData.Number, solverData.Title)
                      );
Console.WriteLine(problemsSummary);

Output is one thing: getting input from a user is another. If users aren't being deliberately evil and trying to crash a program, then they'll often do something stupid; even the best of us sometimes have "senior moments". All of which means that a good proportion of many code bases is taken up with sanitising user input.

I started off with something pretty standard, as follows:

Console.WriteLine("Which problem would you like to solve?");
EulerProblemSolverMetadata chosenSolver = null;

while (chosenSolver == null)
{
    string response = Console.ReadLine();
    int problemNumber = 0;
    bool validResponse = int.TryParse(response, out problemNumber);

    if (!validResponse)
    {
        Console.WriteLine("Please type in a number");
        continue;
    }

    // check whether there is a Solver for that problem number
    chosenSolver = solversMetaData.FirstOrDefault(solver => solver.Number == problemNumber);

    if (chosenSolver != null)
    {
        break;
    }
    else
    {
        Console.WriteLine("That problem number wasn't recognised");
        continue;
    }
}

return chosenSolver;

That while loop made me feel very uncomfortable. It needs to be there to give the user more than one chance at giving a sensible answer: but it would ruin my Functional Programming credentials if I let that stand as my final answer. So I pondered the problem a little while longer (no pun intended!), squinting at that loop to see if I could discern anything that could be made to look LINQish.

Eventually I realised that what I had was essentially a pipeline: the code repeatedly gets user input, subjects it to a set of checks and successive conversions, until finally a valid answer emerges at the other end. If at any stage the pipeline rejects the item, it starts over again. That's almost the cannonical form of a LINQ query: data source, filters, conversions. Once that thought had clicked in my mind, I wrote down what I wanted my code to look like:

var chosenSolver =
       Console.In.ReadLines()
          .Validate(input => input.IsInteger(), "Please type in a number")
          .Select(input => int.Parse(input))
          .Validate(problemNumber =>
                   solversMetaData.Any(metaData => metaData.Number == problemNumber),
                   "That problem number wasn't recognised"
                   )
          .Select(problemNumber =>
                  solversMetaData.First(metaData => metaData.Number == problemNumber)
                  )
          .First();

return chosenSolver;

To make this work, we need just two new extension methods: ReadLines is an extension method on TextReader returning an Iterator to generate a sequence containing succesive pieces of user input:

public static IEnumerable<string> ReadLines(this TextReader reader)
{
  while (true)
  {
     yield return reader.ReadLine();
  }
}

The Validate method is identical to Where in that it filters a sequence using a lambda expression; the only difference is that when Validate rejects an item, it writes out the message that we pass to it:

public static IEnumerable<T> Validate<T>(this IEnumerable<T> sequence, Func<T,bool> predicate, string invalidItemMessage)
{
  foreach (var item in sequence)
  {
    if (predicate(item))
    {
        yield return item;
    }
    else
    {
        Console.WriteLine(invalidItemMessage);
    }
  }
}

With these extension methods in place the LINQ query works identically to the code in the while loop above. Much more beautiful, though, in my opinion, and no loops!

The code can be found in the Program.cs class in the download from MSDN Code Gallery.

Monday, 5 May 2008

LINQ to Reflection

Today we've reached a milestone. 10 Project Euler problems solved, using Functional C# 3.0. To celebrate, I've put the code for all the solutions up on Microsoft's Code Gallery.

You can find them at http://code.msdn.Microsoft.com/projecteuler. I intend to keep this up to date, as I add new solutions.

Before going public, I wanted to spruce up my code a little. It's all held in a Console App. As I was adding new solutions to my project, I'd been creating them as classes, each with their own public static void Main() method, and changing the Startup object in Visual Studio to point to the one I wanted to run. Not very elegant.

What I wanted was a menu that would list all the problems numbers and their titles, and allow the user to pick the one to solve. Being lazy (a great virtue in a programmer!), I didn't want to have to update this menu each time I added a new solution to the project. Let the program find out for itself what solutions exist, I thought.

But how to do that? Enter, Attributes. Attributes are a way of decorating code with additional information. You'll have used an attribute when ever you've marked a class as being Serializable: they are the things that live inside square brackets just before the thing you're decorating. They are often used in combination with Reflection. This is a powerful area of the .Net Base Class libraries which allow you to inspect your code whilst it is running, create classes on the fly, call methods by name, and all kinds of exciting (and just a little scary) things like that.

I decided to create an Attribute to show my program that a particular class is a Project Euler problem solver. The attribute will hold the problem number, and its title.

You define it like this:

public class EulerProblemAttribute : Attribute
    {
        public EulerProblemAttribute(int problemNumber)
        {
            ProblemNumber = problemNumber;
        }

        public int ProblemNumber
        {
            get;
            set;
        }

        public string Title
        {
            get;
            set;
        }
    }

Simple, isn't it. It's like any other class, the key point being that it inherits from Attribute. This is how you use it to decorate a class:

[EulerProblem(7, Title="Find the 10001st prime.")]
    public class Problem7
    {
        public void Solve()
        {
  ...

The next step is to write some code that will find all the classes in the project that are marked with this attribute. This provides a nice opportunity to demonstrate a very practical use of LINQ: you could call it LINQ-to-Reflection.

What I've done is to create a class called EulerProblemSolverMetadata which will hold the information about each solver. The Reflection APIs provide classes that represent the various aspects of code in assemblies. For instance Type holds information about types - classes, structs, etc. MethodInfo holds information about a Method - and allows that method to be invoked dynamically on an object of the appropriate type. So in my EulerProblemSolverMetadata I've put a property called Class which holds the type of the solver, and a property called Method which holds a MethodInfo object representing the "Solve" method which I've decided each solver must have.

Here's the LINQ query that will populate my metadata class for me:

var problemSolvers =
     from type in Assembly.GetExecutingAssembly().GetTypes()
     // filter out types that are not decorated with the EulerProblemAttribute
     where Attribute.IsDefined(type, typeof(EulerProblemAttribute))
     // ensure that the type has a parameterless public Solve method
     let method = type.GetMethod("Solve", new Type[] { })
     where method != null
     // get hold of the attribute, so that we can get the metadata from it
     let attribute = Attribute.GetCustomAttribute(type, typeof(EulerProblemAttribute)) as EulerProblemAttribute
     // sort the problems into ascending order
     orderby attribute.ProblemNumber ascending
     select new EulerProblemSolverMetadata
            {
                Class = type,
                Number = attribute.ProblemNumber,
                Title = attribute.Title,
                Method = method
            };

Now that we've discovered what Solvers are available, we can present the list to the user and ask them to choose one. Once they've made a choice we need to use the metadata to run the appropriate piece of code. To do that we use the Activator class to create an instance of the appropriate Solver type. Then we invoke it's Solve method:

object instance = Activator.CreateInstance(chosenSolver.Class);
chosenSolver.Method.Invoke(instance, new object[] { });

Easy, when you know how.

You can see the full code in the project on the MSDN code gallery.

Next time: LINQ-to-Console!

Project Euler Problem 10

If you remember, we solved Project Euler Problem 10 along with Problem 7. You can find that solution here.

This post is just to keep the sequence tidy!

Thursday, 1 May 2008

Project Euler Problem 9

I've never seen a popularity contest for Mathematical theorems. If one was ever held, I'd bet on Pythagoras's Theorem taking the number one spot - because his is the only theorem that most people have ever heard of. I'd further bet (if I was a betting man) that a good number of them would even be able to quote it - having had it caned into them at school:

"The square on the hypotenuse is equal to the sum of the squares on the other two sides".

Or as my old maths teacher used to say,

"The squaw on the hippopotamus is equal to the sum of the squaws on the other two hides."
(He had a really terrible joke, with this as its punchline; if you're feeling desperate enough, you can read it, and a few others, here)

And so we come to today's problem, Problem 9, which deals with Pythagorean triplets. These are just sets of three integers (a,b,c) with a ^ 2 + b ^2 = c^2; basically, numbers that satisfy Pythagoras's theorem. The problem is to find the unique set of numbers where a + b + c = 1000, and a < b < c.

We'll use a brute force method to solve this. We just need to note that since a must be less than b, and a + b + c = 1000, neither a nor b can exceed 500.

Here's the solution, using C# query syntax:

class Problem9
    {
        public static void Main()
        {
            (
             from a in 1.To(500)
             from b in a.To(500)
             let c = 1000 - a - b
             where a * a + b * b == c * c
             select new { a, b, c, product = a * b * c }
            )
            .Single()
            .DisplayAndPause();
        }
    }

(You can find the code for the two extension methods , To, and DisplayAndPause in the last post)

We're using the two from clauses to generate all possible pairs of numbers (a,b) where a is between 1 and 500, and b is between a and 500. The let clause calculates the value of c, storing it as an intermediate result; The where clause makes sure that a,b and c are truly pythagorean.

In the select clause I'm generating a new anonymous type using the new {...} expression. Anonymous types are just a shorthand way of grouping together a set of properties, without going to the trouble of defining a class to hold them. In many cases you don't even need to give names to those properties: C# will infer names from the variables or properties that you assign into them. So the first 3 properties in this anonymous type will have names "a", "b", and "c"; for the fourth property, I have to stop being lazy and think of a name ("product"), because it gets its value from an expression ("a * b * c"), and C# isn't imaginative enough to pick a name for that.

If you want to use anonymous types yourself, you should note two things. Firstly, the properties on the type are read-only: you can't change their values once they've been initialised. Secondly, you can only easily use anonymous types within the scope of a method: you can't return them from methods for the simple reason that you don't know the name of their type - they're anonymous, duh! Actually, I lie. You can return them from methods, but only if you return them as object - but then you'd need to use Reflection to get hold of their properties.

Because there's a unique answer to this problem, the query expression between the brackets will generate a sequence containing just one element. The Single extension method will return this for us - and will even throw an exception if it finds that there's more than one, which is a useful check that we've got the query expression correct.

As a nice touch, anonymous types have their ToString() method overridden, so that when you display them, as I do in the DisplayAndPause extension method, you see the values of all their properties, like so:

{ a=???, b=???, c=???, product=????}
(except you'd see the answers, rather than the question marks I've put there to stop you cheating!).

Straight forward today, wasn't it?