Wednesday, January 21, 2009

Generating String Permutations Recursively in C#

This article will demonstrate a simple routine that uses recursion in C# to generate
a list of string permutations. I originally wrote this routine because I was
interested in a little bit larger project in which I thought a routine like this
would be useful. I had become interested in an online game where, given a
string of X number of characters, you see how many way you can combine the letters
in that string to make words. The program would go something like this.

  1. Generate the permutations.
  2. Break each permutation down into 3, 4, 5 ... X letter strings.
  3. Check each break down against a dictionary, if in the dictionary, keep the word

So the first order of business was to generate every possible permutation of an
X character string. After working with a recursive routine, I managed to get
it down to a very simple few lines of code.

First, before going over the code, let's understand the concept. Let's
look at the permutations for a 2 character string. Let's say our string
is 'AB'. The possible permutations are

  1. 'AB'
  2. 'BA'

Very easy, we just switch the last two characters. Now if we want to get the
permutations for a 3 character string, Say 'ABC', that process is very simple
too.

  1. Start with 'ABC'.
  2. Swap the last two characters to get ACB
  3. Now take the original string and move the A into the second to last position giving
    you BAC
  4. Again Swap the last two characters giving you BCA
  5. Now come back out and swap the first two characters giving you CBA
  6. And finally swap the last two characters giving you CAB

If you want to do four characters, the process is the same. Permutate the
right most 2 characters, then swap in character 3 and do the permutations, then
swap in character 4 and do the permutations again. The beauty of the recursion
is that upon leaving one swapping operation, you can get back to an original string
(stored on the stack) and keep the permutations going. Since the calls use
the string lenght to determine how to proceed, you should be able to pass a string
of any length in and get the permutations. The only caveat is that the number
of permutations generated for any given string is exponential as the string get's
larger. The number of permutation is X ! given that X is the number of characters
in the original string. As you can see, it can get quite large pretty quick.

String SizeNumber of PermutationsTime to Process
11 (1!)Negligable
2
2 (2!)Negligable
36 (3!)Negligable
424 (4!)Negligable
..........
103,628,800 (10!)7.27 Seconds
12479,001,600 (12!)Out of Memory error thrown.


The time to process above was done on a dual processor test machine running at 3
GHz with 2 Gig of internal memory. As you can see, with a short string, you
can generate many permutations. Get much more over 10 and you will start to
see some serious performance degradation. If you really need to generate permutations
on strings that large, consider disk storage.

Now that we have discussed the concept, let's look at the code. I have
encapsulated all of the code into one class. Here is the listing for that
class.

using System;
using System.Collections;

namespace Permutations
{
// To save space, I have not used proper techniques of
// hiding attributes behind properties. There are
// probably other things that haven't been done as well
// but I am just trying to show the concept.
class PermutateString
{
// Holds the final array of permutations
public ArrayList AL = new ArrayList();

public PermutateString(string Source)
{
Perm("", Source);
}

private void Perm(string Beginning, string Shuffle)
{
// By the time the Shuffle length get's down to 1,
// we have another permutation to store.
if (Shuffle.Length <= 1)
AL.Add(Beginning + Shuffle);
else
{
for (int Ndx = 0; Ndx < Shuffle.Length; Ndx++)
{
// here, we move the character at the ndx position
// to the front of the line, then copy in the first
// ndx characters of the string and then the characters
// after that. so if NDX is at 3 in the following string,

// then the string ABCDEF would become DABCEF. This loop
// pulls each postion out to the front of the line and then
// calls the Perm operation again.
Shuffle = Shuffle.Substring(Ndx, 1) +
Shuffle.Substring(0, Ndx) +
Shuffle.Substring(Ndx + 1);

// Now that we have moved the shuffled characters around a bit,
// we call the perm function again moving one of the characters back

// to the beginning string.
Perm(Beginning + Shuffle.Substring(0, 1),
Shuffle.Substring(1));
}
}
}
}
}

It may be a little difficult to follow so the best thing to do is to copy the
code into your project and run it through the debugger. As you trace the
values of Beginning and Shuffle, you should see the logic unfold. Hope you
enjoyed this.

Tuesday, January 13, 2009

Mio Moov 500 - My thoughts and impressions.

I have been thinking about it and thinking about it and I have finally entered the age of the GPS enabled. The biggest factor against me purchasing a GPS system was indeed the price. Most of the units that were even halfway useful were cost prohibitive. I had traveled with several friends who had GPS systems and I really thought they were a wonderful invention. Well, this past Christmas and Birthday (they are very close together for me), I received some cash so I renewed my search for the perfect GPS. While out shopping with my wife, I stopped into one of the Radio Shack stores in the local mall and noticed they were having a GPS sale. I looked over the models they had; Garmin, Sony, Tom Tom, etc... but the good ones were all still too expensive ($299 and up). Then I see this model with a funny name, Mio (Me Oh). There was a nice, easy to see screen at 4.7" and the price was $129. This was definitely more my speed. So, off I went to research this particular unit but I didn't have much time as the sale was ending in 3 days. After doing my due diligence on Google, I found the people were pretty much happy with their Mio GPS systems. I decided to take a plunge with this one and so far, after one week of playing with it, I am not disappointed. In fact, I am so happy with it, I am inspired to share this with the rest of the internet world.

Here is what I think of the unit. Before I get started, this is not an article intended to give you the technical specifications of the device. Instead, I am giving you my opinion of it. If I include any specs, it is in that context. If I get a spec wrong, then it is wrong, look at the documentation for the correct spec.

Goods:
These are the things that I liked about the system. This is hardly an exhaustive list of the features.

  • The system starts up and is ready to use right out of the box (with a little battery charging)
    The screen is easy to read. The screen is 4.7" I think and it is very clear and easy to read.
  • The voice prompts are mostly accurate and very timely. I like the progression of warnings before a turn. I have had only one problem with this on I75/85 as it joins through Atlanta. The unit didn't handle this as I thought it should be everything else has been great.
  • The resolution of where you are is mind bogglingly accurate. I can zoom in on the "me" icon and it places me on the map with incredible accuracy. In fact, close to my house is an interstate overpass. The DOT built a bridge right beside is so they could tear down the old bridge and rebuild it. If I am on the new bridge, only 20 feet or so from the old bridge, the unit thinks I am on the expressway and begins to recalculate my route. this can be annoying but is a logical effect of the bridge not being where the software thinks it is.
  • The unit is very configurable. There are lots of configuration options including nighttime display, route planning, how much time/distance is favored, avoiding toll roads, avoiding freeways or not, and the list goes on.

Bads:
While I didn't find too much bad with it, I did find some things that I think could use improvement. Also, this may be that I just haven't figured out how to do this yet.

  • Panning, Zooming and level of detail - I found that when you are on a trip, it is difficult to "pan ahead" and look at turns. If you zoom out, then you loose much of the road detail.
  • The unit doesn't have a built in compass. It seems that it determines direction solely on movement so if you are in a parking lot, you actually have to hit the road to find out which way is which. I think a compass would be a nice addition.

Overall:
I am very impressed with this unit. I have programmed in all my normal destinations and it get's me there the quickest way. I have even found a few places where I didn't know where I was going and the trip was flawless. I am sure as I use it more, I may find some problems but for the most part, it is accurate and very easy to use.

Suggestion:
In parting, I would have this suggestion. When you first get a GPS, I would use it right out of the box, even if you already know where you are going. This way, you become familiar with the unit and learn its quirks and how to operate it. The last thing you need is OJT when you are lost. Also, you may want to be aware that if you have roadwork going on, the trip planner doesn't take that into consideration so a little thinking may be required on your part to get around road closings. That is all and I hope this information has been helpful.