jeudi 23 mai 2013

Mastermind : build the k-combination of n colors(with repetitions)

In my 'Mastermind serie', I wrote a small C++ code that i would template later to create the list of the 4-combination of 6 peg (with repetitions) as we already know that for the classic mastermind game:
  • we have 6 colors,
  • the code is 4 peg long,
  • so the total number of combination is 6^4 = 1296

To build that list, I apply the recursion/induction method and obtain finally a short and cool code :)
 Recall that our colors are describe by letters from 'A' to 'F'.


const color_code_map_t color_code = map_list_of (color_e::white, 'A')(color_e::blue, 'B')(color_e::green, 'C')(color_e::yellow, 'D')(color_e::orange, 'E')(color_e::red, 'F') ;


I build the list through the following code:

vector<char> elements;
std::for_each(color_code.begin(), color_code.end(), [&elements](const color_code_map_t::value_type& p) { elements.push_back(p.second); });
auto combi_found = combinations_with_repetitions(elements, TheHiddenCode.size());
std::cout << "total combination you can try = " << combi_found.size() << std::endl;



and in the 2 following function, I use the recursion/induction approach:


void combinations_with_repetitions_recursion(deque< vector<char> >& combi, const vector<char> &elems,
unsigned long req_len,
vector<unsigned long> &pos,
unsigned long depth)
{
// Have we selected the number of required elements?
if (depth >= req_len) {
vector<char> depth_r_combi;
for (unsigned long ii = 0; ii < pos.size(); ++ii){
depth_r_combi += elems[pos[ii]];
}
//copy(depth_r_combi.begin(), depth_r_combi.end(), ostream_iterator<char>(cout, " ")), cout << endl;
combi.push_back(depth_r_combi);
return;
}

// Try to select new elements to the right of the last selected one.
for (unsigned long ii = 0; ii < elems.size(); ++ii) {
pos[depth] = ii;
combinations_with_repetitions_recursion(combi, elems, req_len, pos, depth + 1);
}
return;
}

deque<vector<char>> combinations_with_repetitions(const vector<char> &elems, unsigned long r)
{
if(r > elems.size()){
throw std::logic_error("combination length (r) cannot be greater than the elements list (n)");
}

vector<unsigned long> positions(r, 0);
deque<vector<char>> combi;
combinations_with_repetitions_recursion(combi, elems, r, positions, 0);

return combi;
}


the 'depth' parameters is the key to stop the recursion and drill-up all the results. Based on those function we can easily create function to build permutations, combination(without repetitions), and ....

Aucun commentaire :

Enregistrer un commentaire