<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Life Is Pain, Then You Die: The Blog (Posts about brain-teasers)</title><link>https://siweizhu.com/</link><description></description><atom:link href="https://siweizhu.com/categories/brain-teasers.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2020 &lt;a href="mailto:test"&gt;Siwei Zhu&lt;/a&gt; </copyright><lastBuildDate>Wed, 02 Sep 2020 05:50:00 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>2 Cups 100 Floors</title><link>https://siweizhu.com/posts/2-cups-100-floors/</link><dc:creator>Siwei Zhu</dc:creator><description>&lt;div&gt;&lt;p&gt;There is a brainteaser that goes like this. There is a building with 100 floors and you have two identical cups made from some unknown type of glass. You want to determine the highest floor that you can drop the glass from without it shattering. Call it floor &lt;code class="docutils literal"&gt;k&lt;/code&gt;. The glasses can be dropped as many times as you want from floors below &lt;code class="docutils literal"&gt;k&lt;/code&gt; without breaking, but as soon as you go above &lt;code class="docutils literal"&gt;k&lt;/code&gt;, they break.&lt;/p&gt;
&lt;p&gt;So one way to do this is by dropping the cup from each floor from 1 to 100, sequentially, until it breaks. But this is obviously pretty inefficient. What is the most efficient way of determining &lt;code class="docutils literal"&gt;k&lt;/code&gt; (in the sense of requiring the fewest number of test drops)?&lt;/p&gt;
&lt;p&gt;(I heard a version with eggs instead of cups, and my friend immediately answered that &lt;code class="docutils literal"&gt;k&lt;/code&gt; should be 1 because it’s an egg. “What the hell kind of eggs are you using??”)&lt;/p&gt;
&lt;p&gt;There is a fairly simple solution that people commonly come up with. And, it’s pretty good, but not optimal. This post is about how to get the really actually truly optimal solution. Here is a pause in case you haven’t heard this before and want to figure it out for yourself. Otherwise, read on.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;.&lt;/p&gt;
&lt;p&gt;First, since you don’t know what &lt;code class="docutils literal"&gt;k&lt;/code&gt; is, “fewest” means minimizing the average number of steps your algorithm takes. You could define some other measure of optimality, but this is what we’ll go with. It’s important to note that the answer depends on the distribution &lt;code class="docutils literal"&gt;k&lt;/code&gt; takes on, but it seems pretty reasonable to assume a uniform distribution.&lt;/p&gt;
&lt;p&gt;The simple algorithm goes like this: first, try the 10th, 20th, … etc. floors until the first glass breaks. Once the first glass breaks, you’ve narrowed &lt;code class="docutils literal"&gt;k&lt;/code&gt; to a range of 10 floors. E.g., it didn’t break at 30 but it broke at 40, so &lt;code class="docutils literal"&gt;k&lt;/code&gt; must be between 31 and 39, so you use the second glass to try 31, 32, … etc.&lt;/p&gt;
&lt;p&gt;It’s clear that, once the first glass breaks, you must try the second glass one floor at a time, starting from the highest known floor not to break a glass. So the strategy is entirely determined by what sequence of floors to try for the first glass, before it breaks. The simple solution can be represented by the array &lt;code class="docutils literal"&gt;[10, 20, …, 90]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;You can calculate (e.g., by writing code, or using maths) that the average running time for this algorithm is &lt;code class="docutils literal"&gt;10.81&lt;/code&gt; steps. But, the average running time for the following algorithm, which is optimal, is &lt;code class="docutils literal"&gt;10.31&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="code python"&gt;&lt;a name="rest_code_29061fdca2904055b99b76b65273e54d-1"&gt;&lt;/a&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;13&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;36&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;55&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;63&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;71&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;78&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;84&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;89&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;93&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;96&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;98&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;99&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;p&gt;It turns out that the simple algorithm is actually pretty good. The optimal is only a 5% improvement or so. But why isn’t the simple algorithm optimal? Because it doesn’t self adjust to additional information.&lt;/p&gt;
&lt;p&gt;What is the optimal solution if you only had 50 floors? There’s nothing special about the number 10, so there is no reason to think that &lt;code class="docutils literal"&gt;[10, 20, 30, 40]&lt;/code&gt; should be optimal for 50. If we think the heuristic is a square root, then we should be going up by about 7 floors each time, something like &lt;code class="docutils literal"&gt;[7, 14, 21, …]&lt;/code&gt;.&lt;/p&gt;
&lt;div class="admonition note"&gt;
&lt;p class="admonition-title"&gt;Note&lt;/p&gt;
&lt;p&gt;(Square root is actually a pretty reasonable heuristic — if you make the interval too large, you have to a lot of drops with the second glass, and if you make the interval too small, you have to do a lot of drops with the first glass. Square root balances the expected amount of work you need to do with the first glass with the second.) (And, in fact, the average running time for [7, 14, 21, …] is 7.86, better than [10, 20, 30, 40]’s 8.22.)&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;So, back to the 100 floors case, this means that, if for your first glass, you went 10, 20, … all the way up to 50, and the glass hasn’t broken yet, then switching to going up in intervals of 7 instead of 10 would yield a lower average running time. Because if you’re at 50 and the first glass hasn’t broken yet, then you have reduced to the 50 floors case. The naive strategy of always going up by 10 floors doesn’t adjust to the information you get from the glass not breaking.&lt;/p&gt;
&lt;p&gt;This reduction idea hints at how to find an optimal solution. What if you already knew optimal solutions for the 1 floor, 2 floor, … 99 floors cases? Then to find an optimal solution for the 100 floors case, all you need to do is figure out what is the first floor &lt;code class="docutils literal"&gt;p&lt;/code&gt; that you should test drop at. If the glass breaks at &lt;code class="docutils literal"&gt;p&lt;/code&gt;, you are forced to use the second glass one floor at the time. If the glass does not break at &lt;code class="docutils literal"&gt;p&lt;/code&gt;, then you follow the optimal solution for &lt;code class="docutils literal"&gt;&lt;span class="pre"&gt;100-p&lt;/span&gt;&lt;/code&gt; floors from your book of solutions.&lt;/p&gt;
&lt;p&gt;(My first attempt at explicitly writing down the optimal solution was to brute force all possible strategies — that is, all sequences &lt;code class="docutils literal"&gt;[a1, a2, … am]&lt;/code&gt; with &lt;span class="math"&gt;\(0 &amp;lt; a_1 &amp;lt; a_2 &amp;lt; \ldots  &amp;lt; a_m &amp;lt;= 100\)&lt;/span&gt;. My code ran for 600k iterations before I decided to estimate the number of such sequences and found it was about  &lt;code class="docutils literal"&gt;2^100 = 10^30&lt;/code&gt;. Whoops.)&lt;/p&gt;
&lt;p&gt;Let &lt;span class="math"&gt;\(f(n)\)&lt;/span&gt; denote the optimal average running time of the &lt;code class="docutils literal"&gt;n&lt;/code&gt; floors case. Let’s say that we decide to pick the first floor as &lt;code class="docutils literal"&gt;p&lt;/code&gt;. If &lt;span class="math"&gt;\(k = p\)&lt;/span&gt;, then we need to try every floor below &lt;code class="docutils literal"&gt;p&lt;/code&gt;, so the cost is &lt;code class="docutils literal"&gt;p&lt;/code&gt;. If &lt;span class="math"&gt;\(k &amp;lt; p\)&lt;/span&gt;, then the cost is &lt;code class="docutils literal"&gt;1+k&lt;/code&gt;: 1 for trying the first glass at floor &lt;code class="docutils literal"&gt;p&lt;/code&gt;, which breaks, and &lt;code class="docutils literal"&gt;k&lt;/code&gt; tries with the second glass until it breaks. If &lt;span class="math"&gt;\(k &amp;gt; p\)&lt;/span&gt;, then we reduce to the &lt;span class="math"&gt;\(n-p\)&lt;/span&gt; floors case, so the cost is &lt;span class="math"&gt;\(f(n-p) + 1\)&lt;/span&gt;. To be optimal, we need to pick the p that minimizes the expected value of the cost, so:&lt;/p&gt;
&lt;div class="math"&gt;
\begin{equation*}
f(n) = \min_{p \in [1, n]} E[1+k | k &amp;lt; p] + \frac pn + (1- \frac pn)(f(n-p) + 1)
\end{equation*}
&lt;/div&gt;
&lt;div class="math"&gt;
\begin{equation*}
f(n) = \min_{p \in [1, n]} \frac{p-1}{n} + \frac{(p-1)p}{2n} + \frac pn + (1- \frac pn)(f(n-p) + 1)
\end{equation*}
&lt;/div&gt;
&lt;div class="math"&gt;
\begin{equation*}
f(n) = \min_{p \in [1, n]} \frac{p^2 + 3p - 2}{2n} + (1- \frac pn)(f(n-p) + 1)
\end{equation*}
&lt;/div&gt;
&lt;p&gt;I am not entirely sure how to “solve” for &lt;span class="math"&gt;\(f\)&lt;/span&gt;–maybe there is some slick trick, or maybe it just can’t be done. But it’s straightforward enough to write some code to compute it:&lt;/p&gt;
&lt;pre class="code python"&gt;&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-1"&gt;&lt;/a&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;poly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-2"&gt;&lt;/a&gt;  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-3"&gt;&lt;/a&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-4"&gt;&lt;/a&gt;&lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10000&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-5"&gt;&lt;/a&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-6"&gt;&lt;/a&gt;&lt;span class="n"&gt;g&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-7"&gt;&lt;/a&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-8"&gt;&lt;/a&gt;&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-9"&gt;&lt;/a&gt;  &lt;span class="n"&gt;min_f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-10"&gt;&lt;/a&gt;  &lt;span class="n"&gt;min_p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-11"&gt;&lt;/a&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-12"&gt;&lt;/a&gt;    &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;poly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-13"&gt;&lt;/a&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-14"&gt;&lt;/a&gt;      &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;poly&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-15"&gt;&lt;/a&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;min_f&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;min_f&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-16"&gt;&lt;/a&gt;      &lt;span class="n"&gt;min_f&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tmp&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-17"&gt;&lt;/a&gt;      &lt;span class="n"&gt;min_p&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-18"&gt;&lt;/a&gt;  &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_f&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mf"&gt;0.&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;
&lt;a name="rest_code_940f1020c337486384cfebdca97e129a-19"&gt;&lt;/a&gt;  &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;min_p&lt;/span&gt;
&lt;/pre&gt;&lt;p&gt;Saving the g vector is important if you want to actually know what the optimal algorithm looks like. You can read it off with something like&lt;/p&gt;
&lt;pre class="code python"&gt;&lt;a name="rest_code_72ea350769044afbbfe0606e6e680ef7-1"&gt;&lt;/a&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
&lt;a name="rest_code_72ea350769044afbbfe0606e6e680ef7-2"&gt;&lt;/a&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;a name="rest_code_72ea350769044afbbfe0606e6e680ef7-3"&gt;&lt;/a&gt;&lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;a name="rest_code_72ea350769044afbbfe0606e6e680ef7-4"&gt;&lt;/a&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;a name="rest_code_72ea350769044afbbfe0606e6e680ef7-5"&gt;&lt;/a&gt;  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;a name="rest_code_72ea350769044afbbfe0606e6e680ef7-6"&gt;&lt;/a&gt;  &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;p&gt;Bonus:&lt;/p&gt;
&lt;p&gt;Here is a graph of how &lt;span class="math"&gt;\(g\)&lt;/span&gt; behaves. As with &lt;span class="math"&gt;\(f\)&lt;/span&gt;, I don’t know how to write it down, but it should track &lt;span class="math"&gt;\(1/\sqrt{n}\)&lt;/span&gt; fairly closely.&lt;/p&gt;&lt;/div&gt;</description><category>brain-teasers</category><category>cs</category><category>math</category><guid>https://siweizhu.com/posts/2-cups-100-floors/</guid><pubDate>Fri, 28 Aug 2015 07:00:00 GMT</pubDate></item></channel></rss>