MasterMind scoring algorithm in C# using LINQ

I'm looking for an elegant way to compute the score of a guess in the MasterMind game in C#, preferably using LINQ.

In MasterMind, the codemaker generates a secret code of 4 digits using the digits 1 through 6. A digit may be used more than once. As an example, the secret code is:

int[] secret = { 1, 2, 3, 1 };

The codebreaker tries to break the secret code by presenting a guess. In this example, the guess is:

int[] guess  = { 1, 1, 2, 2 };

(Both code and guess are now stored in an array, but other collection types are okay too).

The codemaker then "scores" this guess by announcing the number of "blacks" and "whites". A black is awarded for each digit from the guess which is correct in both value and position. A white is awarded for each correct digit placed in the wrong position. In this example, the score is 1 black (for the "1" in position 1) and 2 whites (for the "1" and "2" in positions 2 and 3).

Back to the question: I'm looking for an elegant way to compute the score of a guess in C#, preferably using LINQ. So far, I've come up with a statement that computes the number of blacks:

int blacks = new int[] { 0, 1, 2, 3 }.Count(i => (guess[i] == secret[i]));

I was going to proceed along the lines that the number of whites is the total number of matches (3) minus the number of blacks. So I tried:

int whites = guess.Intersect(secret).Count() - blacks;

But, alas, IEnumerable.Intersect() produces { 1, 2 } instead of { 1, 1, 2 }, because it looks at distinct digits only. So it computes whites = 1 instead of 2.

I cannot come up with another way of computing "whites", except from using "C" style nested loops. Can you? Preferably using LINQ - I like the way an algorithm can be expressed in code using LINQ. Execution speed is not really an issue.

18
задан Fred K 16 December 2010 в 15:15
поделиться