views:

129

answers:

1

HI, I am working on a simple class to combine items of any type... this is for a poker game, this is how it looks:

public static List<List<T>> combinar<T>(List<T> items, int take)
{
    List<List<T>> combs = new List<List<T>>();
    var stuff = permutar<T>(items, take);

    var all = from s in stuff
                select new Tuple<List<T>, string>(s, String.Join("", s.OrderBy(c => c).Select(c => c.ToString())));
    var strs = all.Select(s => s.Item2).Distinct();
    foreach (var str in strs)
    {
        combs.Add(all.First(a => a.Item2 == str).Item1);
    }
    return combs;
}
public static List<List<T>> permutar<T>(List<T> list, int take)
{
    List<List<T>> combs = new List<List<T>>();
    foreach (var item in list)
    {
        var newlist = list.Where(i => !i.Equals(item)).ToList();
        var returnlist = take <= 1 ? new List<List<T>> { new List<T>() } : permutar(newlist, take - 1);
        foreach (var l in returnlist)
        {
            l.Add(item);
        }
        combs.AddRange(returnlist);
    }

    return combs;
}

so permutation works perfect.. but I am having some trouble with combination, when T is Card it takes hell lots of time to complete... so my question is how to select distinct lists form the result of permutation???

this is the Card Class:

public class Card : IComparable
{
    Suite _Suite;
    public Suite Suite
    {
        get { return _Suite; }
        set { _Suite = value; }
    }
    Grade _Grade;
    public Grade Grade
    {
        get { return _Grade; }
        set { _Grade = value; }
    }
    string _symbol;
    public string Symbol
    {
       //stuff
    }
    public PictureBox Picture
    {
        //stuff
    }
    public override string ToString()
    {
        return _Grade.ToString() + " " + _Suite.ToString();
    }
    public int CompareTo(object obj)
    {
        Card card = (Card)obj;
        return card.Grade > this.Grade ? -1 : card.Grade < this.Grade ? 1 : 0;
    }
}
+1  A: 

Assuming you don't want to make any big algorithmic changes, your biggest problem here is

combs.Add(all.First().Item1);

That doesn't make any sense. Perhaps you meant

combs.Add(all.First(c => c.Item2 == str)).Item1);

However, that would be very slow; if that's what you want, you should put the results of all into a hash table keyed by the string, and use that instead of looping through Distinct results.

If you wanted to get combinations without computing permutations first, the way to do it would be like this. Given some objects, to find the combinations of length K: if K is 0, return the empty list. Else, for each object, take that object, and then recursively append all the K-minus-1-length combinations of the rest of the objects.

mquander
sorry i was doing it this way but modified it to try something and then forgot to undo to post... already edited the original post... I'll try the hash way... and postback...
Luiscencio
looks like the hashtable way is quite fast, but I am having problems casting it back to a List<List<T>>...
Luiscencio
+1 ahahaha done!!! I was doing **t.Cast<List<T>>()** but it should be **t.Values.Cast<List<T>>()** now it is fast enough... now I just have to testit on slow machines... thanks for your advice =)
Luiscencio