Re: Permuting beyond one collection
- From: "jehugaleahsa@xxxxxxxxx" <jehugaleahsa@xxxxxxxxx>
- Date: Wed, 21 Nov 2007 07:02:02 -0800 (PST)
Think digital clock.
When the minute's number reaches nine, you set it back to zero and
increment the ten's number. If the ten's number goes back to 0,
increment the hour.
I wrote a generic method called CascadingRotation that performs this
action. This what I came up with:
public static IEnumerable<T[]> CascadingRotation<T>(params
IEnumerable<T>[] collections)
{
Debug.ArgumentNull(collections, "collections");
ArrayList<ArrayList<T>> lists = new
ArrayList<ArrayList<T>>();
foreach (IEnumerable<T> collection in collections)
{
Debug.ArgumentNull(collection, "collection");
ArrayList<T> list = new ArrayList<T>(collection);
Debug.LessThanN(list.Count, 1);
lists.Add(list);
}
int i = 0;
int k;
do
{
k = i;
ArrayList<T> tops = new ArrayList<T>();
for (int top = lists.Count - 1; top >= 0; --top)
{
int remainder;
k = System.Math.DivRem(k, lists[top].Count, out
remainder);
tops.Add(lists[top][remainder]);
}
if (k == 0)
{
Reverse<T>(tops.GetFirst(), tops.GetPast());
yield return tops.ToArray();
++i;
}
}
while (k == 0);
}
Its nice because it uses only one indexer, namely i, and uses modulus
properties to get the indexes of each column. It is fast and light on
memory.
Here is the final result of my code:
class Program
{
public static void Main()
{
using (OrderedSet<string> words = getWords())
{
while (true)
{
string number = Console.In.ReadLine();
foreach (string permutation in
getAllPermutations(number))
{
if (words.Contains(permutation))
{
Console.Out.WriteLine(permutation);
}
}
}
}
}
private static OrderedSet<string> getWords()
{
OrderedSet<string> words = new
OrderedSet<string>(Functional.Less<string>);
using (StreamReader reader = new
StreamReader(File.OpenRead(@"E:\Repertoire\data\words.txt")))
{
string line;
while ((line = reader.ReadLine()) != null)
{
words.Add(line.Trim().ToLower());
}
}
return words;
}
private static Regex onlyNumbers = new Regex(@"[2-9]+",
RegexOptions.Compiled);
private static char[][] values =
{
new char[]{ 'a', 'b', 'c' },
new char[]{ 'd', 'e', 'f' },
new char[]{ 'g', 'h', 'i' },
new char[]{ 'j', 'k', 'l' },
new char[]{ 'm', 'n', 'o' },
new char[]{ 'p', 'q', 'r', 's' },
new char[]{ 't', 'u', 'v' },
new char[]{ 'w', 'x', 'y', 'z' }
};
private static IEnumerable<string> getAllPermutations(string
number)
{
ArrayList<string> options = new ArrayList<string>();
if (onlyNumbers.IsMatch(number))
{
ArrayList<char[]> possibleValues = new
ArrayList<char[]>();
foreach (char c in number)
{
possibleValues.Add(values[(int)c - '2']);
}
foreach (char[] option in
Algorithms.CascadingRotation<char>(possibleValues.ToArray()))
{
yield return new String(option);
}
}
}
}
.
- References:
- Permuting beyond one collection
- From: jehugaleahsa@xxxxxxxxx
- Permuting beyond one collection
- Prev by Date: Re: Places to purchase PowerBASIC?
- Next by Date: Re: Places to purchase PowerBASIC?
- Previous by thread: Re: Permuting beyond one collection
- Next by thread: mathematical combination
- Index(es):
Relevant Pages
|