{"id":26190,"date":"2017-10-26T20:24:18","date_gmt":"2017-10-26T14:54:18","guid":{"rendered":"https:\/\/www.wikitechy.com\/technology\/?p=26190"},"modified":"2017-10-26T20:24:18","modified_gmt":"2017-10-26T14:54:18","slug":"c-programming-check-instance-8-puzzle-solvable","status":"publish","type":"post","link":"https:\/\/www.wikitechy.com\/technology\/c-programming-check-instance-8-puzzle-solvable\/","title":{"rendered":"C++ Programming &#8211; How to check if an instance of 8 puzzle is solvable?"},"content":{"rendered":"<p><strong>What is 8 puzzle?<\/strong><br \/>\nGiven a 3\u00d73 board with 8 tiles (every tile has one number from 1 to 8) and one empty space.<span id=\"more-133336\"><\/span>The objective is to place the numbers on tiles in order using the empty space. We can slide four adjacent (left, right, above and below) tiles into the empty space.<\/p>\n<p><img fetchpriority=\"high\" decoding=\"async\" class=\"aligncenter size-full wp-image-26195\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/8puzzle1.png\" alt=\"puzzle\" width=\"259\" height=\"251\" \/><\/p>\n<p><strong>How to find if given state is solvable?<\/strong><br \/>\nFollowing are two examples, the first example can reach goal state by a series of slides. The second example cannot.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-26194\" src=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/8puzzle.png\" alt=\"puzzle2\" width=\"615\" height=\"338\" srcset=\"https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/8puzzle.png 615w, https:\/\/www.wikitechy.com\/technology\/wp-content\/uploads\/2017\/05\/8puzzle-300x165.png 300w\" sizes=\"(max-width: 615px) 100vw, 615px\" \/><\/p>\n<p>Following is simple rule to check if a 8 puzzle is solvable.<br \/>\nIt is not possible to solve an instance of 8 puzzle if number of inversions is odd in the input state. In the examples given in above figure, the first example has 10 inversions, therefore solvable. The second example has 11 inversions, therefore unsolvable.<\/p>\n[ad type=&#8221;banner&#8221;]\n<p>What is inversion?<br \/>\nA pair of tiles form an inversion if the the values on tiles are in reverse order of their appearance in goal state. For example, the following instance of 8 puzzle has two inversions, (8, 6) and (8, 7).<\/p>\n<p>1 2 3<br \/>\n4 _ 5<br \/>\n8 6 7<br \/>\nFollowing is a simple C++ program to check whether a given instance of 8 puzzle is solvable or not. The idea is simple, we count inversions in the given 8 puzzle.<\/p>\n<div class=\"code-embed-wrapper\"> <div class=\"code-embed-infos\"> <span class=\"code-embed-name\">C++ Program<\/span> <\/div> <pre class=\"language-cpp code-embed-pre line-numbers\"  data-start=\"1\" data-line-offset=\"0\"><code class=\"language-cpp code-embed-code\">\/\/ C++ program to check if a given instance of 8 puzzle is solvable or not<br\/>#include &lt;iostream&gt;<br\/>using namespace std;<br\/> <br\/>\/\/ A utility function to count inversions in given array &#039;arr[]&#039;<br\/>int getInvCount(int arr[])<br\/>{<br\/>    int inv_count = 0;<br\/>    for (int i = 0; i &lt; 9 - 1; i++)<br\/>        for (int j = i+1; j &lt; 9; j++)<br\/>             \/\/ Value 0 is used for empty space<br\/>             if (arr[j] &amp;&amp; arr[i] &amp;&amp;  arr[i] &gt; arr[j])<br\/>                  inv_count++;<br\/>    return inv_count;<br\/>}<br\/> <br\/>\/\/ This function returns true if given 8 puzzle is solvable.<br\/>bool isSolvable(int puzzle[3][3])<br\/>{<br\/>    \/\/ Count inversions in given 8 puzzle<br\/>    int invCount = getInvCount((int *)puzzle);<br\/> <br\/>    \/\/ return true if inversion count is even.<br\/>    return (invCount%2 == 0);<br\/>}<br\/> <br\/>\/* Driver progra to test above functions *\/<br\/>int main(int argv, int** args)<br\/>{<br\/>  int puzzle[3][3] =  {{1, 8, 2},<br\/>                      {0, 4, 3},  \/\/ Value 0 is used for empty space<br\/>                      {7, 6, 5}};<br\/>  isSolvable(puzzle)? cout &lt;&lt; &quot;Solvable&quot;:<br\/>                      cout &lt;&lt; &quot;Not Solvable&quot;;<br\/>  return 0;<br\/>}<\/code><\/pre> <\/div>\n<p><strong>Output:<\/strong><\/p>\n<p>Solvable<br \/>\nNote that the above implementation uses simple algorithm for inversion count. It is done this way for simplicity. The code can be optimized to O(nLogn) using the merge sort based algorithm for inversion count.<\/p>\n[ad type=&#8221;banner&#8221;]\n<p><strong>How does this work?<\/strong><br \/>\nThe idea is based on the fact the parity of inversions remains same after a set of moves, i.e., if the inversion count is odd in initial stage, then it remain odd after any sequence of moves and if the inversion count is even, then it remains even after any sequence of moves. In the goal state, there are 0 inversions. So we can reach goal state only from a state which has even inversion count.<\/p>\n<p>How parity of inversion count is invariant?<br \/>\nWhen we slide a tile, we either make a row move (moving a left or right tile into the blank space), or make a column move (moving a up or down tile to the blank space).<br \/>\n<strong>a)<\/strong> A row move doesn\u2019t change the inversion count. See following example<\/p>\n<pre>   1   2   3    Row Move     1   2   3\r\n   4   _   5   ----------&gt;   _   4   5 \r\n   8   6   7                 8   6   7\r\n  Inversion count remains 2 after the move\r\n\r\n   1   2   3    Row Move     1   2   3\r\n   4   _   5   ----------&gt;   4   5   _\r\n   8   6   7                 8   6   7\r\n  Inversion count remains 2 after the move\r\n<\/pre>\n<p><strong>b) <\/strong>A column move does one of the following three.<br \/>\n\u2026..(i) Increases inversion count by 2. See following example.<\/p>\n<pre>         1   2   3   Column Move     1   _   3\r\n         4   _   5   -----------&gt;    4   2   5  \r\n         8   6   7                   8   6   7\r\n      Inversion count increases by 2 (changes from 2 to 4)\r\n<\/pre>\n<p>\u2026..(ii) Decreases inversion count by 2<\/p>\n<pre>         1   3   4    Column Move     1   3   4\r\n         5   _   6   ------------&gt;    5   2   6\r\n         7   2   8                    7   _   8\r\n      Inversion count decreases by 2 (changes from 5  to 3)<\/pre>\n<p>\u2026..(iii) Keeps the inversion count same.<\/p>\n<pre>         1   2   3    Column Move     1   2   3\r\n         4   _   5   ------------&gt;    4   6   5\r\n         7   6   8                    7   _   8\r\n        Inversion count remains 1 after the move<\/pre>\n<p>So if a move either increases\/decreases inversion count by 2, or keeps the inversion count same, then it is not possible to change parity of a state by any sequence of row\/column moves.<\/p>\n[ad type=&#8221;banner&#8221;]\n","protected":false},"excerpt":{"rendered":"<p>C++ Programming &#8211; How to check if an instance of 8 puzzle is solvable &#8211; Given a 3\u00d73 board with 8 tiles (every tile has one number from 1 to 8) and one empty <\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[69969,83515,1,74058],"tags":[77677,77692,77691,77663,77693,77685,77675,77690,77652,77687,77696,77655,77682,77651,77659,59132,77694,77669,77695,77676,77697,77665,77689,77672,77660,77653,77664,77656,77679,77670,77683,77657,77688,77686,77668,77673,77661,77684,77678,77674,77698,77681,77667,77671,77658,77680,77699,77666,77662,77654],"class_list":["post-26190","post","type-post","status-publish","format-standard","hentry","category-algorithm","category-c-programming-3","category-coding","category-mathematical-algorithms","tag-15-games","tag-15-puzzle","tag-16-square-puzzle-solution","tag-8-puzzle","tag-8-puzzle-game","tag-block-puzzle-solutions","tag-brick-puzzle","tag-fifteen-puzzle","tag-heuristic-function-for-8-puzzle-problem","tag-house-puzzle","tag-how-to-draw-house","tag-how-to-solve-8-puzzle-problem","tag-impossible-puzzle","tag-line-puzzle","tag-moving-puzzle","tag-number-puzzle-games","tag-number-puzzle-solver","tag-number-puzzles","tag-number-slide-puzzle","tag-online-slide-puzzle","tag-puzzle-5","tag-puzzle-game-solutions","tag-puzzle-number","tag-puzzle-puzzle","tag-puzzle-puzzle-puzzle","tag-puzzle-room","tag-puzzle-slide","tag-puzzle-solve-it","tag-puzzle-solver","tag-puzzle-solver-app","tag-puzzle-solving-games","tag-slide-games","tag-slide-puzzle","tag-slide-puzzle-games","tag-slide-puzzle-online","tag-slide-puzzle-solver","tag-sliding-block-puzzle","tag-sliding-game-puzzle","tag-sliding-tile-puzzle","tag-sliding-tile-puzzle-solver","tag-solve-15-puzzle","tag-solve-puzzle","tag-solve-puzzle-games","tag-solve-the-puzzle","tag-solve-the-puzzle-game","tag-space-puzzle","tag-square-puzzle","tag-square-puzzle-game","tag-the-fifteen-puzzle","tag-tile-puzzle-games"],"_links":{"self":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26190","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/comments?post=26190"}],"version-history":[{"count":0,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/posts\/26190\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/media?parent=26190"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/categories?post=26190"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wikitechy.com\/technology\/wp-json\/wp\/v2\/tags?post=26190"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}