Skip to content

Instantly share code, notes, and snippets.

@itarato
Created December 29, 2014 15:09
Show Gist options
  • Save itarato/04c9d2850513ff43eb87 to your computer and use it in GitHub Desktop.
Save itarato/04c9d2850513ff43eb87 to your computer and use it in GitHub Desktop.
Sudoku maps - all, sorted
#include <iostream>
#include <vector>
#include <cmath>
#define SUDOKU_SIZE 9
#define COORD_2_IDX(a, b) (SUDOKU_SIZE * a + b)
#define IDX_2_COORD_I(a) (floor(a / SUDOKU_SIZE))
#define IDX_2_COORD_J(a) (a % SUDOKU_SIZE)
using namespace std;
typedef int value_type;
typedef vector<value_type> map_type;
class SudokuMap {
public:
SudokuMap () : map{map_type(pow(SUDOKU_SIZE, 2))} { };
value_type getIJ(int i, int j);
value_type getIJ(int idx);
void setIJ(int i, int j, value_type value);
void setIJ(int idx, value_type value);
void solve();
friend ostream& operator<<(ostream& os, const SudokuMap& s);
private:
map_type map;
bool isValid();
};
value_type SudokuMap::getIJ(int i, int j) {
return map[COORD_2_IDX(i, j)];
}
value_type SudokuMap::getIJ(int idx) {
return map[idx];
}
void SudokuMap::setIJ(int i, int j, value_type value) {
map[COORD_2_IDX(i, j)] = value;
}
void SudokuMap::setIJ(int idx, value_type value) {
map[idx] = value;
}
bool SudokuMap::isValid() {
int blockPosMap[] = {
0, 3, 6,
27, 30, 33,
54, 57, 60
};
int blockInnerMap[] = {
0, 1, 2,
9, 10, 11,
18, 19, 20
};
for (int i = 0; i < SUDOKU_SIZE; i++) {
bool colFlag[SUDOKU_SIZE + 1] = {};
bool rowFlag[SUDOKU_SIZE + 1] = {};
bool blockFlag[SUDOKU_SIZE + 1] = {};
for (int j = 0; j < SUDOKU_SIZE; j++) {
value_type colVal = getIJ(j, i);
if (colVal > 0 && colFlag[colVal]) {
return false;
}
colFlag[colVal] = true;
value_type rowVal = getIJ(i, j);
if (rowVal > 0 && rowFlag[rowVal]) {
return false;
}
rowFlag[rowVal] = true;
value_type blockVal = getIJ(blockPosMap[i] + blockInnerMap[j]);
if (blockVal > 0 && blockFlag[blockVal]) {
return false;
}
blockFlag[blockVal] = true;
}
}
return true;
}
void SudokuMap::solve() {
int valPointer = 0;
while (true) {
// Before first -> end of search.
if (valPointer < 0) {
return;
}
// After last -> found a solution.
if (valPointer >= pow(SUDOKU_SIZE, 2)) {
cout << *this;
valPointer--;
continue;
}
value_type current = getIJ(valPointer);
value_type new_value = current + 1;
do {
setIJ(valPointer, new_value);
} while(!isValid() && ++new_value <= SUDOKU_SIZE);
if (new_value > SUDOKU_SIZE) {
setIJ(valPointer, 0);
valPointer--;
} else {
valPointer++;
}
}
}
ostream& operator<<(ostream& os, const SudokuMap& s) {
for (int i = 0; i < SUDOKU_SIZE; i++) {
for (int j = 0; j < SUDOKU_SIZE; j++) {
os << s.map[COORD_2_IDX(i, j)] << " ";
if (j % 3 == 2) {
os << ' ';
}
}
os << '\n';
if (i % 3 == 2) {
os << '\n';
}
}
return os << '\n';
};
int main(int argc, const char * argv[]) {
SudokuMap s;
s.solve();
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment