// seqSets is a sequence (ordered) of sets (unordered) // muliconcat computes cartesian product in order of given sequence, with limit of the given width // (a1,a2) x (b1,b2) will give (a1,b2) but not (b1,a2) // not that nice as recursive version, but faster (around 25% increase in speed after using this version) public static SymbolChunkSet <SYMBOL_ENUM> MultiConcat <SYMBOL_ENUM>(SymbolChunkSet <SYMBOL_ENUM>[] seq_sets, int lookaheadWidth) where SYMBOL_ENUM : struct { if (seq_sets.Length == 0) { return(new SymbolChunkSet <SYMBOL_ENUM>()); } else { var finished = new List <SymbolChunk <SYMBOL_ENUM> >(); var incomplete = new List <SymbolChunk <SYMBOL_ENUM> >(); foreach (SymbolChunk <SYMBOL_ENUM> chunk in seq_sets[0].Chunks) { var copy = chunk.GetFirst(lookaheadWidth); if (copy.Count == lookaheadWidth) { finished.Add(copy); } else { incomplete.Add(copy); } } for (int i = 1; incomplete.Any() && i < seq_sets.Length; ++i) { var seeds = incomplete; incomplete = new List <SymbolChunk <SYMBOL_ENUM> >(); foreach (SymbolChunk <SYMBOL_ENUM> seed in seeds) { foreach (SymbolChunk <SYMBOL_ENUM> chunk in seq_sets[i].Chunks) { var copy = seed.Concat(chunk, lookaheadWidth); if (copy.Count == lookaheadWidth) { finished.Add(copy); } else { incomplete.Add(copy); } } } } finished.AddRange(incomplete); return(SymbolChunkSet.Create(finished)); } }
// creates all combinations of symbols up to length given by lookaheadWidth // example: A, B, C, up to 2 // will give: (empty), A, B, C, AA, AB, AC, BA, BB, BC, CA, CB, CC public static SymbolChunkSet <SYMBOL_ENUM> MultiplyUpTo <SYMBOL_ENUM>(IEnumerable <SYMBOL_ENUM> symbols, int lookaheadWidth) where SYMBOL_ENUM : struct { var seed = SymbolChunkSet.Create(symbols.Select(it => SymbolChunk.Create(it))); var working = new SymbolChunkSet <SYMBOL_ENUM>(); var result = new SymbolChunkSet <SYMBOL_ENUM>(); result.Add(SymbolChunk.Create <SYMBOL_ENUM>()); // empty entry foreach (var _ in Enumerable.Repeat(0, lookaheadWidth)) { working = MultiConcat(new[] { working, seed }, lookaheadWidth); result.Add(working); } return(result); }