Advertisement
Guest User

kekeke

a guest
Feb 17th, 2020
96
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.49 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <functional>
  4. #include <limits>
  5. #include <queue>
  6. #include <stdexcept>
  7. #include <string>
  8. #include <unordered_map>
  9. #include <utility>
  10. #include <variant>
  11. #include <any>
  12. #include "match_syntax.hpp"
  13. #include "scl/traits.hpp"
  14.  
  15. static std::array keyboard_array = {
  16.     std::array { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' },
  17.     std::array { 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P' },
  18.     std::array { 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ';' },
  19.     std::array { 'Z', 'X', 'C', 'V', 'B', 'N', 'M', ',', '.', '/' }
  20. };
  21.  
  22. inline auto get_keyboard_pos(char symbol) {
  23.     static std::array<std::pair<size_t, size_t>, 256> map = []() {
  24.         std::array<std::pair<size_t, size_t>, 256> result;
  25.  
  26.         std::fill(result.begin(), result.end(),
  27.                 std::pair{std::numeric_limits<size_t>::max(),
  28.                           std::numeric_limits<size_t>::max()});
  29.  
  30.         for (size_t i = 0; i < keyboard_array.size(); ++i)
  31.             for (size_t j = 0; j < keyboard_array[i].size(); ++j)
  32.                 result[keyboard_array[i][j]] = std::pair{i, j};
  33.  
  34.         return result;
  35.     }();
  36.  
  37.     if (symbol >= 'a' && symbol <= 'z')
  38.         symbol += 'A' - 'a';
  39.  
  40.     return map[symbol];
  41. }
  42.  
  43. inline ssize_t abs(ssize_t n) {
  44.     return n < 0 ? -n : n;
  45. }
  46.  
  47. size_t estimate_char(char target, char actual) {
  48.     auto [ti, tj] = get_keyboard_pos(target);
  49.     auto [ai, aj] = get_keyboard_pos(actual);
  50.  
  51.     return size_t(abs(ssize_t(ti) - ssize_t(ai)) + abs(ssize_t(tj) - ssize_t(aj)));
  52. }
  53.  
  54. template <typename IterT1, typename IterT2>
  55. size_t estimate_region(IterT1 t, IterT2 a, size_t count) {
  56.     size_t cost = 0;
  57.  
  58.     for (size_t i = 0; i < count; ++i)
  59.         cost += estimate_char(*(t + i), *(a + i));
  60.  
  61.     return cost;
  62. }
  63.  
  64. template <typename StrT1, typename StrT2>
  65. size_t estimate_string(const StrT1& target, const StrT2& actual) {
  66.     size_t diff_symbols_cost = 4;
  67.     size_t cost = 0;
  68.  
  69.     size_t min = target.size(), max = actual.size();
  70.     if (min > max)
  71.         std::swap(min, max);
  72.  
  73.     cost += (max - min) * diff_symbols_cost;
  74.  
  75.     for (size_t ti = 0, ai = 0; ti < target.size() && ai < actual.size(); ++ti, ++ai) {
  76.         if (ai != actual.size() - 1 && estimate_char(target[ti], actual[ai]) > 1) {
  77.             auto cur_cost   = estimate_region(target.begin() + ti, actual.begin() + ai, min - ti);
  78.             auto shift_cost = estimate_region(target.begin() + ti, actual.begin() + ai + 1, min - ti);
  79.  
  80.             if (cur_cost > shift_cost) {
  81.                 ++ai;
  82.                 cost -= diff_symbols_cost - 1;
  83.             }
  84.         }
  85.  
  86.         cost += estimate_char(target[ti], actual[ai]);
  87.     }
  88.  
  89.     return cost;
  90. }
  91.  
  92. template <typename IterT>
  93. void keyboard_sort(IterT begin, IterT end, const std::string& target) {
  94.     std::stable_sort(begin, end, [&](const auto& lhs, const auto& rhs) {
  95.         return estimate_string(target, lhs) < estimate_string(target, rhs);
  96.     });
  97. }
  98.  
  99.  
  100. template <typename T, typename AllocT = std::allocator<T>>
  101. class HeapyVector : public std::vector<T, AllocT> {
  102. public:
  103.     template <typename FunctionT>
  104.     HeapyVector(FunctionT&& comparator): _comparator(std::forward<FunctionT>(comparator)) {}
  105.  
  106.     template <typename V>
  107.     void push(V&& value) {
  108.         this->push_back(std::forward<T>(value));
  109.         std::push_heap(this->begin(), this->end(), _comparator);
  110.     }
  111.  
  112.     auto get_sorted(size_t count = std::numeric_limits<size_t>::max()) {
  113.         if (count > this->size())
  114.             count = this->size();
  115.  
  116.         std::vector<T, AllocT> result;
  117.         result.reserve(count);
  118.  
  119.         std::vector<T, AllocT> tmp = *this;
  120.  
  121.         while (count--)
  122.             result.emplace_back(pop());
  123.  
  124.         std::swap(tmp, *this);
  125.  
  126.         return result;
  127.     }
  128.  
  129.     void make_heap() {
  130.         std::make_heap(this->begin(), this->end(), _comparator);
  131.     }
  132.  
  133.     T pop() {
  134.         std::pop_heap(this->begin(), this->end(), _comparator);
  135.        
  136.         auto result = std::move(this->back());
  137.         this->pop_back();
  138.  
  139.         return result;
  140.     }
  141.  
  142.     T& top() {
  143.         return this->front();
  144.     }
  145.  
  146.     const T& top() const {
  147.         return this->front();
  148.     }
  149.  
  150. private:
  151.     std::function<bool(const T& lhs, const T& rhs)> _comparator;
  152. };
  153.  
  154.  
  155. class StringSimilarityVector : public HeapyVector<std::string> {
  156. public:
  157.     StringSimilarityVector(const std::string& target):
  158.         HeapyVector<std::string>([target](const auto& lhs, const auto& rhs) {
  159.             return estimate_string(target, lhs) >= estimate_string(target, rhs); }) {};
  160. };
  161.  
  162.  
  163. class CommandArgsBadCast : public std::exception {
  164. public:
  165.     explicit CommandArgsBadCast(std::string error): msg(std::move(error)) {}
  166.     const char* what() const noexcept override { return msg.data(); }
  167.  
  168. private:
  169.     std::string msg;
  170. };
  171.  
  172.  
  173. class CommandArgsInvalidCount : public std::exception {
  174. public:
  175.     explicit CommandArgsInvalidCount(std::string error): msg(std::move(error)) {}
  176.     const char* what() const noexcept override { return msg.data(); }
  177.  
  178. private:
  179.     std::string msg;
  180. };
  181.  
  182.  
  183. class CommandArg {
  184. public:
  185.     CommandArg(const std::string& str) {
  186.         nma::match(str,
  187.             "true"  doo { var = true;  },
  188.             "on"    doo { var = true;  },
  189.             "false" doo { var = false; },
  190.             "off"   doo { var = false; },
  191.             condx(true) doo {
  192.                 try {
  193.                     var = std::stod(str);
  194.                 } catch (const std::exception& e) {
  195.                     var = str;
  196.                 }
  197.             });
  198.     }
  199.  
  200.     bool asBool() const {
  201.         return nma::match(var,
  202.             [](bool v) { return v; },
  203.             [](auto)   { throw CommandArgsBadCast("Argument not a Bool"); return false; } );
  204.     }
  205.  
  206.     double asNumber() const {
  207.         return nma::match(var,
  208.             [](double v) { return v; },
  209.             [](auto)     { throw CommandArgsBadCast("Argument not a Double"); return 0.0; } );
  210.     }
  211.  
  212.     std::string asString() const {
  213.         return nma::match(var,
  214.             [](bool v)        { return std::string(v ? "true" : "false"); },
  215.             [](double v)      { return std::to_string(v); },
  216.             [](const auto& v) { return std::string(v); });
  217.     }
  218.  
  219. private:
  220.     std::variant<double, std::string, bool> var;
  221. };
  222.  
  223.  
  224. class AnyCommand {
  225. public:
  226.     template <typename T>
  227.     static auto wrap_command_arg(const CommandArg& arg)
  228.     -> std::enable_if_t<std::is_floating_point_v<T> || std::is_integral_v<T>, T> {
  229.         return T(arg.asNumber());
  230.     }
  231.  
  232.     template <typename T>
  233.     static auto wrap_command_arg(const CommandArg& arg)
  234.     -> std::enable_if_t<std::is_same_v<std::string, std::decay_t<T>>, std::string> {
  235.         return arg.asString();
  236.     }
  237.  
  238.     template <typename T>
  239.     static auto wrap_command_arg(const CommandArg& arg)
  240.     -> std::enable_if_t<std::is_same_v<bool, std::decay_t<T>>, bool> {
  241.         return arg.asBool();
  242.     }
  243.  
  244.     template <typename T, size_t>
  245.     using WrapTypeSequence = T;
  246.  
  247.     template <typename F, size_t... _ArgsCount>
  248.     static auto generate_wrapper(F function, std::index_sequence<_ArgsCount...>&&) {
  249.         return std::function{[=](const WrapTypeSequence<CommandArg, _ArgsCount>&... args) {
  250.             function(wrap_command_arg<scl::arg_type_of_t<F, _ArgsCount>>(args)...);
  251.         }};
  252.     }
  253.    
  254.     template <typename FunctionT>
  255.     AnyCommand(FunctionT function):
  256.         _f(generate_wrapper(function, std::make_index_sequence<scl::args_count_of_v<FunctionT>>())) {}
  257.    
  258.     template <size_t... _Idxs>
  259.     void _call(const std::vector<CommandArg>& args, std::index_sequence<_Idxs...>&&) {
  260.         auto f = std::any_cast<const std::function<void(const decltype(args[_Idxs])&...)>>(_f);
  261.         f(args[_Idxs]...);
  262.     }
  263.  
  264.     template <size_t _ArgsMax = 16, size_t _ArgCounter = 0>
  265.     void call(const std::vector<CommandArg>& args) {
  266.         if constexpr (_ArgCounter == _ArgsMax)
  267.             return;
  268.         else {
  269.             if (_ArgCounter == args.size()) {
  270.                 try {
  271.                     _call(args, std::make_index_sequence<_ArgCounter>());
  272.                 } catch (const std::bad_any_cast&) {
  273.                     throw CommandArgsInvalidCount("Invalid arguments count");
  274.                 }
  275.             }
  276.  
  277.             call<_ArgsMax, _ArgCounter + 1>(args);
  278.         }
  279.     }
  280.  
  281. private:
  282.     std::any _f;
  283. };
  284.  
  285.  
  286.  
  287. class CommandMgr {
  288. public:
  289.     template <typename F>
  290.     void add(const std::string& name, F function) {
  291.         _commands.emplace(name, function);
  292.     }
  293.  
  294.     void exec(const std::string& command) {
  295.     }
  296.  
  297. private:
  298.     std::unordered_map<std::string, AnyCommand> _commands;
  299. };
  300.  
  301.  
  302. std::ostream& operator<< (std::ostream& os, const std::vector<std::string>& vec) {
  303.     for (auto& e : vec)
  304.         std::cout << e << " ";
  305.     return os;
  306. }
  307.  
  308.  
  309.  
  310. void hello(const std::string& name, int number) {
  311.     std::cout << "Hello, " << name << " " << number << std::endl;
  312. }
  313.  
  314.  
  315.  
  316. int main() {
  317.     auto cmd = AnyCommand(hello);
  318.  
  319.     cmd.call({CommandArg("pidor"), CommandArg("9")});
  320.  
  321.     //std::vector<std::string> strs = {"ypdatw", "uppdate", "h[date", "ipfaate", "updatw", "upppdate"};
  322.    
  323.     //StringSimilarityVector sorter("update");
  324.     //for (auto& s : strs)
  325.     //    sorter.push(s);
  326.  
  327.     //std::vector<std::string> strs = { "uppdate", "update" };
  328.     //keyboard_sort(strs.begin(), strs.end(), "update");
  329.  
  330.     //std::cout << sorter.get_sorted() << "\n" << sorter.get_sorted(4) << std::endl;
  331.     return 0;
  332. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement