Created
April 28, 2017 19:00
-
-
Save LiSongMWO/145f1d89bcee571b16e38d90c9c9008e to your computer and use it in GitHub Desktop.
Eight queens
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 <array> | |
#include <atomic> | |
#include <chrono> | |
#include <cstdint> | |
#include <iostream> | |
#include <set> | |
#include <unordered_set> | |
#include <vector> | |
constexpr int GRID_SIZE = 15; | |
class board; | |
int solc = 0; | |
int rowmasks[GRID_SIZE]; | |
int rowmasks_inv[GRID_SIZE]; | |
void make_masks() { | |
for (int i = 0; i < GRID_SIZE; ++i) { | |
rowmasks[i] = (1 << i); | |
rowmasks_inv[i] = ~(1 << i); | |
} | |
} | |
struct column { | |
int queen_row = -1; | |
int allowed = 0xffffffff; | |
void remove_allowed(int row) { | |
if (row < 0 || row >= GRID_SIZE) | |
return; | |
allowed &= rowmasks_inv[row]; /*~(1 << row);*/ | |
} | |
bool is_allowed(int row) { return allowed & rowmasks[row]; /*(1 << row);*/ } | |
}; | |
class board { | |
std::array<column, GRID_SIZE> cols; | |
size_t next_col = 0; | |
public: | |
void place_queen(int row) { | |
for (int c = next_col + 1; c < GRID_SIZE; ++c) { | |
cols[c].remove_allowed(row + (c - next_col)); | |
cols[c].remove_allowed(row - (c - next_col)); | |
cols[c].remove_allowed(row); | |
} | |
cols[next_col].queen_row = row; | |
next_col++; | |
} | |
void solve() { | |
if (next_col == GRID_SIZE) { | |
solc++; | |
} else { | |
for (int row = 0; row < GRID_SIZE; ++row) { | |
if (cols[next_col].is_allowed(row)) { | |
auto copy = *this; | |
copy.place_queen(row); | |
copy.solve(); | |
} | |
} | |
} | |
} | |
}; | |
int main() { | |
make_masks(); | |
int k = 1; | |
std::atomic_thread_fence(std::memory_order_seq_cst); | |
auto start = std::chrono::high_resolution_clock::now(); | |
for (int i = 0; i < k; ++i) { | |
board b; | |
b.solve(); | |
} | |
auto diff = std::chrono::high_resolution_clock::now() - start; | |
std::atomic_thread_fence(std::memory_order_seq_cst); | |
std::cout << (std::chrono::duration<double, std::milli>(diff).count() / k) | |
<< " us\n"; | |
std::cout << solc << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment