/// <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());
        }
Ejemplo n.º 2
0
        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));
        }