Files
test/puzzles/training/2048.cpp
2021-11-20 22:47:05 +00:00

244 lines
5.3 KiB
C++

/*
VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}"
VIM: let b:cf5run="{OUT}"
*/
#include <iostream>
#include <exception>
#include <chrono>
#include <vector>
void print(const std::vector<int>& row)
{
for (auto i : row){
std::cout << i << ',';
}
std::cout << std::endl;
}
void print(const std::vector<std::vector<int>>& board)
{
for (const auto& row : board){
for (auto i : row){
std::cout << i << ',';
}
std::cout << std::endl;
}
}
struct OneDimVec
{
using board_t = std::vector<int>;
using iterator_t = int *;
enum {dimentions=1};
static iterator_t begin(board_t& b, int n){
return b.data();
}
static iterator_t end(board_t& b, int n){
return b.data()+b.size();
}
static iterator_t next(iterator_t it){
return it+1;
}
};
struct OneDimVecReverse
{
using board_t = std::vector<int>;
using iterator_t = board_t::reverse_iterator;
enum {dimentions=1};
static iterator_t begin(board_t& b, int n){
return b.rbegin();
}
static iterator_t end(board_t& b, int n){
return b.rend();
}
static iterator_t next(iterator_t it){
return it+1;
}
};
template <typename Traits>
void push(typename Traits::board_t& board, int n)
{
auto q = Traits::begin(board, n);
auto pe = Traits::end(board, n);
for (auto p = Traits::next(q); p != pe; p=Traits::next(p)){
if (*p==0){
continue;
}
else if (*q == 0){
*q+=*p;
*p = 0;
}
else if (*q == *p){
*q+=*p;
*p = 0;
q = Traits::next(q);
}
else {
q = Traits::next(q);
*q = *p;
if (q != p){
*p = 0;
}
}
}
}
template <typename T>
void test(typename T::board_t v){
std::cout << "--------------" << std::endl;
print(v);
if constexpr (T::dimentions == 1){
push<T>(v,0);
} else {
for (int i = 0; i < T::dim_size(v); ++i){
push<T>(v,i);
}
}
std::cout << "-" << std::endl;
print(v);
}
struct BoardTraits
{
using board_t=std::vector<std::vector<int>>;
enum {dimentions=2};
struct iterator_t {
board_t& b;
int i;
int j;
int& operator*(){
return b[i][j];
}
bool operator != (const iterator_t& it){
return i != it.i;
}
iterator_t& operator = (const iterator_t& it){
i=it.i;
j=it.j;
return *this;
}
};
};
struct Up : public BoardTraits
{
static int dim_size(const board_t& b){
return b[0].size();
}
static iterator_t begin(board_t& b, int n){
return {b, 0, n};
}
static iterator_t end(board_t& b, int n){
return {b, int(b.size()), n};
}
static iterator_t next(const iterator_t& it){
return {it.b, it.i+1, it.j};
}
};
struct Down : public BoardTraits
{
static int dim_size(const board_t& b){
return b[0].size();
}
static iterator_t begin(board_t& b, int n){
return {b, int(b.size())-1, n};
}
static iterator_t end(board_t& b, int n){
return {b, -1, n};
}
static iterator_t next(const iterator_t& it){
return {it.b, it.i-1, it.j};
}
};
struct Left : public BoardTraits
{
using iterator_t = std::vector<int>::iterator;
static int dim_size(const board_t& b){
return b.size();
}
static iterator_t begin(board_t& b, int n){
return b[n].begin();
}
static iterator_t end(board_t& b, int n){
return b[n].end();
}
static iterator_t next(const iterator_t& it){
return it+1;
}
};
struct Right : public BoardTraits
{
using iterator_t = std::vector<int>::reverse_iterator;
static int dim_size(const board_t& b){
return b.size();
}
static iterator_t begin(board_t& b, int n){
return b[n].rbegin();
}
static iterator_t end(board_t& b, int n){
return b[n].rend();
}
static iterator_t next(const iterator_t& it){
return it+1;
}
};
int main ( void )
{try{
auto begin = std::chrono::high_resolution_clock::now();
test<OneDimVec>({4, 0, 4, 8});
test<OneDimVecReverse>({4, 0, 4, 8});
std::cout << "test" << std::endl;
//......
test<Left>({
{4, 0, 4, 8},
{2, 0, 2, 8},
{1, 1, 0, 0},
{4, 0, 4, 4}
});
test<Right>({
{4, 0, 4, 8},
{2, 0, 2, 8},
{1, 1, 0, 0},
{4, 0, 4, 4}
});
test<Up>({
{4, 0, 4, 8},
{2, 0, 2, 8},
{1, 1, 0, 0},
{4, 0, 4, 4}
});
test<Down>({
{4, 0, 4, 8},
{2, 0, 2, 8},
{1, 1, 0, 0},
{4, 0, 4, 4}
});
auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> seconds = end - begin;
std::cout << "Time: " << seconds.count() << std::endl;
return 0;
}
catch ( const std::exception& e )
{
std::cerr << std::endl
<< "std::exception(\"" << e.what() << "\")." << std::endl;
return 2;
}
catch ( ... )
{
std::cerr << std::endl
<< "unknown exception." << std::endl;
return 1;
}}