繁体   English   中英

有人可以滥用LINQ并解决这个钱难题吗?

[英]Can someone abuse LINQ and solve this money puzzle?

为了它的乐趣,我想看到有人使用和滥用LINQ来解决这个钱的问题。 我真的不知道你会怎么做 - 我想填充一些然后选择它。

如果给出一定数量的硬币并将所有硬币的总金额加在一起:显示每种可能的硬币组合。 硬币是四分之一(.25),尺寸(.10)镍(.05)和便士(.01)

包括选项,以便硬币类型可以为零,或者每个硬币必须至少有1个。

示例问题:如果我有19个硬币并且硬币加起来为1.56美元并且每种类型的硬币必须至少有1个。

答案是:

1个季度,9个尺寸,8个镍,1个便士

2个宿舍,5个角,11个镍,1个便士

2个季度,9个尺寸,2个镍,6个便士

3个宿舍,1个角,14个镍,1个便士

3个宿舍,5个角,5个镍,6个便士

4个宿舍,1个角钢,8个镍币,6个便士

5个季度,1个尺寸,2个镍,11个便士

如果我们允许零投注,我们允许额外获得0个季度,13个角钱,5个镍币,1个便士

下面是一些使用强力方法解决问题的示例C#代码。 不要费心改进样本,让我们看看使用Linq的解决方案。 //如果可能的话,尽量不要使用任何regualar c#循环代码。

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));
    }

未经测试,但是:

        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

您还可以通过在maxDimes测试中减去(例如) q来减少已检查案例的数量(等等......) - 类似于(简化):

        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 };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM