Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
211 views
in Technique[技术] by (71.8m points)

C# Building Permutations with replacement but skip if it doesn't exist in a position

I want to permute with replacement but skip if a symbol is not in the list. Currently the implementation does not rely on PayDistribution. it uses only the symbol list. So, if I send the symbolList of (A,B,C) and windowWidth of 3, I will get:

A,A,A

A,A,B

A,A,C

A,B,A

A,B,B

...

C,C,C

But if for example I have a PayDistribution of:

symbol: first to third positions

A:1 1 1

B:1 1 0

C:1 1 1

Where B will not be in the third position, then I don't want to include any permutations where B is in the third position:

A,A,B for example should not exist.

I just want it to jump the the next valid entry. Seems I can add a check in the GetCombinations function to do so, but I am not sure how. Really looking to speed this up by skipping. With large symbolLists it can take a while. My usage isn't super important:

public ACombo[] PayHashLineCreate(SymbolList symbolList, ComboList comboTable, int windowWidth,List<List<int>> PayDistribution)
{
    Console.Write("Creating Pay Hash ");
    WindowWidth = windowWidth;
    SymbolCount = symbolList.NumRegularSym;

    var count = 0;

    var filteredList = new SymbolList();
    
    filteredList.AddRange(symbolList.Where(symbol => typeof (RegularSymbol) == symbol.GetType()));
    filteredList.AddRange(symbolList.Where(symbol => typeof (ScatterSymbol) == symbol.GetType()));
    var filteredSymbolListArray = filteredList.ToArray();

    var filteredComboList = new ComboList();
    filteredComboList.AddRange(comboTable.Where(combo => typeof (T) == combo.GetType()));

    foreach (
        var symbolArrangement in        
  CombinationsWithReplacement.GetCombinationsWithReplacementLexographicOrder(filteredSymbolListArray, windowWidth,PayDistribution))
    {
        Add(null);
        foreach (var combo in filteredComboList)
        {
            var match = Compare(combo, symbolArrangement);
            if (!match) continue;
            this[count] = combo;

            break;
        }
        count++;
    }
    Console.WriteLine("DONE");
    return ToArray(); 
}

But the important functions:

public static IEnumerable<List<T>> GetCombinationsWithReplacementLexographicOrder<T>(IList<T> pool, 
int comboLength, List<List<int>> PayDistribution)
{
    
    foreach (var list in GetCombinations(pool, comboLength, PayDistribution).Select(c => 
c.ToList()))
    yield return list;
}

private static IEnumerable<IEnumerable<T>> GetCombinations<T>(IList<T> list, int length, 
List<List<int>> PayDistribution)
{
            
    if (length == 1) return list.Select(t => new[] { t });

    return GetCombinations(list, length -1).SelectMany(t => list, (t1, t2) => t1.Concat(new[] { t2 
}));
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since the PayDistribution is position first, then symbol, it can be directly converted to a Dictionary for each T and filter the combinations by the matching Dictionary for each position:

private static IEnumerable<List<T>> GetCombinationsWithReplacementLexographicOrder<T>(IList<T> list, int length, List<List<int>> PayDistribution) {
    var PayMap = PayDistribution.Select(g => g.Select((pd,i) => (pd,i)).ToDictionary(pdi => list[pdi.i], pdi => pdi.pd > 0)).ToList();

    foreach (var c in GetCombinations(list, length, PayMap))
        yield return c.ToList();
}

private static IEnumerable<IEnumerable<T>> GetCombinations<T>(IList<T> list, int length, List<Dictionary<T, bool>> PayMaps, int pos = 1) {
    var payMap = PayMaps[length-pos];
    if (pos == length)
        return list.Where(t => payMap[t]).Select(t => new[] { t });

    return GetCombinations(list, length, PayMaps, pos + 1)
            .SelectMany(t => list.Where(t2 => payMap[t2]), (t1, t2) => t1.Concat(new[] { t2 }));
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...