Advertisement
Aliyahu

Untitled

Mar 25th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.06 KB | None | 0 0
  1. #include <iostream>
  2. #include <algorithm>
  3. #include <cmath>
  4. #include <string>
  5. #include <unordered_set>
  6. #include <set>
  7. #include <vector>
  8. #include <queue>
  9. #include <unordered_map>
  10.  
  11. const std::vector <char> answer = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 15 };
  12. const std::vector <char> answer_x = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3 };
  13. const std::vector <char> answer_y = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 };
  14.  
  15. struct Vertex {
  16.     std::vector<char> vertex;
  17.     Vertex(std::vector<char>& v) : vertex(v) {};
  18.     std::vector<std::pair<Vertex, char>> GetNextVertices();
  19.  
  20. private:
  21.     std::pair<Vertex, char> up();
  22.     std::pair<Vertex, char> down();
  23.     std::pair<Vertex, char> left();
  24.     std::pair<Vertex, char> right();
  25.     friend struct std::hash<Vertex>;
  26. };
  27.  
  28. bool operator==(const Vertex &v1, const Vertex &v2) {
  29.     return v1.vertex == v2.vertex;
  30. }
  31.  
  32. bool operator<(const std::pair<int, std::pair<Vertex, std::string>>& v1, const std::pair<int, std::pair<Vertex, std::string>>& v2) {
  33.     return v1.first < v2.first;
  34. }
  35.  
  36. std::pair<Vertex, char> Vertex::up() {
  37.     std::vector <char> v = vertex;
  38.     std::swap(v[v[16]], v[v[16] - 4]);
  39.     v[16] = v[16] - 4;
  40.     Vertex _v(v);
  41.     return std::pair<Vertex, char>(_v, 'D');
  42. }
  43.  
  44. std::pair<Vertex, char> Vertex::down() {
  45.     std::vector <char> v = vertex;
  46.     std::swap(v[v[16]], v[v[16] + 4]);
  47.     v[16] = v[16] + 4;
  48.     Vertex _v(v);
  49.     return std::pair<Vertex, char>(_v, 'U');
  50. }
  51.  
  52. std::pair<Vertex, char> Vertex::left() {
  53.     std::vector <char> v = vertex;
  54.     std::swap(v[v[16]], v[v[16] - 1]);
  55.     v[16] = v[16] - 1;
  56.     Vertex _v(v);
  57.     return std::pair<Vertex, char>(_v, 'R');
  58. }
  59.  
  60. std::pair<Vertex, char> Vertex::right() {
  61.     std::vector <char> v = vertex;
  62.     std::swap(v[v[16]], v[v[16] + 1]);
  63.     v[16] = v[16] + 1;
  64.     Vertex _v(v);
  65.     return std::pair<Vertex, char>(_v, 'L');
  66. }
  67.  
  68. std::vector<std::pair<Vertex, char>> Vertex::GetNextVertices() {
  69.     std::vector<std::pair<Vertex, char>> output;
  70.     if (vertex[16] > 3) {
  71.         output.push_back(up());
  72.     }
  73.     if (vertex[16] < 12) {
  74.         output.push_back(down());
  75.     }
  76.     if (vertex[16] % 4 < 3) {
  77.         output.push_back(right());
  78.     }
  79.     if (vertex[16] % 4 > 0) {
  80.         output.push_back(left());
  81.     }
  82.     return output;
  83. }
  84.  
  85.  
  86. template<>
  87. class std::hash<Vertex> {
  88. public:
  89.     int operator()(const Vertex& _vertex) const noexcept {
  90.         std::string hash;
  91.         for (auto i : _vertex.vertex) {
  92.             hash += i;
  93.         }
  94.         std::hash<std::string> hash_function;
  95.         return hash_function(hash);
  96.     }
  97. };
  98.  
  99. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  100. /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  101.  
  102. int heuristic(const Vertex& v) {
  103.     int count = 0;
  104.     for (int i = 0; i < 16; ++i) {
  105.         if (v.vertex[i] == answer[i])
  106.             continue;
  107.         int x = i % 4;
  108.         int y = i / 4;
  109.         if (v.vertex[i] != 0)
  110.             count += std::abs(x - answer_x[v.vertex[i] - 1]) + std::abs(y - answer_y[v.vertex[i] - 1]);
  111.     }
  112.     return count * 3;
  113. }
  114.  
  115. bool is_correct(std::vector<char> input) {
  116.     std::reverse(input.begin() + 4, input.begin() + 8);
  117.     std::reverse(input.begin() + 12, input.begin() + 16);
  118.     int count = 0;
  119.     for (int i = 0; i < 16; ++i) {
  120.         if (input[i] == 0)
  121.             continue;
  122.         for (int j = i + 1; j < 16; ++j) {
  123.             if (input[j] == 0)
  124.                 continue;
  125.             if (input[i] > input[j])
  126.                 ++count;
  127.         }
  128.     }
  129.     return count % 2 == 1;
  130. }
  131.  
  132. std::string fast_solv15(std::vector<char>& input) {
  133.     if (!is_correct(input))
  134.         return "-1";
  135.     if (input == answer)
  136.         return "";
  137.     Vertex vertex(input);
  138.     std::set<std::pair<int, std::pair<Vertex, std::string>>> qu;
  139.     std::pair<Vertex, std::string> _pair(vertex, "");
  140.     qu.insert(std::pair<int, std::pair<Vertex, std::string>>(heuristic(vertex), _pair));
  141.     std::unordered_map<Vertex, int> _visit;
  142.     _visit.insert(std::pair<Vertex, int>(vertex, heuristic(vertex)));
  143.  
  144.     while (qu.size() != 0) {
  145.         std::pair<int, std::pair<Vertex, std::string>> current = *(qu.begin());
  146.         qu.erase(qu.begin());
  147.         std::vector<std::pair<Vertex, char>> next = current.second.first.GetNextVertices();
  148.         for (auto u : next) {
  149.             int l = heuristic(u.first) + current.second.second.size();
  150.             auto it = _visit.find(u.first);
  151.             if (it == _visit.end()) {
  152.                 if (answer == u.first.vertex)
  153.                     return (current.second.second + u.second);
  154.                 qu.insert(std::pair<int, std::pair<Vertex, std::string>>(l, std::pair<Vertex, std::string>(u.first, current.second.second + u.second)));
  155.                 _visit.insert(std::pair<Vertex, int>(u.first, l));
  156.             }
  157.             else if (it->second > l) {
  158.                 qu.insert(std::pair<int, std::pair<Vertex, std::string>>(l, std::pair<Vertex, std::string>(u.first, current.second.second + u.second)));
  159.                 it->second = l;
  160.             }
  161.         }
  162.     }
  163. }
  164.  
  165. int main() {
  166.     std::vector <char> inp(17);
  167.     const int n = 16;
  168.     for (int i = 0; i < n; ++i) {
  169.         int a;
  170.         std::cin >> a;
  171.         inp[i] = a;
  172.         if (a == 0)
  173.             inp[n] = i;
  174.     }
  175.     std::string output = fast_solv15(inp);
  176.     if (output == "-1")
  177.         std::cout << -1;
  178.     else {
  179.         std::cout << output.size() << std::endl << output;
  180.     }
  181.     return 0;
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement