{"id":598,"date":"2013-05-26T12:53:06","date_gmt":"2013-05-26T11:53:06","guid":{"rendered":"http:\/\/oprsteny.cz\/?p=598"},"modified":"2013-05-27T08:10:00","modified_gmt":"2013-05-27T07:10:00","slug":"algorithms-puzzle-called-falling-egg","status":"publish","type":"post","link":"https:\/\/oprsteny.cz\/?p=598","title":{"rendered":"Algorithms: Puzzle called &#8220;Falling egg&#8221;"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" class=\" alignleft\" alt=\"\" src=\"http:\/\/oprsteny.cz\/wp-content\/uploads\/img_51a1f5ebcb258.png\" width=\"127\" height=\"177\" \/>Assume you are given 2 eggs.<br \/>\nYou have access to a 100-floors high building<br \/>\nEggs can break if dropped from the first floor or may not even break if dropped from 100th floor.<br \/>\nBoth eggs are identical.<\/p>\n<p><em id=\"__mceDel\">You need to figure out the highest floor of a 100-storey building an egg can be dropped from without breaking.<br \/>\nThe question is how many drops you need to make. You are allowed to break 2 eggs in the process<!--more--><\/em><\/p>\n<p>The following is a description of the instance of this famous puzzle involving<br \/>\n&#8211; N = 2 eggs<br \/>\n&#8211; building with H = 100 floors<\/p>\n<p>Suppose that we wish to know which floors in a 100-floors high building are safe to drop eggs from, and which will cause the eggs to break on landing. We make a few assumptions:<br \/>\n&#8211; An egg that survives a fall can be used again.<br \/>\n&#8211; A broken egg must be discarded.<br \/>\n&#8211; The effect of a fall is the same for all eggs.<br \/>\n&#8211; If an egg breaks when dropped, then it would break if dropped from a higher window.<br \/>\n&#8211; If an egg survives a fall, then it would survive a any shorter fall.<\/p>\n<p>It is not ruled out that the first-floor windows break eggs, nor is it ruled out that the 100th-floor windows do not cause an egg to break.<\/p>\n<p>If only one egg is available and we wish to be sure of obtaining the right result, the experiment can be carried out in only one way:<br \/>\n1. drop the egg from the first-floor window<br \/>\n2. if it survives, drop it from the second-floor window<br \/>\n3. Continue upward until it breaks<\/p>\n<p>In the worst case, this method may require 100 droppings.<\/p>\n<p>But according to our scenario we have 2 eggs available.<br \/>\nWhat is the least number of egg-droppings that is guaranteed to work in all cases?<\/p>\n<p>To derive a dynamic programming functional equation for this puzzle, let the state of the dynamic programming model be a pair s = (n,k), where<br \/>\nn = number of test eggs available, n = 0, 1, 2, 3, &#8230;, N &#8211; 1.<br \/>\nk = number of (consecutive) floors yet to be tested, k = 0, 1, 2, &#8230;, H &#8211; 1.<\/p>\n<p>For instance, s = (3,48) indicates that<br \/>\n&#8211; 3 test eggs are available<br \/>\n&#8211; 48 (consecutive) floors are yet to be tested<\/p>\n<p>The initial state of the process is s = (N,H) where N denotes the number of test eggs available at start of the experiment.<br \/>\nThe process terminates either when<br \/>\n&#8211; there are no more test eggs (n = 0) or<br \/>\n&#8211; when k = 0, whichever occurs first.<br \/>\nIf termination occurs at state s = (0,k) and k &gt; 0, then the test failed.<\/p>\n<p>Now, let function\u00a0W(n,k) = minimum number of trials required to identify the value of the critical floor under the worst case scenario given that the process is in state s = (n,k).<\/p>\n<p>Then it can be shown that<br \/>\nW(n,k) = 1 + min{max(W(n &#8211; 1, x &#8211; 1), W(n,k &#8211; x)): x = 1, 2, &#8230;, k;}<br \/>\nwith knowing that W(n,1) = 1 for all n &gt; 0 and W(1,k) = k for all k.<\/p>\n<p>It is easy to solve this equation iteratively by systematically increasing the values of x.<\/p>\n<p>In the following code there is my own generalized solution for N eggs and K-floors high building coded in C++. I know it&#8217;s not optimal, but it works and gives correct results.<\/p>\n<pre lang=\"cpp\">#include&lt;iostream&gt;\r\n#include&lt;map&gt;\r\n#include&lt;time.h&gt;\r\nusing namespace std;\r\n\r\nstruct Status {\r\n  int n; \r\n  int k;\r\n  bool operator &lt; (const Status&amp; other) const {\r\n    return n &lt; other.n ? true : k &lt; other.k;\r\n  }\r\n\r\n  Status(int n, int k):n(n), k(k){}\r\n};\r\nmap&lt;string, int&gt; W_res;\r\n\r\nint GetMax (int a, int b) {\r\n  return a&gt;b?a:b;\r\n}\r\n\r\nint W(Status status, int passed = 0){\r\n\/*\r\n  To Avoid computing the same again -&gt;\r\n  use precomputed values\r\n*\/\r\n  if(W_res.find(status) != W_res.end()) {\r\n    return W_res[status];\r\n  }\r\n\r\n  if(status.n == 0 &amp;&amp; status.k &gt; 0) throw \"Wrong way\";\r\n  else if(status.n == 1 || status.k &lt;= 1) return status.k;\r\n  else {\r\n    int min = status.k;\r\n    int max_x;\r\n    for(int x = 1; x &lt;= status.k; x++) {\r\n      try{\r\n        int max = GetMax(W(Status(status.n-1, x-1), passed), W(Status(status.n, status.k-x), x));\r\n        if(max &lt; min) {\r\n          min = max;\r\n          max_x = x + passed;\r\n        }\r\n      }catch (const char* err_msg){;}\/\/ignore this result\r\n    }\r\n\r\n    W_res[status] = 1 + min; \/\/save as precomputed value\r\n    return 1 + min;\r\n  }\r\n}\r\n\r\nint main (int argc, char *argv[]) {\r\n  cout &lt;&lt; \"Please enter number of floors: \";\r\n  int NUM_FLOORS = 0;\r\n  cin &gt;&gt; NUM_FLOORS;\r\n\r\n  cout &lt;&lt; \"Please enter number of available eggs: \";\r\n  int NUM_EGGS = 0;\r\n  cin &gt;&gt; NUM_EGGS;\r\n\r\n  clock_t start = clock();\r\n\r\n  cout &lt;&lt; \"Number of floors: \" &lt;&lt; NUM_FLOORS &lt;&lt; endl\r\n       &lt;&lt; \"Number of available eggs: \" &lt;&lt; NUM_EGGS &lt;&lt; endl &lt;&lt; endl\r\n       &lt;&lt; \"How many attempts do we need at worst case \" &lt;&lt; endl\r\n       &lt;&lt; \"to check the highest floor we can drop an egg from \" &lt;&lt; endl\r\n       &lt;&lt; \"without breaking it: \" &lt;&lt; W(Status(NUM_EGGS,NUM_FLOORS)) &lt;&lt; endl;\r\n\r\n  double duration = double((clock() - start)) \/ CLOCKS_PER_SEC;\r\n  cout &lt;&lt; \"\\nTime needed for computation (sec): \" &lt;&lt; duration \r\n       &lt;&lt; \"\\n\\nPress Enter to termiate\";\r\n\r\n  cin.ignore();\r\n  cin.get();\r\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Assume you are given 2 eggs. You have access to a 100-floors high building Eggs can break if dropped from the first floor or may not even break if dropped from 100th floor. Both eggs are identical. You need to &hellip; <a href=\"https:\/\/oprsteny.cz\/?p=598\">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":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Algorithms: Puzzle called \"Falling egg\"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[15,150,9],"tags":[159,149,160,158],"class_list":["post-598","post","type-post","status-publish","format-standard","hentry","category-algorithms","category-c-development","category-development","tag-brain-teaser","tag-cpp","tag-falling-egg","tag-puzzle"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p3nYbe-9E","jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/598","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=598"}],"version-history":[{"count":7,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/598\/revisions"}],"predecessor-version":[{"id":604,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=\/wp\/v2\/posts\/598\/revisions\/604"}],"wp:attachment":[{"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=598"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=598"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oprsteny.cz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=598"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}