2.1. Black-Peg AB-Mastermind, Case
For convenience, we will use the term permutation for both, a mapping in and its one-line representation as a vector. Our algorithm for finding the secret permutation includes two main phases that are based on two ideas. In the first phase, the codebreaker guesses an initial sequence of n permutations that has a predefined structure. In the second phase, the structure of the initial sequence and the corresponding information by the codemaker enable us to identify correct components of the secret code one after another, each by using a binary search. Recall that, for two codes and , we denote by the number of components in which w and x are equal. We denote the mapping x restricted to the set with , .
Phase 1. Consider the
n permutations,
, which are defined as follows:
corresponds to the identity map and, for
, we obtain
from
by a circular shift to the right. For example, if
, we have
,
,
and
. Within those
n permutations, every color appears exactly once at every position and, thus, we have
The codebreaker guesses
and obtains the additional information
from Equation (
1).
Phase 2. The strategy of the second phase identifies the values of y one after another. This is done by using two binary search routines, called findFirst and findNext, respectively. The idea behind both binary search routines is to exploit the information that, for we have , , and , while, except for an infrequent special case, findFirst is used to identify the first correct component of the secret code, and findNext identifies the remaining components in the main loop of the algorithm. Actually, findFirst would also be able to find the remaining components but requires more guesses than findNext (twice as many in the worst case). On the other hand, findNext only works if at least one value of y is already known such that we have to identify the value of one secret code component in advance.
Identifying the First Component: Equation (
1) implies that either
holds for all
or that we can find a
with
.
In the first case, which is infrequent, we can find one correct value of y by guessing at most modified versions of some initial guess, say . Namely, if we define a guess by swapping a pair of components of , we will obtain , if and only if one of the swapped components has the correct value in .
In the frequent second case, we find the first component by
findFirst in at most
guesses. The routine
findFirst is outlined as Algorithm 1 and works as follows. In the given case, we can either find a
with
but
and set
, or we have
but
and set
and
. We call such an index
j an
active index. Now, for every
we define the code
and call the peg at position
ℓ in
the pivot peg. Note that notations of the form
substitute
and vanish in the case
. From the information
for
, we conclude that
is actually a new permutation as required. The fact that
implies that the number of correct pegs up to position
in
is either
(if
) or
(if
). For our algorithm, we will only need to know if there exists one correct peg in
up to position
. The question is cleared up, if
. On the other hand, if
, we can define a new guess
by swapping the pivot peg with a wrong peg in
. We define
Algorithm 1: Routine findFirst |
|
For the case , we may assume that we applied our query procedure for an already, proving that the first pegs in are wrong, particularly . Now, we obtain , if and only if the pivot peg had a wrong color in meaning that there is one correct peg in in the first places. Thus, we can find the position m of the leftmost correct peg in by a binary search as outlined in Algorithm 1.
Identifying a Further Component: For the implementation of
findNext (Algorithm 2), we deal with a partial solution vector
x that satisfies
for all
. We call the (indices of the) non-zero components of the partial solution
fixed. They indicate the components of the secret code that have already been identified. The (indices of the) zero components are called
open. Whenever
findNext makes a guess
, it requires knowing the number of open components in which the guess coincides with the secret code, i.e., the number
Note that the term
is known by the codebreaker and not greater than
. After the first component of
y has been found and fixed in
x, there exists a
such that
. As long as we have open components in
x, we can either find a
with
but
and set
, or we have
but
and set
and
. Again, we call such an index
j an
active index. Let
j be an active index and
r its related index. Let
c be the color of some component of
y that is already identified and fixed in the partial solution
x. With
and
we denote the position of color
c in
and
, respectively. The peg with color
c serves as a pivot peg for identifying a correct position
m in
that is not fixed yet. There are two possible modes for the binary search that depend on the fact if
. The mode is indicated by a Boolean variable
and determined by lines 5 to 10 of
findNext. Clearly,
if
. Otherwise, the codebreaker guesses
By the information we obtain that . We further know that every open color has a wrong position in . For that reason, implies that .
Algorithm 2: Routine findNext |
|
The binary search for the exact value of
m is done in the interval
, where
m is initialized as
n and
as
(lines 11 to 16 of
findNext). In order to determine if there is an open correct component on the left side of the current center
ℓ of
in
, we can define a case dependent permutation:
In the first case, the first components of coincide with those of . The remaining components of cannot coincide with the corresponding components of the secret code if they have not been fixed yet. This is because the ℓ-th component of has the already fixed value c, components to coincide with the corresponding components of , which satisfies and the remaining components have been checked to be wrong in this case (cf. former definition of in line 5 and line 9, respectively). Thus, there is a correct open component on the left side of ℓ in , if and only if . In the second case, the same holds for similar arguments. Now, if there is a correct open component to the left of ℓ, we update the binary search interval by . Otherwise, we update by .
The Main Algorithm. The main algorithm is outlined as Algorithm 3. It starts with an empty partial solution and finds the components of the secret code y one-by-one. Herein, the vector v does keep records about the number of open components in which the permutations equal y and is, thus, initialized by , and . As mentioned above, the main loop always requires an active index. For that reason, if in the beginning, we fix one solution peg in and update x and v, correspondingly. Every call of findNext in the main loop augments x by a correct solution value. Since one call of findNext requires at most guesses, Algorithm 3 does not need more than queries for (inclusive initial guesses, guesses to find the first correct peg, calls of findNext and 2 final queries) to break the secret code.
Algorithm 3: Algorithm for Permutations |
|
Example 1. We consider the case and suppose that the secret code y is Figure 1 (upper panel) shows
n possible initial queries. We illustrate the procedure
findNext and further suppose that we have already identified the positions of three colors indicated in the partial solution
x:
From the
values in
Figure 1, we see that
and
, so we choose 3 as our active index applying
findNext with the highlighted initial queries,
and
. Choosing the already identified color 2 as a pivot color,
findNext does its binary search to identify the next correct peg as demonstrated in the lower panel of
Figure 1. Since the information
for query
is 0 (cf. lines 7–9 of Algorithm 2), all correctly placed but unidentified pegs in
are in the first four places. Thus, we can apply a binary search for the leftmost correct peg in the first four places of query
using the pivot peg. Here, the binary search is done by queries
and
and identifies the peg with color 7 (in general, the peg that is left to the leftmost pivot position for which
is non-zero). If the response to
would have been greater than 0, we would have found analogously a new correct peg among the last four places of
.