To solve a puzzle fast, algorithm is crucial. and the data structure is important to implement the algorithm properly. Here, I am going to explain the data structure I used for the kakuro solver.
Representation of solution sets and possible solutions
Values in solution sets and possible solution values are represented as bits. The least bit in an integer represents the value "1", the 5th least bit represents "5", and so on. This way, you can easily calculate union and intersection by bitwise logic operations.
Actually I used the bitset container of the C++ STL. I would create a custom class for solution sets if it weren't fast enough but it is really fast!
White cells
A white cell has three properties. The first one is possible solution values. The second one is pointers to the two entries which the white cell belongs to. The last one is the position or coordinate in the problem board.
Entries
An entry has four properties. The first one is possible solution values which its white cells can take.
The second one is a list of solution sets. I used an STL list container because
List of white cells without a solution
When you iterate the calculation of possible solution values of white cells, you want to skip white cells which already have a solution. I used a list container to store white cells which don't have a solution yet.
I used a list container because of the same reason as the solution sets for entries.
Database of solution sets for an entry
I need the initial solution sets database for entries to initialize an entry. I could calculate an initial solution sets each time I initialize an entry but apparently it is a waste of time. I store the database in a form of const static variable like:
const static valueSet_t CAND2_3_12(0x3);
const static valueSet_t CAND2_4_13(0x5);
const static valueSet_t CAND2_5_14(0x9);
const static valueSet_t CAND2_5_23(0x6);
Representation of solution sets and possible solutions
Values in solution sets and possible solution values are represented as bits. The least bit in an integer represents the value "1", the 5th least bit represents "5", and so on. This way, you can easily calculate union and intersection by bitwise logic operations.
Actually I used the bitset container of the C++ STL. I would create a custom class for solution sets if it weren't fast enough but it is really fast!
White cells
A white cell has three properties. The first one is possible solution values. The second one is pointers to the two entries which the white cell belongs to. The last one is the position or coordinate in the problem board.
Entries
An entry has four properties. The first one is possible solution values which its white cells can take.
The second one is a list of solution sets. I used an STL list container because
- I don't need random access. I sequentially access the list
- A white cell can be removed from the list in constant time.
List of white cells without a solution
When you iterate the calculation of possible solution values of white cells, you want to skip white cells which already have a solution. I used a list container to store white cells which don't have a solution yet.
I used a list container because of the same reason as the solution sets for entries.
Database of solution sets for an entry
I need the initial solution sets database for entries to initialize an entry. I could calculate an initial solution sets each time I initialize an entry but apparently it is a waste of time. I store the database in a form of const static variable like:
const static valueSet_t CAND2_3_12(0x3);
const static valueSet_t CAND2_4_13(0x5);
const static valueSet_t CAND2_5_14(0x9);
const static valueSet_t CAND2_5_23(0x6);
valueSet_t is a class to represent solution sets in bits; derived from the bitset container.
No comments:
Post a Comment