{"id":128,"date":"2010-01-10T20:00:51","date_gmt":"2010-01-10T19:00:51","guid":{"rendered":"http:\/\/daniel.hepper.net\/blog\/?p=128"},"modified":"2018-11-25T19:03:43","modified_gmt":"2018-11-25T18:03:43","slug":"how-to-solve-the-36-cube-puzzle","status":"publish","type":"post","link":"https:\/\/daniel.hepper.net\/blog\/2010\/01\/how-to-solve-the-36-cube-puzzle\/","title":{"rendered":"How to solve the 36 Cube puzzle &#8211; hints &#038; solution"},"content":{"rendered":"<p>For Christmas, I got the ThinkFun 36 Cube. It is consists of 36 towers in 6 colors and 6 different sizes and a base plate with 6 by 6 slots to plug in the towers. These slots are of different heights. The goal is to place one towers of every color in each row and column. And the\u00a0 towers must fit to form a level cube.<\/p>\n<p>After some tries, I came to the conclusion that this puzzle is the work of the devil and that I should not waste more brain cycles on solving it. So I wrote a little python script to solve the puzzle for me.<\/p>\n<p><a onclick=\"document.getElementById('34cube').style.display='inline';\" href=\"javascript:void(0)\">Show sourcecode<\/a><\/p>\n<div id=\"34cube\" style=\"display: none;\">\n<pre lang=\"python\">#!\/usr\/bin\/python\r\n\r\nCOLORS = dict(zip((1 &lt;&lt; i for i in range(6)), ('P','Y','O','B','R','G')))\r\nCOLORS[False] = 'X'\r\n\r\nused_towers = [0 for i in range(6)]\r\n\r\ncube = ((1,3,4,5,2,0),\r\n        (2,5,0,4,1,3),\r\n        (0,1,3,2,5,4),\r\n        (5,4,1,3,0,2),\r\n        (4,2,5,0,3,1),\r\n        (3,0,2,1,4,5))\r\n\r\nsolution = [[False for x in range(6)] for x in range(6)]\r\nused = tuple(set() for i in range(6))\r\n\r\ndef test_color(pos, solution, used_towers, color, size):\r\n #check if tower of this size and color has already been used\r\n if color &amp; used_towers[size]:\r\n  return False\r\n #check if tower has already been used in row or column:\r\n for i in range(6):\r\n  if color == solution[pos\/6][i]: return False\r\n  if color == solution[i][pos%6]: return False\r\n return True\r\n\r\ndef print_solution(solution):\r\n for i in range(6):\r\n  print zip((COLORS[c] for c in solution[i]), (6 - s for s in cube[i]))\r\n\r\ndef solve(pos, solution, used_towers, best):\r\n if pos == 36: return best, solution\r\n size = cube[pos\/6][pos%6]\r\n for i in range(6):\r\n  color = 1 &lt;&lt; i\r\n  if test_color(pos, solution, used_towers, color, size):\r\n   used_towers[size] = used_towers[size] | color\r\n   solution[pos\/6][pos%6] = color\r\n   if pos &gt; best:\r\n    print \"#######\", pos + 1, \"towers placed\"\r\n    print_solution(solution)\r\n    best = pos\r\n   best, solution = solve(pos+1, solution, used_towers, best)\r\n   if best &gt;= 35:\r\n    return best, solution\r\n   solution[pos\/6][pos%6] = False\r\n   used_towers[size] = used_towers[size] ^ color\r\n return best, solution\r\n\r\nsolve(0, solution, used_towers, 0)<\/pre>\n<\/div>\n<p>My program quickly came up with a correct placement for 34 towers &#8211; but it failed to find the complete solution.<\/p>\n<pre>[('P', 5), ('Y', 3), ('O', 2), ('B', 1), ('R', 4), ('G', 6)]\r\n[('Y', 4), ('O', 1), ('P', 6), ('R', 2), ('G', 5), ('B', 3)]\r\n[('O', 6), ('B', 5), ('R', 3), ('G', 4), ('P', 1), ('Y', 2)]\r\n[('R', 1), ('G', 2), ('Y', 5), ('P', 3), ('B', 6), ('O', 4)]\r\n[('B', 2), ('P', 4), ('G', 1), ('Y', 6), ('O', 3), ('R', 5)]\r\n[('G', 3), ('R', 6), ('B', 4), ('O', 5), ('X', 2), ('X', 1)]<\/pre>\n<p>Legend:<br \/>\nP = Purple, Y = Yellow, O = Orange, B = Blue, R = Red, G = Green, X = Empty<br \/>\nThe number is the size of the tower.<br \/>\nAs you can see, I didn&#8217;t waste much time on making the output pretty \ud83d\ude42<\/p>\n<div id=\"attachment_129\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_almost_solved.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-129\" class=\"size-medium wp-image-129\" title=\"36cube almost solved\" src=\"http:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_almost_solved-300x225.jpg\" alt=\"36cube almost solved\" width=\"300\" height=\"225\" srcset=\"https:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_almost_solved-300x225.jpg 300w, https:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_almost_solved.jpg 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-129\" class=\"wp-caption-text\">So close and yet so far<\/p><\/div>\n<p>After spending lots of time verifying that my program was working correctly, I became impatient and googled for help. I found an answer, but it revealed too much, taking all the fun.<\/p>\n<p>Therefore, I split my solution into multiple hints. If you are stuck, reveal just one of them at a time and try to figure it out by yourself. It is way more rewarding!<\/p>\n<p>Hint #1 <a onclick=\"document.getElementById('hint1').style.display='inline';\" href=\"javascript:void(0)\">(show)<\/a>: <span id=\"hint1\" style=\"display: none;\">Your assumptions are probably wrong.<br \/>\nNow go back and try to solve it. I&#8217;m waiting here.<\/span><\/p>\n<p>Hint #2 <a onclick=\"document.getElementById('hint2').style.display='inline';\" href=\"javascript:void(0)\">(show)<\/a>: <span id=\"hint2\" style=\"display: none;\">The assumption that all towers of the same size only differ in color is wrong.<\/span><\/p>\n<p>Hint #3 <a onclick=\"document.getElementById('hint3').style.display='inline';\" href=\"javascript:void(0)\">(show)<\/a>: <span id=\"hint3\" style=\"display: none;\">There are two towers which do fit on slots where the other towers of the same size do not fit.<\/span><\/p>\n<p>Hint #4 <a onclick=\"document.getElementById('hint4').style.display='inline';\" href=\"javascript:void(0)\">(show)<\/a>: <span id=\"hint4\" style=\"display: none;\">The two special towers are the orange one of heigh 5 and the red one of height 6.<\/span><\/p>\n<p>Hint #5 <a onclick=\"document.getElementById('hint5').style.display='inline';\" href=\"javascript:void(0)\">(show)<\/a>: <span id=\"hint5\" style=\"display: none;\">The orange tower of height 5 has to go to position (1,2) and the red tower of height 6 to (3,2) in my coordinate system.<\/span><\/p>\n<p>Even if you uncovered all hints, the puzzle is still far from solved. You can still tinker with it forever.<\/p>\n<p>Spoiler alert: Don&#8217;t uncover the solution, unless you are really desperate!<\/p>\n<p><strong><a onclick=\"document.getElementById('solution').style.display='inline';\" href=\"javascript:void(0)\">Click to show the 36cube solution.<\/a><\/strong><\/p>\n<div id=\"solution\" style=\"display: none;\">After I had found the two culprits, I adjusted my program by changing the array and inserting two special conditions. Within seconds I had a complete solution of the 36 Cube:<\/p>\n<pre>[('P', 5), ('Y', 3), ('B', 2), ('O', 1), ('R', 4), ('G', 6)]\r\n[('B', 4), ('P', 1), ('Y', 5), ('G', 2), ('O', 5), ('R', 3)]\r\n[('R', 6), ('G', 5), ('P', 3), ('Y', 4), ('B', 1), ('O', 2)]\r\n[('G', 1), ('R', 2), ('O', 6), ('B', 3), ('Y', 6), ('P', 4)]\r\n[('Y', 2), ('O', 4), ('R', 1), ('P', 6), ('G', 3), ('B', 5)]\r\n[('O', 3), ('B', 6), ('G', 4), ('R', 5), ('P', 2), ('Y', 1)]<\/pre>\n<div id=\"attachment_130\" style=\"width: 310px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_complete_solution.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-130\" class=\"size-medium wp-image-130\" title=\"36cube complete solution\" src=\"http:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_complete_solution-300x225.jpg\" alt=\"\" width=\"300\" height=\"225\" srcset=\"https:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_complete_solution-300x225.jpg 300w, https:\/\/daniel.hepper.net\/blog\/wp-content\/36cube_complete_solution.jpg 1024w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><p id=\"caption-attachment-130\" class=\"wp-caption-text\">Finally solved<\/p><\/div>\n<pre lang=\"python\">#!\/usr\/bin\/python\r\n\r\nCOLORS = dict(zip((1 &lt;&lt; i for i in range(6)), ('P','Y','O','B','R','G')))\r\nCOLORS[False] = 'X'\r\n\r\nused_towers = [0 for i in range(6)]\r\n\r\n# definition with (1,2) and (3,2) switched\r\ncube = ((1,3,4,5,2,0),\r\n        (2,5,1,4,1,3),\r\n        (0,1,3,2,5,4),\r\n        (5,4,0,3,0,2),\r\n        (4,2,5,0,3,1),\r\n        (3,0,2,1,4,5))\r\n\r\nsolution = [[False for x in range(6)] for x in range(6)]\r\nused = tuple(set() for i in range(6))\r\n\r\ndef test_color(pos, solution, used_towers, color, size):\r\n #check if tower of this size and color has already been used\r\n if color &amp; used_towers[size]:\r\n  return False\r\n #check if tower has already been used in row or column:\r\n for i in range(6):\r\n  if color == solution[pos\/6][i]: return False\r\n  if color == solution[i][pos%6]: return False\r\n # special conditions for the two special towers\r\n if (pos\/6, pos%6) == (1,2) and color != 2: return False\r\n if (pos\/6, pos%6) == (3,2) and color != 4: return False\r\n return True\r\n\r\ndef print_solution(solution):\r\n for i in range(6):\r\n  print zip((COLORS[c] for c in solution[i]), (6 - s for s in cube[i]))\r\n\r\ndef solve(pos, solution, used_towers, best):\r\n if pos == 36: return best, solution\r\n size = cube[pos\/6][pos%6]\r\n for i in range(6):\r\n  color = 1 &lt;&lt; i\r\n  if test_color(pos, solution, used_towers, color, size):\r\n   used_towers[size] = used_towers[size] | color\r\n   solution[pos\/6][pos%6] = color\r\n   if pos &gt; best:\r\n    print \"#######\", pos + 1, \"towers placed\"\r\n    print_solution(solution)\r\n    best = pos\r\n   best, solution = solve(pos+1, solution, used_towers, best)\r\n   if best &gt;= 35:\r\n    return best, solution\r\n   solution[pos\/6][pos%6] = False\r\n   used_towers[size] = used_towers[size] ^ color\r\n return best, solution\r\n\r\nsolve(0, solution, used_towers, 0)<\/pre>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>For Christmas, I got the ThinkFun 36 Cube. It is consists of 36 towers in 6 colors and 6 different sizes and a base plate with 6 by 6 slots to plug in the towers. These slots are of different &hellip; <a href=\"https:\/\/daniel.hepper.net\/blog\/2010\/01\/how-to-solve-the-36-cube-puzzle\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[11,35],"tags":[],"class_list":["post-128","post","type-post","status-publish","format-standard","hentry","category-howto","category-python"],"_links":{"self":[{"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/posts\/128","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/comments?post=128"}],"version-history":[{"count":31,"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/posts\/128\/revisions"}],"predecessor-version":[{"id":636,"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/posts\/128\/revisions\/636"}],"wp:attachment":[{"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/media?parent=128"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/categories?post=128"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/daniel.hepper.net\/blog\/wp-json\/wp\/v2\/tags?post=128"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}