Archive for September, 2009

Demo of Euclid.NET Launched

Posted in Programming, Projects, Software on September 20th, 2009 by Noldorin – Be the first to comment

Just a quick note that I’ve recently put up an interactive demo of my Euclid.NET project (symbolic mathematical framework for .NET).  This project is based off my TeX.NET parser, which is currently all of which the demo presently consists. I hope to both expand and document the support for the parser soon, as well as starting some serious work on Euclid.NET specifically (most likely, a symbolic differentiator to begin).

Writing a Parser in C#

Posted in Programming, Projects on September 14th, 2009 by Noldorin – 1 Comment

This is just a quick note about a particularly useful article that I stumbled across in the process of writing my TeX Math parser (to be described in full in an upcoming post). The article Grammars and parsing with C# 2.0 is a wonderful introduction to writing a lexer and parser for any language represented by a context free grammar (more accurately, a parser expression grammar).

The document is written in a refreshingly lucid fashion and what is more there are straightforward examples in C# regularly interspersed. (I am not overly-inclined to give out such praise!) For a topic so mired in confusion and complexity, I though this would be an especially helpful link to share with any C# coders who are interested in entering the field, as I am currently doing myself. The content is something I believe any coder with a solid background in OOP should be able to drive straight into without much difficulty (that isn’t to say you will glean everything from a one-pass read). Of course, it is only a guide for relative beginners (albeit a fairly thorough one) – if anyone happens to have other basic or more advanced texts on the subject of similar quality, it would be great to compile a small collection of selective resources on the subject, and expand this post in the process.

Hungarian Algorithm in C#

Posted in Maths & Science, Programming on September 8th, 2009 by Noldorin – 23 Comments

The Hungarian algorithm, also known as the Kuhn-Munkres algorithm, is well-known to be the most efficient algorithm for solving the assignment problem. In fact, it does what is considered by many to an exponential time algorithm (more specifically, factorial time), in O(n3).

The Wikipedia page describes the general form of the problem quite well.

There are a number of agents and a number of tasks. Any agent can be assigned to perform any task, incurring some cost that may vary depending on the agent-task assignment. It is required to perform all tasks by assigning exactly one agent to each task in such a way that the total cost of the assignment is minimized.

However, the implementation of this algorithm is far from trivial. In fact, for all my Googling, not a single implementation in C# turned up (though there was at least one in each of C, C++, Java, and Python). Given this opportunity, I took on the task of porting this code given on this page in the Ada language, to C# 3.0. With almost 300 lines of code, and a bit of debugging with the sample problem,

You may download the complete code for the algorithm, in C# 3.0, here. It is contained within a single static class that exposes an extension method that operates on a matrix (2D array), for ease of use. Although I believe that as an almost line-for-line port of the Ada code, there should not be any issues with my implementation, any bug reports would be appreciated.

Updated 15/10/09: Several bug fixes have been made that fix issues (most noticeably, endless looping) for non-square as well as various other sorts of matrices.

Updated 24/10/09: Fixed bug (endless looping) that affects large variety of matrices involving ConvertPath function.

Google Code Jam in C#

Posted in Fun, Programming on September 3rd, 2009 by Noldorin – Be the first to comment

The Qualification round for Google Code Jam 2009 is entering its closing hours, and having submitted my solutions for the three problems, I thought I would share just the framework I set up for solving the problems. This is something I originally began  writing for last year’s Code Jam, but I have updated it for the altered format this year, as well as expanded the functionality.

The framework consitsts of a class that has a number of simple methods for accessing the input data as well as writing the output cases. The main convience is its abstraction of the text file I/O  into simple methods that deal with arrays (and arrays of arrays) of primitive types. As a bonus, all the relevant output information, as well as the execution time, is printed to the standard out stream (console window).

using System;
using System.IO;
using System.Text;

public class CodeJamProblem : IDisposable
{
    protected int caseNumber;

    protected StreamReader textReader;
    protected StreamWriter textWriter;

    private bool disposed = false;

    public CodeJamProblem(string inputFileName)
    {
        this.InputFileName = inputFileName;
        this.OutputFileName = Path.ChangeExtension(this.InputFileName, ".out");

        this.textReader = new StreamReader(this.InputFileName);
        this.textWriter = new StreamWriter(this.OutputFileName);

        this.caseNumber = 1;
        this.StartTime = Environment.TickCount;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                this.ElapsedTime = Environment.TickCount - this.StartTime;

                textReader.Dispose();
                textWriter.Dispose();

                Console.WriteLine("Elapsed time: {0:#,#0}ms", this.ElapsedTime);
                Console.Beep();
                Console.ReadKey(true);
            }
        }

        disposed = true;
    }

    public int StartTime
    {
        get;
        private set;
    }

    public int ElapsedTime
    {
        get;
        private set;
    }

    public int CurrentCaseNumber
    {
        get { return this.caseNumber; }
    }

    public bool InputAvailable
    {
        get { return this.textReader.Peek() != -1; }
    }

    public string InputFileName
    {
        get;
        private set;
    }

    public string OutputFileName
    {
        get;
        private set;
    }

    public void OutputCase(params object[] values)
    {
        var parts = new string[values.Length];
        for (int i = 0; i < parts.Length; i++)
            parts[i] = values[i].ToString();
        OutputCase(string.Join(" ", parts));
    }

    public void OutputCase()
    {
        OutputCase((string)null);
    }

    public void OutputCase(string value)
    {
        WriteLine("Case #{0:#0}: {1}", this.caseNumber, value);
        this.caseNumber++;
    }

    public void WriteArrays<T>(T[][] entries)
    {
        for (int i = 0; i < entries.Length; i++)
            WriteArray(entries[i]);
    }

    public void WriteArray<T>(T[] values)
    {
        var parts = new string[values.Length];
        for (int i = 0; i < parts.Length; i++)
            parts[i] = values[i].ToString();
        WriteLine(string.Join(" ", parts));
    }

    public void WriteLines(string[] lines)
    {
        for (int i = 0; i < lines.Length; i++)
            WriteLine(lines[i]);
    }

    public void WriteLine(string format, params object[] arg)
    {
        Console.WriteLine(format, arg);
        this.textWriter.WriteLine(format, arg);
    }

    public void WriteLine(string line)
    {
        Console.WriteLine(line);
        this.textWriter.WriteLine(line);
    }

    public int[][] ReadIntArrays(int count)
    {
        var entries = new int[count][];
        for (int i = 0; i < entries.Length; i++)
            entries[i] = ReadIntArray();
        return entries;
    }

    public int[] ReadIntArray()
    {
        var parts = ReadParts();
        var values = new int[parts.Length];
        for (int i = 0; i < values.Length; i++)
            values[i] = int.Parse(parts[i]);
        return values;
    }

    public double[][] ReadDoubleArrays(int count)
    {
        var entries = new double[count][];
        for (int i = 0; i < entries.Length; i++)
            entries[i] = ReadDoubleArray();
        return entries;
    }

    public double[] ReadDoubleArray()
    {
        var parts = ReadParts();
        var values = new double[parts.Length];
        for (int i = 0; i < values.Length; i++)
            values[i] = double.Parse(parts[i]);
        return values;
    }

    public string[] ReadParts()
    {
        return ReadLine().Split(' ');
    }

    public string[] ReadLines(int count)
    {
        var lines = new string[count];
        for (int i = 0; i < lines.Length; i++)
            lines[i] = ReadLine();
        return lines;
    }

    public string ReadLine()
    {
        return this.textReader.ReadLine();
    }
}

Hopefully this will assist someone other tham myself, though I suspect most contestants have set up something of the same sort. I will continue to make minor modifications over the duration of the contest, and will update this post to reflect them.

Regarding the Qualification round itself, the problems have proven to be fairly interesting. (Well, the first was rather trivial if one is honest.) Now, only to wait for the upcoming Round 1, and hope the problems don’t become too much more challenging!