EulerWell: Solving Project Euler problems

Summary EulerWell is a simple framework for solving Project Euler problems.

Project Euler is a collection of challenging math and programming puzzles. As the site itself says,

Project Euler is a series of challenging mathematical/computer programming problems that will require more than just mathematical insights to solve. Although mathematics will help you arrive at elegant and efficient methods, the use of a computer and programming skills will be required to solve most problems.

After talking with some colleagues, I thought it might be useful to start walking through some of these problems as exercises in writing some fun and useful C#. This isn't a new idea, of course -- the natural appeal of writing code to solve simple problems in interesting ways has broad appeal. For example, PyEuler tries to accomplish the same thing by using a functional-programming style of Python.

To accomplish this, I wrote a lightweight framework called EulerWell. EulerWell lets you:

  • Have a common framework to implement solutions to Project Euler problems.
  • Run unit tests for each problem to prove that it works correctly and produces the desired result.
  • Reuse previously solved problems to understand how to solve more complex ones.

The last point is worth noting. Software has many parallels to math here: if you can reduce a complex problem to its more easily solvable constituents, you have to do much less work than solving the problem head-on. We'll see later on that this proves to be a crucial factor in how difficult Project Euler problems appear to be at first glance.

I've opened a Git repository for EulerWell here. You can clone the repository with the following git command.

git clone git://github.com/fj/euler-well.git

Overview of EulerWell

EulerWell is divided into three projects:

  • EulerWell.Common contains a simple framework to describe Project Euler problems.
  • EulerWell.Solvers contains implementations of solutions to Project Euler problems.
  • EulerWell.Tests contains unit tests that you can run against the solution implementations to verify their correctness.

EulerWell.Common namespace

EulerWell.Common is simple and straightforward, and contains only three entities.

  • The SolutionStrategy<T> delegate represents an implementation of the solution to a particular Project Euler problem. The type parameter indicates the type of value that will be returned as an answer. Typically this is a numeric value.
namespace DistilledB.EulerWell.Common { public delegate T SolutionStrategy<T>(); }
  • The IProblemSolver<T> interface represents an implementation of the solution to a particular Project Euler problem. Each of the SolutionStrategy<T> instances in Strategies is capable of solving the problem.
using System.Collections.Generic; namespace DistilledB.EulerWell.Common { public interface IProblemSolver<T> { IEnumerable<SolutionStrategy<T>> Strategies { get; } } }
  • Finally, the ProjectEulerProblemAttribute associates metadata about the Project Euler problem with a particular IProblemSolver<T>. There's nothing that prevents you from using this attribute on other things affiliated with a particular Project Euler problem, however.
using System; namespace DistilledB.EulerWell.Common { [AttributeUsage(AttributeTargets.Class)] public class ProjectEulerProblemAttribute : Attribute { public string Name { get; set; } public string Id { get; set; } public string Description { get; set; } } }

EulerWell.Solvers and EulerWell.Tests namespaces

These two parts represent the meat of the implementation here. EulerWell.Solvers contains each implementation of a solution to a problem, while EulerWell.Tests contains tests that apply to each one.

In an upcoming post we'll talk about how to solve Project Euler problems of varying difficulty.

Trackbacks (none)

TrackBack URL: http://distilledb.com/mt/mt-tb.cgi/24

leave new comment