我正在寻找一种优雅的方法来计算在C#的MasterMind游戏中的猜测得分,最好使用LINQ。
在MasterMind中,编码器使用数字1到6生成4位数字的密码。一个数字可以多次使用。例如,密码为:
int[] secret = { 1, 2, 3, 1 };
密码破解者试图通过提供猜测来破解密码。在此示例中,猜测为:
int[] guess = { 1, 1, 2, 2 };
( code和guess现在都存储在一个数组中,但其他集合类型也可以)。
然后,编码者通过宣布“黑人”和“白人”的数量来给这个猜测“评分”。猜测中的每个数字都会被奖励一个黑色,无论是数值还是位置都是正确的。每一个正确的数字放在错误的位置,就会得到一个白色的奖励。在此示例中,分数为1黑色(位置1中的"1“)和2白色(位置2和3中的"1”和"2“)。
回到问题:我正在寻找一种在C#中计算猜测分数的优雅方法,最好是使用LINQ。到目前为止,我已经提出了一个计算黑人数量的语句:
int blacks = new int[] { 0, 1, 2, 3 }.Count(i => (guess[i] == secret[i]));
我将沿着这样的思路继续下去,即白人的数量是匹配的总数量(3)减去黑人的数量。所以我试着:
int whites = guess.Intersect(secret).Count() - blacks;
但是,遗憾的是,IEnumerable.Intersect()生成{ 1,2}而不是{ 1,1,2 },因为它只查看不同的数字。所以它计算的是whites =1而不是2。
除了使用"C“样式的嵌套循环之外,我想不出另一种计算”白色“的方法。你能?最好使用LINQ -I,就像使用LINQ用代码表示算法的方式一样。执行速度并不是真正的问题。
发布于 2010-12-16 21:31:31
var black = guess
.Zip(secret, (g, s) => g == s)
.Count(z => z);
var white = guess
.Intersect(secret)
.Sum(c =>
System.Math.Min(
secret.Count(x => x == c),
guess.Count(x => x == c))) - black;
给定:
int[] secret = { 1, 2, 3, 1 };
int[] guess = { 1, 1, 2, 2 };
然后:
black == 1 && white == 2
发布于 2010-12-16 23:57:20
Ani的回答是好的。这里有一个更好的(更清晰的)方法来进行分组和连接。
ILookup<int, int> guessLookup = guess.ToLookup(i => i);
int blackPlusWhite
(
from secretNumber in secret.GroupBy(i => i)
let secretCount = secretNumber.Count()
let guessCount = guessLookup[secretNumber.Key].Count()
select Math.Min(secretCount, guessCount)
).Sum()
int black = Enumerable.Range(0, secret.Count).Count(i => guess[i] == secret[i]);
int white = blackPlusWhite - black;
https://stackoverflow.com/questions/4460940
复制相似问题