Может ли кто-то злоупотреблять LINQ и решать эту проблему?

Для удовольствия, я хотел бы, чтобы кто-то использовал и злоупотреблял LINQ для решения этой проблемы с деньгами. Я действительно понятия не имею, как вы это сделаете - я предполагаю, что вы заполняете какой-то набор, а затем выбираете его.

Если дано общее количество монет и общее количество всех монет добавлено вместе: Покажите все возможные комбинации монет. Монеты - кварталы (0,25), Dimes (.10) Никели (0,05) и Пенни (0,01)

Включите эту опцию, чтобы было нулевое число монеты или должно быть не менее 1 из них.

Проблема с образцом: если у меня есть 19 монет, и монеты составляют до $1,56, и там должно быть не менее 1 каждого типа монет.

Ответ будет следующим:

1 квартал, 9 копейки, 8 никелей, 1 пенни

2 квартала, 5 Dimes, 11 Nickels, 1 Pennies

2 квартала, 9 монет, 2 никеля, 6 пенни

3 квартала, 1 день, 14 никелей, 1 пенни

3 квартала, 5 Dimes, 5 Nickels, 6 Pennyies

4 квартала, 1 день, 8 никелей, 6 пенни

5 кварталов, 1 Dimes, 2 Nickels, 11 Pennyies

И если мы допустили нуль для coint, мы позволили получить дополнительный 0 кварталов, 13 Dimes, 5 Nickels, 1 Pennies

Вот пример кода С#, использующего метод грубой силы для решения проблемы. Не беспокойтесь о том, чтобы улучшить выборку, просто взгляните на решение, используя Linq. // По возможности старайтесь не использовать любой циклический код regualar С#.

private void SolveCoinProblem(int totalNumberOfCoins, double totalAmount, int minimumNumberOfEachCoin)
    {
        int foundCount = 0;
        long numberOfTries = 0;
        Console.WriteLine(String.Format("Solving Coin Problem:TotalNumberOfCoins={0}TotalAmount={1}MinimumNumberOfEachCoin{2}", totalNumberOfCoins, totalAmount, minimumNumberOfEachCoin));
        for (int totalQuarters = minimumNumberOfEachCoin; totalQuarters < totalNumberOfCoins; totalQuarters++)
        {
            for (int totalDimes = minimumNumberOfEachCoin; totalDimes < totalNumberOfCoins; totalDimes++)
            {
                for (int totalNickels = minimumNumberOfEachCoin; totalNickels < totalNumberOfCoins; totalNickels++)
                {
                    for (int totalPennies = minimumNumberOfEachCoin; totalPennies < totalNumberOfCoins; totalPennies++)
                    {
                        numberOfTries++;
                        if (totalQuarters + totalDimes + totalNickels + totalPennies == totalNumberOfCoins)
                        {
                            if (Math.Round((totalQuarters * .25) + (totalDimes * .10) + (totalNickels * .05) + (totalPennies * .01),2) == totalAmount)
                            {
                                Console.WriteLine(String.Format("{0} Quarters, {1} Dimes, {2} Nickels, {3} Pennies", totalQuarters, totalDimes, totalNickels, totalPennies));
                                foundCount++;
                            }
                        }
                    }
                }
            }
        }
        Console.WriteLine(String.Format("{0} Combinations Found. We tried {1} combinations.", foundCount, numberOfTries));
    }

Ответ 1

Отключено, но:

        int minQuarters = 1, minDimes = 1,
            minNickels = 1, minPennies = 1,
            maxQuarters = 19, maxDimes = 19,
            maxNickels = 19, maxPennies = 19,
            coinCount = 19, total = 156;
        var qry = from q in Enumerable.Range(minQuarters, maxQuarters)
                  from d in Enumerable.Range(minDimes, maxDimes)
                  from n in Enumerable.Range(minNickels, maxNickels)
                  from p in Enumerable.Range(minPennies, maxPennies)
                  where q + d + n + p == coinCount
                  where q * 25 + d * 10 + n * 5 + p == total
                  select new {q,d,n,p};
        foreach (var row in qry)
        {
            Console.WriteLine("{0} quarter(s), {1} dime(s), {2} nickel(s) and {3} pennies",
                row.q, row.d, row.n, row.p);
        }

Собственно, для розничных целей - возможно, лучший вопрос: "Каковы наименьшие монеты, которые я могу выдать"? Заменить на:

...
from p in Enumerable.Range(minPennies, maxPennies)
where q + d + n + p <= coinCount
where q * 25 + d * 10 + n * 5 + p == total
orderby q + d + n + p
...

и используйте либо First(), либо Take(...);-p

Возможно, вы также можете уменьшить количество проверенных случаев, вычитая (например) q в тесте maxDimes (и так далее...) - что-то вроде (упрощенного):

        int minCount = 1,
            coinCount = 19, total = 156;
        var qry = from q in Enumerable.Range(minCount, coinCount - (3 * minCount))
                  where q * 25 <= total
                  from d in Enumerable.Range(minCount, coinCount - (q + (2 * minCount)))
                  where q * 25 + d * 10 <= total
                  from n in Enumerable.Range(minCount, coinCount - (q + d + minCount))
                  where q * 25 + d * 10 + n * 5 <= total
                  from p in Enumerable.Range(minCount, coinCount - (q + d + n))
                  where q + d + n + p == coinCount
                  where q * 25 + d * 10 + n * 5 + p == total
                  select new { q, d, n, p };