From 3a8916e0fc46db245c030a3b1038b5d0eaecf414 Mon Sep 17 00:00:00 2001 From: Aleksey Lobanov Date: Thu, 19 Apr 2018 15:58:19 +0300 Subject: [PATCH] Finite function moved to another file --- finite_function.hpp | 164 +++++++++++++++++++++++++++++++++++++++++++ main.cpp | 165 ++------------------------------------------ 2 files changed, 169 insertions(+), 160 deletions(-) create mode 100644 finite_function.hpp diff --git a/finite_function.hpp b/finite_function.hpp new file mode 100644 index 0000000..e24744f --- /dev/null +++ b/finite_function.hpp @@ -0,0 +1,164 @@ +#include +#include +#include + +typedef int8_t CellType; + +// Пока положим, что только два аргумента, чтобы упростить реализацию +template +class FiniteFunction { + public: + FiniteFunction() {} + + // Устанавливает результат функции, использую другую функцию как + // инициализатор + template + FiniteFunction(Callable initer) : _num(0) { + for (CellType first = 0; first < BASE; ++first) + for (CellType second = 0; second < BASE; ++second) { + auto inited_result = initer(first, second); + set_result(first, second, inited_result); + } + update_num(); + } + + explicit FiniteFunction(std::string text_repr) { + size_t cur_ind = 0; + for (auto ch: text_repr) { + if ( !isdigit(ch) ) + continue; + _results.at(cur_ind) = std::stoi(std::string(1, ch)); + ++cur_ind; + } + update_num(); + } + ~FiniteFunction() {} + + // Устанавливает результат функции по двум аргументам + void set_result(CellType first, CellType second, CellType result) { + _results[get_index(first, second)] = result; + } + + int operator() (CellType first, CellType second) const { + return _results[get_index(first, second)]; + } + + bool operator < (const FiniteFunction &f) const { + return _num < f._num; + } + + bool operator == (const FiniteFunction &f) const { + return _num == f._num; + } + + FiniteFunction reversed() const { + // f(x,y) -> f(y,x) + FiniteFunction res; + for (CellType first = 0; first < BASE; ++first) + for (CellType second = 0; second < BASE; ++second) { + res.set_result(first, second, (*this)(second, first)); + } + res.update_num(); + return res; + } + + FiniteFunction equaled() const { + // f(x,y) -> f(x,x) + FiniteFunction res; + for (CellType first = 0; first < BASE; ++first) + for (CellType second = 0; second < BASE; ++second) { + res.set_result(first, second, (*this)(first, first)); + } + res.update_num(); + return res; + } + + FiniteFunction apply_to_first_partial(const FiniteFunction &g) const { + // -> this(g(x,y), x) + FiniteFunction res; + for (CellType first = 0; first < BASE; ++first) + for (CellType second = 0; second < BASE; ++second) { + res.set_result(first, second, (*this)(g(first, second), first)); + } + res.update_num(); + return res; + } + + std::tuple apply_to_first(const FiniteFunction &g) const { + // -> this(g(x,y), x), this(g(x,y), y) + FiniteFunction res_1, res_2; + for (CellType first = 0; first < BASE; ++first) + for (CellType second = 0; second < BASE; ++second) { + res_1.set_result(first, second, (*this)(g(first, second), first)); + res_2.set_result(first, second, (*this)(g(first, second), second)); + } + res_1.update_num(); + res_2.update_num(); + return std::make_tuple(res_1, res_2); + } + + FiniteFunction apply_two(const FiniteFunction &g, const FiniteFunction &h) const { + FiniteFunction res; + for (CellType first = 0; first < BASE; ++first) + for (CellType second = 0; second < BASE; ++second) { + res.set_result( + first, + second, + (*this)(g(first, second), h(first, second)) + ); + } + res.update_num(); + return res; + } + + FiniteFunction apply_permutation(std::array perm) const { + FiniteFunction res; + for (CellType first = 0; first < BASE; ++first) + for (CellType second = 0; second < BASE; ++second) { + res.set_result( + first, + second, + std::find( + perm.begin(), + perm.end(), + (*this)(perm[first], perm[second]) + ) - perm.begin() + ); + } + res.update_num(); + return res; + } + + uint32_t get_hash() const { + return _num; + } + + static size_t get_index(CellType first, CellType second) { + return first * BASE + second; + } + template + friend std::ostream& operator << (std::ostream& os, const FiniteFunction<_BASE> &f); + private: + void update_num() { + _num = 0; + for (auto&& val: _results) { + _num *= BASE; + _num += val; + } + } + uint32_t _num; + std::array _results; +}; + + +template +std::ostream& operator << (std::ostream& os, const FiniteFunction &f){ + for (int first = 0; first < BASE; ++first) { + for (int second = 0; second < BASE; ++second) { + os << f(first, second); + } + if ( first != BASE-1 ) + os << " "; + } + return os; +} diff --git a/main.cpp b/main.cpp index f250b0d..48c731d 100644 --- a/main.cpp +++ b/main.cpp @@ -12,171 +12,16 @@ #include #include + +#include "finite_function.hpp" + using namespace std; -typedef int8_t CellType; + + const CellType CUR_BASE = 3; const int ARGS_COUNT = 2; -// Пока положим, что только два аргумента, чтобы упростить реализацию -template -class FiniteFunction { - public: - FiniteFunction() {} - - // Устанавливает результат функции, использую другую функцию как - // инициализатор - template - FiniteFunction(Callable initer) : _num(0) { - for (CellType first = 0; first < BASE; ++first) - for (CellType second = 0; second < BASE; ++second) { - auto inited_result = initer(first, second); - set_result(first, second, inited_result); - } - update_num(); - } - - explicit FiniteFunction(string text_repr) { - size_t cur_ind = 0; - for (auto ch: text_repr) { - if ( !isdigit(ch) ) - continue; - _results.at(cur_ind) = stoi(string(1, ch)); - ++cur_ind; - } - update_num(); - } - ~FiniteFunction() {} - - // Устанавливает результат функции по двум аргументам - void set_result(CellType first, CellType second, CellType result) { - _results[get_index(first, second)] = result; - } - - int operator() (CellType first, CellType second) const { - return _results[get_index(first, second)]; - } - - bool operator < (const FiniteFunction &f) const { - return _num < f._num; - } - - bool operator == (const FiniteFunction &f) const { - return _num == f._num; - } - - FiniteFunction reversed() const { - // f(x,y) -> f(y,x) - FiniteFunction res; - for (CellType first = 0; first < BASE; ++first) - for (CellType second = 0; second < BASE; ++second) { - res.set_result(first, second, (*this)(second, first)); - } - res.update_num(); - return res; - } - - FiniteFunction equaled() const { - // f(x,y) -> f(x,x) - FiniteFunction res; - for (CellType first = 0; first < BASE; ++first) - for (CellType second = 0; second < BASE; ++second) { - res.set_result(first, second, (*this)(first, first)); - } - res.update_num(); - return res; - } - - FiniteFunction apply_to_first_partial(const FiniteFunction &g) const { - // -> this(g(x,y), x) - FiniteFunction res; - for (CellType first = 0; first < BASE; ++first) - for (CellType second = 0; second < BASE; ++second) { - res.set_result(first, second, (*this)(g(first, second), first)); - } - res.update_num(); - return res; - } - - tuple apply_to_first(const FiniteFunction &g) const { - // -> this(g(x,y), x), this(g(x,y), y) - FiniteFunction res_1, res_2; - for (CellType first = 0; first < BASE; ++first) - for (CellType second = 0; second < BASE; ++second) { - res_1.set_result(first, second, (*this)(g(first, second), first)); - res_2.set_result(first, second, (*this)(g(first, second), second)); - } - res_1.update_num(); - res_2.update_num(); - return make_tuple(res_1, res_2); - } - - FiniteFunction apply_two(const FiniteFunction &g, const FiniteFunction &h) const { - FiniteFunction res; - for (CellType first = 0; first < BASE; ++first) - for (CellType second = 0; second < BASE; ++second) { - res.set_result( - first, - second, - (*this)(g(first, second), h(first, second)) - ); - } - res.update_num(); - return res; - } - - FiniteFunction apply_permutation(array perm) const { - FiniteFunction res; - for (CellType first = 0; first < BASE; ++first) - for (CellType second = 0; second < BASE; ++second) { - res.set_result( - first, - second, - find( - perm.begin(), - perm.end(), - (*this)(perm[first], perm[second]) - ) - perm.begin() - ); - } - res.update_num(); - return res; - } - - uint32_t get_hash() const { - return _num; - } - - static size_t get_index(CellType first, CellType second) { - return first * BASE + second; - } - template - friend ostream& operator << (ostream& os, const FiniteFunction<_BASE> &f); - private: - void update_num() { - _num = 0; - for (auto&& val: _results) { - _num *= BASE; - _num += val; - } - } - uint32_t _num; - array _results; -}; - - -template -ostream& operator << (ostream& os, const FiniteFunction &f){ - for (int first = 0; first < BASE; ++first) { - for (int second = 0; second < BASE; ++second) { - os << f(first, second); - } - if ( first != BASE-1 ) - os << " "; - } - return os; -} - template class FixedIniter { public: