【发布时间】:2010-12-16 23:57:19
【问题描述】:
我正在寻找一种优雅的方法来计算 C# 中 MasterMind 游戏中的猜测分数,最好使用 LINQ。
在 MasterMind 中,密码生成器使用数字 1 到 6 生成 4 位密码。一个数字可以多次使用。例如,密码是:
int[] secret = { 1, 2, 3, 1 };
密码破解者试图通过猜测来破解密码。在这个例子中,猜测是:
int[] guess = { 1, 1, 2, 2 };
(代码和猜测现在都存储在数组中,但其他集合类型也可以)。
然后,代码制作者通过宣布“黑人”和“白人”的数量来“评分”这个猜测。猜中的每个数字在数值和位置上都是正确的,将获得一个黑色。放置在错误位置的每个正确数字都会获得白色。在此示例中,得分为 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 - 我喜欢使用 LINQ 在代码中表达算法的方式。执行速度不是问题。
【问题讨论】:
-
“C 风格的嵌套循环”到底有什么问题,这看起来像是一个家庭作业。
-
如果猜测是“1111”,您的秘密值的得分是多少?
-
@Ramhound - 我的 C 风格解决方案需要 15 行。我正在掌握 LINQ,并且确信 LINQ 可以用更少的行来做到这一点,同时更具可读性。顺便说一句,当我在学校时,C 是一门现代语言 :-)
-
@Vilx - 2 个黑人 0 个白人。有关 MasterMind 游戏的详细说明,请参阅 wikipedia 上的 Mastermind_(board_game)。