/// <summary> /// Generates all repeating compositions with the specified parameters. /// </summary> /// <param name="compositionParameters">The parameters of the compositions to generate.</param> /// <returns>An <see cref="IEnumerable{T}"/> containing the compositions that were generated.</returns> /// <exception cref="ArgumentNullException"><paramref name="compositionParameters"/> is /// <see langword="null"/>.</exception> /// <exception cref="ArgumentException"><paramref name="compositionParameters"/> does not /// have <see cref="CompositionParameters.Sum"/> a multiple of the number of repetitions of /// this generator, or <paramref name="compositionParameters"/> does not have /// <see cref="CompositionParameters.NumTerms"/> a multiple of the number of repetitions of /// this generator.</exception> /// <remarks> /// <para>The compositions are generated in increasing lexicographical order.</para> /// </remarks> public IEnumerable <Composition> GenerateCompositions(CompositionParameters compositionParameters) { if (compositionParameters is null) { throw new ArgumentNullException(nameof(compositionParameters)); } if (!compositionParameters.Sum.IsMultipleOf(numRepetitions)) { throw new ArgumentException($"The sum ({compositionParameters.Sum}) is not a multiple " + $"of the number of repetitions ({numRepetitions})."); } if (!compositionParameters.NumTerms.IsMultipleOf(numRepetitions)) { throw new ArgumentException($"The number of terms ({compositionParameters.NumTerms}) " + $"is not a multiple of the number of repetitions ({numRepetitions})."); } IEnumerable <Composition> Generate() { var exhaustiveGenerator = new ExhaustiveCompositionGenerator(); var parametersForNonRepeatingCompositions = new CompositionParameters( compositionParameters.Sum / numRepetitions, compositionParameters.NumTerms / numRepetitions); foreach (var nonRepeatingComposition in exhaustiveGenerator.GenerateCompositions(parametersForNonRepeatingCompositions)) { var repeatingTerms = Enumerable.Repeat(nonRepeatingComposition.Terms, numRepetitions).SelectMany(term => term); var repeatingComposition = new Composition(repeatingTerms); yield return(repeatingComposition); } } return(Generate()); }
private IEnumerable <InteractiveLayeredQuiverGeneratorOutput> DoWork( InteractiveLayeredQuiverGenerator interactiveQuiverGenerator, CompositionParameters nextCompositionParameters, ICompositionGenerator compositionGenerator) { if (nextCompositionParameters is null) { yield return(interactiveQuiverGenerator.EndGeneration()); yield break; } foreach (var composition in compositionGenerator.GenerateCompositions(nextCompositionParameters)) { if (!interactiveQuiverGenerator.TrySupplyComposition(composition, out nextCompositionParameters)) { continue; } foreach (var output in DoWork(interactiveQuiverGenerator, nextCompositionParameters, compositionGenerator)) { yield return(output); } interactiveQuiverGenerator.UnsupplyLastComposition(); } }
/// <summary> /// Generates all compositions with the specified parameters. /// </summary> /// <param name="compositionParameters">The parameters of the compositions to generate.</param> /// <returns>An <see cref="IEnumerable{T}"/> containing the compositions that were generated.</returns> /// <exception cref="ArgumentNullException"><paramref name="compositionParameters"/> is /// <see langword="null"/>.</exception> /// <remarks> /// <para>The compositions are generated in increasing lexicographical order.</para> /// </remarks> public IEnumerable <Composition> GenerateCompositions(CompositionParameters compositionParameters) { if (compositionParameters is null) { throw new ArgumentNullException(nameof(compositionParameters)); } // If no terms, return the singleton collection of the empty composition. if (compositionParameters.NumTerms == 0) { return(new Composition[] { new Composition() }); } int numTermsLeft = compositionParameters.NumTerms; var previousValues = new List <int>(); var previousValuesSum = 0; int targetSum = compositionParameters.Sum; return(DoWork(numTermsLeft, previousValues, previousValuesSum, targetSum)); }