Skip to content

Instantly share code, notes, and snippets.

@adrian17
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adrian17/be20590be73ae30a5d1d to your computer and use it in GitHub Desktop.
Save adrian17/be20590be73ae30a5d1d to your computer and use it in GitHub Desktop.
EdgeSolver with templates
#include <iostream>
#include <vector>
#include <string>
#include <array>
#include <fstream>
using std::cout;
using std::endl;
typedef std::vector<std::array<char, 4>> Board;
void fastswap(Board::iterator it1, Board::iterator it2){
std::swap(*(int*)it1->data(), *(int*)it2->data());
}
void fastrot(Board::iterator it) {
static_assert(sizeof(int) == 4, "rotation will not work");
int &val = *(int*)it->data();
val = (val << 8) | (val >> ((sizeof(int) * 8 - 8)));
}
template<int size>
bool checkLeftEdge(Board::iterator begin, Board::iterator right){
if ((right - begin) % size == 0)
return true;
auto left = right - 1;
char c1 = (*right)[3], c2 = (*left)[1];
return c1 - 32 == c2 || c1 == c2 - 32;
}
template<int size>
bool checkTopEdge(Board::iterator begin, Board::iterator bottom){
if (bottom < begin + size)
return true;
auto top = bottom - size;
char c1 = (*bottom)[0], c2 = (*top)[2];
return c1 - 32 == c2 || c1 == c2 - 32;
}
template<int size>
inline bool isLastElementValid(Board::iterator begin, Board::iterator last){
return
checkTopEdge<size>(begin, last) &&
checkLeftEdge<size>(begin, last);
}
template<int size>
bool recurse(Board::iterator begin, Board::iterator end, Board::iterator len){
if (len == end)
return true;
for (auto it = len; it != end; ++it){
fastswap(len, it);
for (int j = 0; j < 4; ++j){
if (isLastElementValid<size>(begin, len)){
bool success = recurse<size>(begin, end, len + 1);
if (success)
return true;
}
fastrot(len);
}
fastswap(len, it);
}
return false;
}
int to_index(int x, int y, int size){ return y * size + x; }
void draw(const Board &board, int size){
for (int y = 0; y < size; ++y){
cout << std::string(size * 4 + 1, '-') << endl;
for (int x = 0; x < size; ++x)
cout << "| " << board[to_index(x, y, size)][0] << " ";
cout << "|" << endl;
for (int x = 0; x < size; ++x)
cout << "|" << board[to_index(x, y, size)][3] << " " << board[to_index(x, y, size)][1];
cout << "|" << endl;
for (int x = 0; x < size; ++x)
cout << "| " << board[to_index(x, y, size)][2] << " ";
cout << "|" << endl;
}
cout << std::string(size * 4 + 1, '-') << endl;
cout << endl;
}
int main(){
std::ifstream in ("in.txt");
if (!in)
return 1;
int size;
in >> size;
Board board(size * size);
for (auto& str : board){
in.ignore();
in.read(str.data(), 4);
}
bool success = false;
if(size == 2) success = recurse<2>(board.begin(), board.end(), board.begin());
else if(size == 3) success = recurse<3>(board.begin(), board.end(), board.begin());
else if(size == 4) success = recurse<4>(board.begin(), board.end(), board.begin());
else if(size == 5) success = recurse<5>(board.begin(), board.end(), board.begin());
if (success)
draw(board, size);
std::cin.ignore();
std::cin.get();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment