Advertisement
Guest User

blahblahpyatnashki

a guest
Jun 19th, 2018
101
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.22 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstdio>
  3. #include <array>
  4. #include <set>
  5. #include <algorithm>
  6. #include <vector>
  7. #include <map>
  8.  
  9.  
  10. using namespace std;
  11.  
  12. typedef array<int, 16> board;
  13. typedef unsigned long long desc;
  14.  
  15. void printboard(const board& b) {
  16.     for (int row = 0; row < 4; ++row) {
  17.         for (int col = 0; col < 4; ++col) {
  18.             printf("%3d", b[row*4+col]);
  19.         }
  20.         printf("\n");
  21.     }
  22. }
  23.  
  24. int coord2ind(pair<int, int> c) {
  25.     return c.first * 4 + c.second;
  26. }
  27.  
  28. pair<int,int> ind2coord(int i) {
  29.     return make_pair(i / 4, i % 4);
  30. }
  31.  
  32. desc b2desc(const board& b) {
  33.     desc h = 0;
  34.     for (int v : b) {
  35.         h *= 16;
  36.         h += v;
  37.     }
  38.     return h;
  39. }
  40.  
  41. board desc2b(desc h) {
  42.     board b = {};
  43.     for (int i = 15; i >= 0; --i) {
  44.         b[i] = h % 16;
  45.         h /= 16;
  46.     }
  47.     return b;
  48. }
  49.  
  50. int heuristic(const board& b) {
  51.     int dist = 0;
  52.     for (int i = 0; i < 16; ++i) {
  53.         int v = b[i];
  54.         if (v == 0) continue;
  55.         auto curr_c = ind2coord(i);
  56.         auto dest_c = ind2coord(v-1);
  57.         dist += abs(curr_c.first - dest_c.first);
  58.         dist += abs(curr_c.second - dest_c.second);
  59.     }
  60.     return dist;
  61. }
  62.  
  63. int find_hole(const board& b) {
  64.     for (int i = 0; i < 16; ++i) {
  65.         if (b[i] == 0) return i;
  66.     }
  67.     return -1;
  68. }
  69.  
  70. board finish() {
  71.     return board{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
  72. }
  73.  
  74. int oddness(const board& b) {
  75.     vector<int> z;
  76.     for (int i = 0; i < 16; ++i) {
  77.         if (b[i] != 0) z.push_back(b[i]-1);
  78.     }
  79.     set<int> done;
  80.     int result = 0;
  81.     for (int st = 0; st < 15; ++st) {
  82.         if (done.count(st)) continue;
  83.         int i = st;
  84.         int cnt = 0;
  85.         do {
  86.             done.insert(i);
  87.             i = z[i];
  88.             cnt++;
  89.         } while (i != st);
  90.         result += cnt-1;
  91.     }
  92.     return result % 2;
  93. }
  94.  
  95. void unroll_solution(const map<desc, desc>& visited, desc last, desc first) {
  96.    
  97. }
  98.  
  99. void go(const board& start_b) {
  100.     map<desc, desc> visited;
  101.     set<tuple<int, int, desc>> q; // total, before, desc
  102.    
  103.     desc start_d = b2desc(start_b);
  104.     q.insert(make_tuple(heuristic(start_b), 0, start_d));
  105.     visited[start_d] = 0;
  106.     desc finishdesc = b2desc(finish());
  107.    
  108.     while (!q.empty()) {
  109.         int _, before;
  110.         desc d;
  111.         tie(_, before, d) = *q.begin();
  112.         q.erase(q.begin());
  113.         board b = desc2b(d);
  114.        
  115. //        printf("Visiting:\n");
  116. //        printboard(b);
  117.         static int c = 0;
  118.         ++c;
  119.         if (c == 10000000) {
  120.             printf("Limit reached");
  121.             return;
  122.         }
  123.        
  124.         if (d == finishdesc) {
  125.             printf("FOUND!!! In %d moves\n", before);
  126.             return;
  127.         }
  128.        
  129.         pair<int,int> moves[4];
  130.         int nmoves = 0;
  131.        
  132.         int hole_i = find_hole(b);
  133.         auto hole_c = ind2coord(hole_i);
  134.         if (hole_c.first > 0) {
  135.             moves[nmoves++] = make_pair(hole_c.first - 1, hole_c.second);
  136.         }
  137.         if (hole_c.second > 0) {
  138.             moves[nmoves++] = make_pair(hole_c.first, hole_c.second - 1);
  139.         }
  140.         if (hole_c.first < 3) {
  141.             moves[nmoves++] = make_pair(hole_c.first + 1, hole_c.second);
  142.         }
  143.         if (hole_c.second < 3) {
  144.             moves[nmoves++] = make_pair(hole_c.first, hole_c.second + 1);
  145.         }
  146.         for (int imove = 0; imove < nmoves; imove++) {
  147.             auto move = moves[imove];
  148.             int move_i = coord2ind(move);
  149.             board b2 = b;
  150.             swap(b2[move_i], b2[hole_i]);
  151.             desc d2 = b2desc(b2);
  152.             if (visited.count(d2)) {
  153.                 continue;
  154.             }
  155.             visited[d2] = d;
  156.             q.insert(make_tuple(before + 1 + heuristic(b2), before + 1, d2));
  157.         }
  158.     }
  159.     printf ("Q is empty, eh?\n");
  160. }
  161.  
  162. int main(int argc, const char * argv[]) {
  163. //    board b = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 0, 13, 14, 15};
  164.     board b = {1, 2, 3, 4, 5, 6, 7, 8, 10, 9, 12, 11, 13 ,14 ,15, 0};
  165. //    board b3 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0};
  166.    
  167.     if (oddness(b) == 1) {
  168.         printf("It's odd.");
  169.         return 0;
  170.     }
  171.  
  172.     go(b);
  173.    
  174.     return 0;
  175. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement