11/26/2013

Kakuro Solver - how to create database of solution sets

I created the database of solution sets programatically. I used the code below to enumerate {number of cells, clue} pairs:
 
typedef std::bitset<9> valueSet_t;
typedef std::list<valueSet_t> result_t;

const unsigned NumToBit[] = {
 0, 1, 2, 4, 8, 16, 32, 64, 128, 256,
};

void iterLevel(size_t begin, size_t level, size_t sum, valueSet_t & set, result_t & result)
{
 if(sum < begin)
  return;

 if(--level == 0) {
  if(sum <= 9) {
   set |= NumToBit[sum];
   result.push_back(set);
   set &= ~NumToBit[sum];
  }
  return;
 }

 for(size_t i = begin; i <= 9; i++) {
  set |= NumToBit[i];
  iterLevel(i + 1, level, sum - i, set, result);
  set &= ~NumToBit[i];
 }
}


void kakkuroSums()
{
 valueSet_t set;
 result_t result;
 for(size_t level = 2; level <= 9; level++) {
  for(size_t sum = 3; sum <= 45; sum++) {
   set.reset();
   result.clear();
   iterLevel(1, level, sum, set, result);

   if(result.size() > 0) {
    // generate the database here
  }
 }

}
The idea is, when I calculate solution sets for an entry with 5 white cells, call iterLevel() recursively 5 times. Each call picks up a solution value for a white cell.
For example, assume we want to find solution sets for 13-in-three. The first call of iterLevel() picks up "1" as a solution value. The second call picks up "2". The last call finds a set {1, 2, 10} but this is not a valid set, so just returns. Back to the second call, it picks up "3" next. The last call finds a set {1, 3, 9} and this is valid, so remember the result and returns. And so on.

But after I made the database, I realized that I could find all solution sets by simply finding all combinations of 1 through 9. And it is easy to get all the combinations by checking values from 3 to 511.
For example, 3 - 0b11 in binary. If you interprete the least bit as "1" and the second least bit as "2", 3 is interpreted as a solution set {1, 2} for 3-in-two. 4 has only one bit set, so skip it. 5 is interpreted as  {1, 3}. 6 as {2, 3}, 7 as {1, 2, 3}, and so on.
The result is not sorted, so you need to sort it in the order you want but it looks faster than what I actually did.

No comments:

Post a Comment