{"id":51,"date":"2005-06-28T12:28:53","date_gmt":"2005-06-28T02:28:53","guid":{"rendered":"http:\/\/www.somethinkodd.com\/oddthinking\/?p=51"},"modified":"2007-10-07T21:10:53","modified_gmt":"2007-10-07T11:10:53","slug":"analysing-the-first-move-of-klondike","status":"publish","type":"post","link":"https:\/\/www.somethinkodd.com\/oddthinking\/2005\/06\/28\/analysing-the-first-move-of-klondike\/","title":{"rendered":"Analysing the first move of Klondike"},"content":{"rendered":"<p><!-- UnMarkedDown_2_01132526319--><\/p>\n<p>A few days ago, I <a href=\"http:\/\/www.somethinkodd.com\/oddthinking\/2005\/06\/25\/the-finer-points-of-klondike\/#comment-123\">commented<\/a> on <a href=\"http:\/\/www.techuser.net\/about.html\">Usman Latif<\/a>&#8216;s <a href=\"http:\/\/www.techuser.net\/klondikeprob.html\">analysis<\/a> of the very first move of <a href=\"http:\/\/www.somethinkodd.com\/oddthinking\/2005\/06\/25\/the-finer-points-of-klondike\">Klondike<\/a>. Latif used the <a href=\"http:\/\/en.wikipedia.org\/wiki\/Monte_Carlo_method\" title=\"Wikipedia definition of Monte_Carlo_method\" class=\"wikipedia\">Monte Carlo method<\/a> to estimate the chance that there are exactly no moves possible from the initial deal.<\/p>\n<p>As I have <a href=\"http:\/\/www.somethinkodd.com\/oddthinking\/2005\/05\/31\/beating-the-clock-solitaire\/\">mentioned before<\/a>:<\/p>\n<blockquote><p>\nlike backtracking (which I have dismissed before), the Monte Carlo method skips the niceties of logical analysis to use sheer brute force to solve a problem.\n<\/p><\/blockquote>\n<p>I didn&#8217;t think Latif had given analysis a fair go, so I gave it a try.<\/p>\n<p>My very first attempt was a dismal failure after just a few minutes. However, I had another stab, and this time, I got a lot further.<\/p>\n<p>The solution takes a few pages to work through. <\/p>\n<p>Using the Principle of Mathematical Induction, it works out the chance that the <em>n<\/em>th card is unplayable, given that the first <em>n-1<\/em> cards are all unplayable. To do that, it has to know how many of the previous cards are deuces, how many are kings, how many &#8220;matches&#8221; there are (same rank and colour), and how many of <em>those<\/em> are deuces and kings. <\/p>\n<p>The neat trick is then to work out what the odds are that this unplayable card is itself a matching\/non-matching deuce\/middle\/king card, and recurse with each of those options to find out the chance of success.  Add the tail case (which represents the chance that the 8 revealed cards in the stock are all unplayable) and voila &#8211; a <strong>six-way<\/strong> recursive function that determines the odds. (<a href=\"http:\/\/www.somethinkodd.com\/oddthinking\/2005\/06\/27\/ackermanns-made-icky\/\">Ackerman<\/a>, eat your heart out! Two-way recursion is for wusses!)<\/p>\n<p>Of course, the problem with a six-way recursive function is how long it takes to evaluate, especially when you are trying for n = 7.  I figured 6^7 = ~280,000 executions of the tail case alone.  The tail case has a significant constant time (computing combinatorials involves large factorials, around n = 45, and Python is slow) and there are only 86,400 seconds in the day. Finger-in-the-air estimate? About 6 hour to 18 hours of computing time.<\/p>\n<p>Off I went, and implemented it in Python.  I optimised the tail-case by caching the combinatorial functions into a table. There was also significant pruning of the recursion tree (no extra effort &#8211; it was required to prevent, for example, five Kings from being played). <\/p>\n<p>I was incredible surprised when the whole thing completed with only 31,000 executions of the tail case, and in well under five seconds! So much for my estimates!<\/p>\n<p>That was the good news. <\/p>\n<p>The bad news was, when I turned on error-checking assert statements, they revealed that I had made a horrible mistake in my analysis. I had wrongly calculated the odds that this next card is a middle card <em>given<\/em> that this card is unplayable. The <em>correct<\/em> way of calculating it is still beyond me.  <\/p>\n<p>I suspect what it needs is a <strong>12-way<\/strong> recursive function (no need to recurse for Aces).  My ever-so-reliable estimation methods only put that at about ten minutes of computing. However, it sounds suspiciously close to checking every possible input.<\/p>\n<p>Checking every possible input to a problem is a more deterministic cousin of the stochastic Monte Carlo method. It gives an exact response, rather that a probabilistic response based on sampling. However, it is too close to brute force, and hence my interest is starting to wane.<\/p>\n<p>Maybe I should spend some more time on it &#8211; optimising 52! down to 12^7 is considerable and worthy of a try, but I think I will take a break for now. In the meantime, I have to give a nod to Latif; the analysis remains trickier than I thought.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>A few days ago, I commented on Usman Latif\u00e2\u20ac\u2122s analysis of the very first move of Klondike.<\/p>\n<p>I didn\u00e2\u20ac\u2122t think Latif had given logical analysis a fair go, so I gave it a try.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_s2mail":"","footnotes":""},"categories":[28,35,33],"tags":[55,69,54],"class_list":["post-51","post","type-post","status-publish","format-standard","hentry","category-doubleplus-geek","category-heroic-failures","category-puzzle-solving","tag-puzzle","tag-software","tag-solution"],"_links":{"self":[{"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/posts\/51","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/comments?post=51"}],"version-history":[{"count":0,"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/posts\/51\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/media?parent=51"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/categories?post=51"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.somethinkodd.com\/oddthinking\/wp-json\/wp\/v2\/tags?post=51"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}