Last active
December 16, 2015 04:59
-
-
Save cire3791/5381142 to your computer and use it in GitHub Desktop.
Code exploration based on a discussion at http://www.cplusplus.com/forum/lounge/98939/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include "grid.h" | |
Grid& Grid::flip(std::size_t pos) | |
{ | |
switch(pos) | |
{ | |
case 0: _grid.flip(0).flip(1).flip(3) ; break ; | |
case 1: _grid.flip(0).flip(1).flip(2).flip(4) ; break ; | |
case 2: _grid.flip(1).flip(2).flip(5) ; break ; | |
case 3: _grid.flip(0).flip(3).flip(4).flip(6) ; break ; | |
case 4: _grid.flip(1).flip(3).flip(4).flip(5).flip(7) ; break ; | |
case 5: _grid.flip(2).flip(4).flip(5).flip(8) ; break ; | |
case 6: _grid.flip(3).flip(6).flip(7) ; break ; | |
case 7: _grid.flip(4).flip(6).flip(7).flip(8) ; break ; | |
case 8: _grid.flip(5).flip(7).flip(8) ; break ; | |
} | |
return *this ; | |
} | |
Grid& Grid::invert() | |
{ | |
_grid = ~_grid ; | |
return *this ; | |
} | |
std::ostream& operator<<(std::ostream& os, const Grid& g) | |
{ | |
for ( unsigned i=0; i<3; ++i ) | |
{ | |
for ( unsigned j=0; j<3; ++j ) | |
os << (g[i*3+j] ? '*' : '-') ; | |
os << '\n' ; | |
} | |
return os ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef EMS_GRID_H | |
#define EMS_GRID_H | |
#include <bitset> | |
class Grid | |
{ | |
public: | |
int compare(const Grid & g) const ; | |
Grid& flip(std::size_t pos) ; | |
Grid& invert() ; | |
bool operator[](std::size_t pos) const { return _grid[pos] ; } | |
friend std::ostream& operator<<(std::ostream&, const Grid& g) ; | |
friend struct GridHashFunc ; | |
private: | |
std::bitset<9> _grid ; | |
}; | |
struct GridHashFunc | |
{ | |
std::size_t operator() (const Grid& g) { return g._grid.hash() ; } | |
}; | |
inline int Grid::compare(const Grid& g) const | |
{ | |
return _grid.to_ulong() - g._grid.to_ulong() ; | |
} | |
inline bool operator==(const Grid& a, const Grid& b ) | |
{ | |
return a.compare(b) == 0 ; | |
} | |
inline bool operator<(const Grid& a, const Grid& b) | |
{ | |
return a.compare(b) < 0 ; | |
} | |
#endif | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fstream> | |
#include <vector> | |
#include <unordered_map> | |
#include <functional> | |
#include "grid.h" | |
const size_t squares = 9 ; | |
typedef std::unordered_map<Grid,unsigned,GridHashFunc> SolutionMap ; | |
SolutionMap buildSolutionMap() | |
{ | |
typedef std::vector<Grid> grid_vec ; | |
typedef std::pair<std::size_t, std::size_t> range_element ; | |
typedef std::vector<range_element> range_vec ; | |
SolutionMap gridInfo ; | |
grid_vec grids ; | |
// prime the pump. | |
gridInfo.emplace(Grid(), 0) ; | |
gridInfo.emplace(Grid().invert(), 0) ; | |
grids.push_back(Grid()) ; | |
grids.push_back(Grid().invert()) ; | |
range_vec ranges(1, range_element(0, grids.size())) ; | |
bool done = false ; | |
size_t flips = 0 ; | |
while ( ! done ) | |
{ | |
range_element& range = ranges[flips] ; | |
for ( std::size_t i=range.first; i!= range.second; ++i ) | |
{ | |
for ( std::size_t j = 0; j < squares; ++j ) | |
{ | |
Grid working = grids[i] ; | |
working.flip(j) ; | |
if ( !gridInfo.count(working) ) | |
{ | |
grids.push_back(working) ; | |
gridInfo.emplace(std::make_pair(working, flips+1)) ; | |
} | |
} | |
} | |
if ( range.second == grids.size() ) | |
done = true ; | |
else | |
{ | |
ranges.emplace_back(std::make_pair(range.second, grids.size())) ; | |
++flips ; | |
} | |
} | |
return gridInfo ; | |
} | |
int main() | |
{ | |
SolutionMap solutions = buildSolutionMap() ; | |
std::ofstream out ("solutions.txt") ; | |
out << solutions.size() << '\n' ; | |
for ( auto & solution : solutions ) | |
out << solution.first << solution.second << " flips\n\n" ; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment