Trying to find an algorithm for the Number Mastermind game

In summary, the code that is supposed to guess the secret number for a game called "Mastermind" seems to be impossible to write without knowing the specific rules of the game first. However, by knowing the colors of the pegs and the positions of the pegs, it is possible to solve the game without needing to write code.
  • #1
Arman777
Insights Author
Gold Member
2,168
193
I am trying to write a code to guess the secret number. For example, if I have a secret number called 412.
My code will take the inputs as

120 - 0
312 - 2
439 - 1

where the numbers on the right gives the position of the correct digit at the correct location. I have thought some codes but it seems they would contain many many lines of codes. Can someone recommend me some algorithms
 
Technology news on Phys.org
  • #3
The problem is I am given the number of guesses by another user. I mean I am not getting any values from a server or something. I am given the data let me give you an example. FOr instance I have given only data such as

402 0
390 0
816 2
848 2
777 0
815 1

By using only this data how can I find the secret number ?
 
  • #4
Arman777 said:
By using only this data how can I find the secret number ?
If those are successive guesses with a score, all from one previous game, then how do you know that there is sufficient information to identify only one code, secret number?
Maybe your last guess will be different to the codebreaker's last guess.
 
  • #5
The game is supposed to give two scores for each guess.
In master-mind, it was black pegs for correct color in correct position, and white for correct color in wrong position. There were two algorithms for white pegs which differed if a color could appear more than once in the answer.

I wrote a small program to play the other side so I could do it solitaire instead of requiring a second person. With 4 pegs each filled with one of 6 random colors, I could work out the answer in typically under 5 guesses.
 
  • Like
Likes JamieSalaor
  • #6
Arman777 said:
I am trying to write a code to guess the secret number. For example, if I have a secret number called 412.
My code will take the inputs as

120 - 0
312 - 2
439 - 1

where the numbers on the right gives the position of the correct digit at the correct location.
If the secret number is 412, shouldn't the algorithm tell you if you get two digits correct, or even all three? Why is only digit 2 in the middle guess above identified? The third digit is also correct.
Halc said:
The game is supposed to give two scores for each guess.
In master-mind, it was black pegs for correct color in correct position, and white for correct color in wrong position. There were two algorithms for white pegs which differed if a color could appear more than once in the answer.
This post seems to be related to the questions I've asked above. I've never played Mastermind, so I don't know how the game is played.
 
  • #7
Mark44 said:
If the secret number is 412, shouldn't the algorithm tell you if you get two digits correct, or even all three? Why is only digit 2 in the middle guess above identified? The third digit is also correct.
2 means two of the digits are correct. It doesn't identify which ones.
 
  • Like
Likes JamieSalaor and hmmm27
  • #8
Halc said:
2 means two of the digits are correct. It doesn't identify which ones.
Which is different from what was stated in the OP.
Arman777 said:
where the numbers on the right gives the position of the correct digit at the correct location.
 
  • #9
Arman777 said:
By using only this data how can I find the secret number ?
This is a protean game, with very many different implementations and rules.
The last rule is always; “Other rules may be specified.”

There is no possibility of writing code until every rule has been specified.
You may as well be playing “Mornington Crescent” or any of it's derivatives.
https://en.wikipedia.org/wiki/Mornington_Crescent_(game)
 
  • #10
Is this another coding challenge related question? It certainly isn't any standard version of the Mastermind game which is as others have described (and solutions for which are published as others have also linked).

The idea of a coding challenge is for you to work it out yourself. It is OK to ask for help with technical issues but asking for someone else to solve a problem so that you can submit the solution to a coding challenge is a waste of everyone's time.
 
  • #11
pbuk said:
Is this another coding challenge related question? It certainly isn't any standard version of the Mastermind game which is as others have described (and solutions for which are published as others have also linked).

The idea of a coding challenge is for you to work it out yourself. It is OK to ask for help with technical issues but asking for someone else to solve a problem so that you can submit the solution to a coding challenge is a waste of everyone's time.
I am really not looking for a code. I am just trying to implement an algorithm. I have found one but it requires a great amount of coding and I was looking for a clever one.

Consider this as a new a game it looks like a mastermind yes, but it is different. Let me be muc more clear about the question. Suppose my friend Julia and I playing this game. She guessed a number which I don't know.

And she guessed "846". And my guesses are

402 0
390 0
816 2
848 2
777 0
815 1

For each guess Julia should answer how many digits are correct i.e. are the same in the proposed value and in his secret number - and are placed in the same position.

My algorithm should take the guess values and obtain the secret number.
 
  • #12
I think its a challenging question and we can find some clever algorithm to solve the problem with minimum effort.
 
  • #13
This
Arman777 said:
I am really not looking for a code. I am just trying to implement an algorithm. I have found one but it requires a great amount of coding and I was looking for a clever one.
No, the idea is not to implement someone else's algorithm, the idea is to come up with the algorithm yourself. This belongs in homework really so if the following hint isn't enough to get to one solution I suggest you repost there.
Solving a problem by 'brute force' means trying every possible solution and seeing if it works. Often there are too many possible solutions to make this work in a reasonable amount of time so we have to try something else. How many possible solutions are there here?
 
Last edited:
  • #14
What is it you want?

You asked for an algorithm for Mastermind.
You got one.
Then you said, "No, no, this isn't Mastermind. It is some other game like Mastermind."

You have to give us the rules. It is not sufficient to give us one example of a played game and hope we can infer the rules. You are asking us to guess the correct question and then provide the answer.
 
  • #15
pbuk said:
This

No, the idea is not to implement someone else's algorithm, the idea is to come up with the algorithm yourself. This belongs in homework really so if the following hint isn't enough to get to one solution I suggest you repost there.
Solving a problem by 'brute force' means trying every possible solution and seeing if it works. Often there are too many possible solutions to make this work in a reasonable amount of time so we have to try something else. How many possible solutions are there here?
I know that its just I am trying to create a discussion type subject. You don't have to give me the answer. I can start by telling my idea

So for the 3 digit number we can separate the digits. Let me consider the previous example

1 - Create an array that contains all the 3 digit numbers (100, 999) (Let us call this array pos_num)
2- Take a guess number (let us take 402)
3 - If the returned value is "0",
3 - Seperate its digits _4_, _0_, _2_
4 - Remove all numbers that contains _4_ in the first digit, similarly remove all the numbers that contains _0_ in the second digit and remove all the numbers that contain _2_ at the third digit.

It goes like this. Its similar if the returned value is 1 and for the 2 but it seems a bit messy to create a code. This is not a homework ..
 
  • #16
Arman777 said:
I can start by telling my idea

So for the 3 digit number we can separate the digits. Let me consider the previous example

1 - Create an array that contains all the 3 digit numbers (100, 999)
First of all, zero is not legal as a first digit? That's one 'color' that is not legal in certain positions, which kind of goes against the general master-mind vibe. The general form of the game is X many positions, and Y many colors/characters that each position can be. There's no rule about it having to look like a number at all, let alone a normalized one. The program I use uses letters, so up to 26 'colors'.
Your OP is very vague about this. Nowhere does it say that the number of digits of your normalized number is known, so the correct answer may well be 332780195.
Secondly, this brute method works for this trivial example of a thousand possibilities, but not so good if there's say 20 positions and 17 colors to choose from. Your computer doesn't have enough time or memory for an array that large.

How does a human do it? I don't find myself iterating though all 1000 numbers and rejecting them one by one. I can glance at just those middle two clues and narrow it down to just two possibilities. What is a non-brute method that might do that?

Finally, suppose there is more than one answer that satisfies all the clues. How does the algorithm pick one? Just say "unsolvable with current information"? Or is it playing the game and needs to choose something? If the latter, what makes for a good choice vs. a poor one? Does it only pick from the list of possible solutions or is it trying to minimize the number of guesses needed?
 
Last edited:
  • Like
Likes JamieSalaor
  • #17
Let the first poor guess be 402 – 0. Then a second very lucky guess is 846, which happens to be the correct answer.

If I gave you 402 – 0, you could not possibly derive the correct answer from that one bad guess.

It demonstrates that there may be no rational solution to many examples.
 
  • #18
Is this the game?

You guess a number. If it's wrong you get back the number of correct digits. The goal is to find the answer using the fewest guesses?

If so, you probably want to track not just what you've ruled out, but also the probabilities.
 
  • #19
Arman777 said:
1 - Create an array that contains all the 3 digit numbers (100, 999) (Let us call this array pos_num)
Like @Halc I am surprised that you are excluding the possibility of 0 as a first digit.

Arman777 said:
2- Take a guess number (let us take 402)
3 - If the returned value is "0",
3 - Seperate its digits _4_, _0_, _2_
4 - Remove all numbers that contains _4_ in the first digit, similarly remove all the numbers that contains _0_ in the second digit and remove all the numbers that contain _2_ at the third digit.
So doing it that way you take the set of possible solutions and eliminate from it elements that cannot be solutions - that should work, at the end you should have left only candidates that fit each of the marking responses (of which there may be none, one or more than one).

I can think of an easier way to find candidates that fit each of the marking responses though, can you?

Arman777 said:
This is not a homework ..
No but it fits the criteria for the homework section, I'll get it moved.

Halc said:
Secondly, this brute method works for this trivial example of a thousand possibilities, but not so good if there's say 20 positions and 17 colors to choose from. Your computer doesn't have enough time or memory for an array that large.
Yes but we don't have 20 positions and 17 colours: premature generalisation is an even bigger sin than premature optimisation IMHO.

Baluncore said:
If I gave you 402 – 0, you could not possibly derive the correct answer from that one bad guess.
Why do you see this as a problem? A suitable algorithm should be able to identify and report all possible solutions, even if there are more than one (or none).

Baluncore said:
It demonstrates that there may be no rational solution to many examples.
What does an irrational solution look like :wink:
 
  • Haha
Likes sysprog
  • #20
Oh, you might find the following piece of code useful:
Python:
def getDigit(n, index):
  return (n // (10 ** index)) % 10
 
  • Like
Likes Arman777 and sysprog
  • #21
I was ready to give the post #19 reply of @pbuk a 'like', but the
What does an irrational solution look like :wink:
at the end made me change the 'like' to a 'haha', and now he gets a 'like' for post #20 ##\dots##
 
  • #22
Jarvis323 said:
If so, you probably want to track not just what you've ruled out, but also the probabilities.
There are probabilities? I mean, each clue eliminates a bunch of otherwise viable answers. The remaining ones are equally probable assuming it was randomly chosen in the first place.
That said, some next-guesses are far superior to other ones, and a good algorithm would choose one of those despite the fact that all remaining possibilities are equally probable. Sometimes the best next guess is one that is known to have been eliminated, and thus has zero probability of being correct.

pbuk said:
Yes but we don't have 20 positions and 17 colours: premature generalisation is an even bigger sin than premature optimisation IMHO.
I could just write a program that does effectively: print ("846") then. It seems to be a generalization to write one that prints the answer for a different data set. Just saying, where do you draw the line?
I always think in terms of scalability, but nevertheless agree that a good scalable solution may not be optimal if the working dataset is known to be confined to small cases.
 
  • Like
Likes JamieSalaor
  • #23
Halc said:
There are probabilities? I mean, each clue eliminates a bunch of otherwise viable answers. The remaining ones are equally probable assuming it was randomly chosen in the first place.
That said, some next-guesses are far superior to other ones, and a good algorithm would choose one of those despite the fact that all remaining possibilities are equally probable. Sometimes the best next guess is one that is known to have been eliminated, and thus has zero probability of being correct.I could just write a program that does effectively: print ("846") then. It seems to be a generalization to write one that prints the answer for a different data set. Just saying, where do you draw the line?
I always think in terms of scalability, but nevertheless agree that a good scalable solution may not be optimal if the working dataset is known to be confined to small cases.
The probability would be based on your knowledge (in a Bayesian sense).

There would be probabilities for each digit separately. For example, if your first guess is 123 and it gives back 2. Then it means that 1 out of 3 digits were incorrect. So there is a 2/3 chance for each digit that it is the one you guessed and 1/3 probability it is something else.

At each guess there would be one or more maximum likely guesses. You keep updating your probabilities after each guess.

A greedy algorithm would always choose one of the most probable new guesses. I'm not saying that the greedy algorithm is necessarily optimal though. That was just my initial thought.
 
Last edited:
  • #24
pbuk said:
I can think of an easier way to find candidates that fit each of the marking responses though, can you?
Maybe a hint ?
 
  • #25
Halc said:
I could just write a program that does effectively: print ("846") then. It seems to be a generalization to write one that prints the answer for a different data set.
No, it is a requirement that the program works out the solution for any set of marked guesses, not just the example.

Halc said:
Just saying, where do you draw the line?
At the requirements. It is a requirement to solve for any 3-digit problem.
 
  • #26
Arman777 said:
Maybe a hint ?
Well I am not sure I can give a much better hint, and there seems to be a few posts here getting lost down rabbit holes so I am just going to post a solution in the spoiler below and on repl.it.

Python:
# The number of digits in a possible solution.
DIGITS = 3

def getDigit(n, index):
  return (n // (10 ** index)) % 10

def mark(answer, guess):
  correct = 0
  for digit in range(DIGITS):
    if getDigit(guess, digit) == getDigit(answer, digit):
      correct += 1
  return correct

def solve(problem):
  solutions = []
  # Iterate over all possible answers.
  for answer in range(10 ** DIGITS - 1):
    markIsWrong = False
    # Check the mark given for each round.
    for [guess, marked] in problem:
      if mark(answer, guess) != marked:
        markIsWrong = True
        break
    if (not markIsWrong):
      solutions.append(answer)
  return solutions

# Try the example problem.
problem = [
  [402, 0],
  [390, 0],
  [816, 2],
  [848, 2],
  [777, 0],
  [815, 1],
]

solutions = solve(problem)
count = len(solutions)

if count == 0:
  print('No solutions found')
elif count == 1:
  print('Found unique solution', solutions[0])
else:
  print('Found', count, 'solutions:', solutions)
 
Last edited:
  • Like
Likes Arman777
  • #27
pbuk said:
No, it is a requirement that the program works out the solution for any set of marked guesses, not just the example.

At the requirements. It is a requirement to solve for any 3-digit problem.
Obviously, but I saw no such explicit requirement in the OP, so I labeled that a generalization, which is how a scalable solution was labeled by you. The OP asked how to solve the one example, and it didn't even specify that the size of the number was known to be 3 items, and that the items were to be selected from and only from an alphabet of 10 digits. Without such a specification, it wasn't really known how complex the program needed to be.
Really, the brute method is probably optimal for a 3-digit number. Saving an extra 100th of a second isn't going to get anybody back to their family any sooner.

The clues in the OP are not enough to determine a unique answer. Was the program to simply report this fact, or should it take a valid guess, or should it play an optimal move? The 'specification' doesn't say.

Jarvis323 said:
The probability would be based on your knowledge (in a Bayesian sense).

There would be probabilities for each digit separately. For example, if your first guess is 123 and it gives back 2. Then it means that 1 out of 3 digits were incorrect. So there is a 2/3 chance for each digit that it is the one you guessed and 1/3 probability it is something else.
But the purpose of the program is not to find the probability that the first digit is X. It is supposed to find the one (or one of? or a list of all?) answer.

At each guess there would be one or more maximum likely guesses.
Kindly illustrate with an example where one answer is more likely than any other.

For instance, suppose the answer is 412 (per OP) and the one and only (very lucky) guess so far is 312 which yields an reply of <2 correct>. That means each of the 3, 1, and 2 has a 2/3 probability of being correct. So what? That just means that in a list of all the 27 possible answers, each of those digits appears in its respective place in 18 of them, but it doesn't make anyone of those 27 answers more probable than any other.
 
  • #28
I won't look at it..as I said I am not looking for a solution..let me try to think more and maybe I start a new thread..and when I find it I ll come back and compare.. but that's really amazing you find a solution in such a short time. I guess I am not really a good coder
 
  • #29
Jarvis323 said:
A greedy algorithm would always choose one of the most probable new guesses. I'm not saying that the greedy algorithm is necessarily optimal though. That was just my initial thought.

Well, it's hard to tell since we seem to be playing Calvinball, but I think "greedy" has at least two meanings: one would be to get the highest possible number of hits on this turn, and the other would be to remove as many incorrect solutions from the search space as possible.

The example is likely confusing because it is an example of non-optimal play:

Arman777 said:
402 0
390 0
816 2
848 2
777 0
815 1

After 848 there are only two possibilities: 846 and 818. Guessing 777 gives no new information. Guessing 717 or 776 or 778 etc. would all you to infer the answer in the next turn, but at this point no strategy is better than guessing one number and if it isn't right, guessing the other.
 
  • #30
Halc said:
But the purpose of the program is not to find the probability that the first digit is X. It is supposed to find the one (or one of? or a list of all?) answer.

I obviously misread the problem statement if you read my first post.

Kindly illustrate with an example where one answer is more likely than any other.

For instance, suppose the answer is 412 (per OP) and the one and only (very lucky) guess so far is 312 which yields an reply of <2 correct>. That means each of the 3, 1, and 2 has a 2/3 probability of being correct. So what? That just means that in a list of all the 27 possible answers, each of those digits appears in its respective place in 18 of them, but it doesn't make anyone of those 27 answers more probable than any other.

In the case where you already have 2 out of 3 right, and know nothing else, then it is true that each possible answer is equally likely next. An example where they aren't equal is after getting back a 1 on the first guess. With more than 3 digits you would get a lot more interesting and complicated situations in terms of probability.
 
  • #31
Vanadium 50 said:
The example is likely confusing because it is an example of non-optimal play:
It is true that the OP was not as clear as they could have been, but it is clear to me at least that the problem is NOT to find an a priori strategy for playing the game by making guesses, it is to determine ex post from a set of marked guesses the solution(s) (if any).
 
  • #32
Jarvis323 said:
In the case where you already have 2 out of 3 right, and know nothing else, then it is true that each possible answer is equally likely next. An example where they aren't equal is after getting back a 1 on the first guess.

[/QUOTE]So you assert.
Back to the OP, guessing 439 (1). That just means that in the remaining list of all the 243 possible answers , each of those digits appears in its respective place in 81 of them, but it doesn't make anyone of those 243 answers more probable than any other. I notice you didn't call out any specific answer as being more probable than some other valid answer.
Yes, the list is longer with a reply of 1 (and even longer with 0 in the case of only 3 digits), but that doesn't make their probabilities unequal.
With more than 3 digits you would get a lot more interesting and complicated situations in terms of probability.
With more than 3 digits, there would be n*9n-1 possible answers, all equally probable.
 
  • #33
Halc said:
So you assert.
Back to the OP, guessing 439 (1). That just means that in the remaining list of all the 243 possible answers , each of those digits appears in its respective place in 81 of them, but it doesn't make anyone of those 243 answers more probable than any other. I notice you didn't call out any specific answer as being more probable than some other valid answer.
Yes, the list is longer with a reply of 1 (and even longer with 0 in the case of only 3 digits), but that doesn't make their probabilities unequal.
With more than 3 digits, there would be 9n possible answers, all equally probable.
https://en.wikipedia.org/wiki/Bayesian_probability

439 (1) means P(437) > P(457) > 0
 
  • #34
pbuk said:
It is true that the OP was not as clear as they could have been, but it is clear to me at least that the problem is NOT to find an a priori strategy for playing the game by making guesses, it is to determine ex post from a set of marked guesses the solution(s) (if any).
Yeah that's the whole idea. Guesses are given by the computer. No one is guessing in here. Someone puts the guesses in front of you and he says its certain that for the given numbers, you ll find the secret number. What would be your algorithm to obtain this secret number from the given list of guesses
 
  • #35
Arman777 said:
I won't look at it..as I said I am not looking for a solution..let me try to think more and maybe I start a new thread..and when I find it I ll come back and compare..
I'll give you another hint. From the example in #3:
Code:
Guess Mark
402    0
390    0
816    2
848    2
777    0
815    1
How can I tell that the secret is not 400?

Arman777 said:
thats really amazing you find a solution in such a short time. I guess I am not really a good coder
I've been doing this sort of thing for 45 years which means that (i) I have had a lot of practice and (ii) I have seen many different problems with some similar characteristics.
 
Back
Top