Skip to content

Instantly share code, notes, and snippets.

@Per48edjes
Last active November 14, 2023 20:19
Show Gist options
  • Save Per48edjes/301317d8af3f81cbf042981f5e0804aa to your computer and use it in GitHub Desktop.
Save Per48edjes/301317d8af3f81cbf042981f5e0804aa to your computer and use it in GitHub Desktop.
Journey optimizing my solution to Leetcode 887. Super Egg Drop
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"id": "14537de4-524a-42e9-8fe6-c53a7c1ffc7a",
"metadata": {},
"source": [
"# Super Egg Drop\n",
"\n",
"Ravi Dayabhai"
]
},
{
"cell_type": "markdown",
"id": "630fab73-0d79-4a7d-95ec-d42a95bbd355",
"metadata": {},
"source": [
"## Problem Statement\n",
"\n",
"You are given `k` identical eggs and you have access to a building with `n` floors labeled from 1 to `n`.\n",
"\n",
"You know that there exists a floor `f` where `0 <= f <= n` such that any egg dropped at a floor higher than `f` will break, and any egg dropped at or below floor `f` will not break.\n",
"\n",
"Each move, you may take an unbroken egg and drop it from any floor `x` (where `1 <= x <= n`). If the egg breaks, you can no longer use it. However, if the egg does not break, you may reuse it in future moves.\n",
"\n",
"Return the minimum number of moves that you need to determine with certainty what the value of `f` is."
]
},
{
"cell_type": "markdown",
"id": "2386c7c1-f0c7-4378-a56d-71066a760bef",
"metadata": {},
"source": [
"## Suboptimal Solution\n",
"\n",
"The following is an attempt to inspect the growth/behavior of the subproblems as the number of eggs and the floors vary."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "3de7fd4f-5e79-4192-b97e-21a133603aab",
"metadata": {},
"outputs": [],
"source": [
"from typing import Callable\n",
"import functools\n",
"import sys\n",
"\n",
"\n",
"# Set a new recursion limit (just to execute a large example)\n",
"new_limit = 5000\n",
"sys.setrecursionlimit(new_limit)\n",
"\n",
"# Define a custom cache that we can inspect\n",
"class ViewableCache:\n",
"\n",
" def __init__(self, func: Callable):\n",
" functools.update_wrapper(self, func)\n",
" self.func = func\n",
" self.memo = {}\n",
"\n",
" # Only works for functions with positional arguments...\n",
" def __call__(self, *args):\n",
" param_key = tuple(args)\n",
" if param_key not in self.memo:\n",
" self.memo[param_key] = self.func(*args)\n",
" return self.memo[param_key]\n",
"\n",
"\n",
"@ViewableCache\n",
"def superEggDrop(k: int, n: int) -> int:\n",
" if k == 1:\n",
" return n\n",
" return min(\n",
" (1 + max(\n",
" # Case: Egg survives drop from floor f => Go \"up\"\n",
" superEggDrop(k, n-f),\n",
" # Case: Egg breaks on drop from floor f => Go \"down\"\n",
" superEggDrop(k-1, f-1)\n",
" ) \n",
" for f in range(1, n+1)\n",
" ), \n",
" default=0\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "7caac8ab-667c-471b-be9e-03bb7274904b",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"10"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Run a few examples\n",
"superEggDrop(1, 500)\n",
"superEggDrop(2, 500)\n",
"superEggDrop(3, 500)\n",
"superEggDrop(4, 500)\n",
"superEggDrop(5, 500)\n",
"superEggDrop(6, 500)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "1d294e4a-060b-4311-89d6-a0705b4d744b",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Show all rows\n",
"pd.set_option('display.max_rows', None)\n",
"\n",
"# Collect call data into dataframe\n",
"data = {k: v for k, v in superEggDrop.memo.items()}\n",
"index = pd.MultiIndex.from_tuples(data.keys(), names=['Eggs', 'Floors'])\n",
"df = pd.DataFrame(data.values(), index=index, columns=['Drops'])\\\n",
" .unstack(level=-1)\\\n",
" .transpose()\\\n",
" .sort_values('Floors', ascending=False)\n",
"df.index = df.index.droplevel()"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "984851fb-0878-4b92-a1e4-928f322a6bf7",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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EVFbW/u23bve+vqta/aksbExampqSo75v38p2zcIAECPUFFZ0W2P1OQWTs4+++xYt25drF27tuM4+eST46KLLur45z59+sSKFSs6vmf9+vWxcePGqKuri4iIurq6WLduXWzZsqXjmuXLl0d1dXWMHz/+He/d0NAQra2tJcfnDx/WeW8WAAB4V7kt6xo0aFAcf/zxJecGDBgQQ4cO7Th/2WWXxdy5c2PIkCFRXV0dV155ZdTV1cWpp54aERFTpkyJ8ePHx8UXXxy33357NDc3x/XXXx/19fVRVVX1jveuqqp62+svW9IFAAC5SvoT4u+8886orKyMWbNmRaFQiKlTp8a9997b8XqvXr1iyZIlccUVV0RdXV0MGDAgZs+eHbfeemuOVQMA0KMkuCVvd1VRLBaLeReRgt+eMeHdL+KgMWDZ3LxLoAs98+q/5V0CXWhr4Y95l0AXenWnzzXrST573L3vflEOdlxzTt4lHLABdy7Pu4QS1jIBAABJEE4AAIAkJD1zAgAAqUtxS97uSucEAABIgnACAAAkQTgBAACSYOYEAADK0cvf+7PiSQIAAEkQTgAAgCQIJwAAUI7Kiu577KPGxsY45ZRTYtCgQTF8+PCYMWNGrF+/vuSaM888MyoqKkqOz3/+8/v3KPfragAAoMdZuXJl1NfXx6pVq2L58uWxe/fumDJlSuzYsaPkus997nOxefPmjuP222/fr/sYiAcAAPZq2bJlJV8vXLgwhg8fHmvWrIkzzjij4/whhxwStbW1B3wfnRMAAOihCoVCbNu2reQoFArv+n2tra0RETFkyJCS89///vfj0EMPjeOPPz4aGhrij3/8437VI5wAAEAZKnpVdNujsbExampqSo7Gxsa9vt/29va4+uqr47TTTovjjz++4/ynPvWp+N73vhc///nPo6GhIb773e/Gpz/96f16lpZ1AQBAD9XQ0BBz584tOVdVVbXX76mvr49f/epX8dhjj5Wcv/zyyzv++YQTToiRI0fG2WefHc8//3wcddRR+1SPcAIAAD1UVVXVu4aRPzVnzpxYsmRJPProo3HYYYft9dpJkyZFRMSGDRuEEwAA6BL7sSVvd1UsFuPKK6+MBx54IB555JEYM2bMu37P2rVrIyJi5MiR+3wf4QQAANir+vr6WLRoUTz44IMxaNCgaG5ujoiImpqa6N+/fzz//POx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AMCfsawLAABIgnACAAAkwbIuAAAog885yY7OCQAAkAThBAAASIJlXQAAUAZbCWdH5wQAAEiCcAIAACRBOAEAAJJg5gQAAMpQNHOSGZ0TAAAgCbmGk8bGxjjllFNi0KBBMXz48JgxY0asX7++5JqdO3dGfX19DB06NAYOHBizZs2KlpaWkms2btwY06dPj0MOOSSGDx8e1157bbzxxhtd+VYAAIAy5RpOVq5cGfX19bFq1apYvnx57N69O6ZMmRI7duzouOaaa66Jhx56KO6///5YuXJlbNq0KWbOnNnxeltbW0yfPj127doVTzzxRHz729+OhQsXxo033pjHWwIAoIdp78b/SU1FsVgs5l3EW1566aUYPnx4rFy5Ms4444xobW2NYcOGxaJFi+LjH/94REQ8++yzceyxx0ZTU1OceuqpsXTp0vjoRz8amzZtihEjRkRExPz58+O6666Ll156Kfr27btP9y6uu7mz3hYJ+vl7duVdAl3ot61b8y6BLvTy6+n9ny2Qjf968vy8S9ij51rvyLuEAza2Zm7eJZRIauaktbU1IiKGDBkSERFr1qyJ3bt3x+TJkzuuGTduXIwePTqampoiIqKpqSlOOOGEjmASETF16tTYtm1bPPPMM11YPQAAUI5kwkl7e3tcffXVcdppp8Xxxx8fERHNzc3Rt2/fGDx4cMm1I0aMiObm5o5r/jSYvPX6W68BAADdQzJbCdfX18evfvWreOyxxzr9XoVCIQqFQsm5vrveiKq+yTwOAAC6CVsJZyeJzsmcOXNiyZIl8fOf/zwOO+ywjvO1tbWxa9eu2Lp1a8n1LS0tUVtb23HNn+/e9dbXb13z5xobG6OmpqbkaPznzg9FAADAO8s1nBSLxZgzZ0488MAD8bOf/SzGjBlT8vrEiROjT58+sWLFio5z69evj40bN0ZdXV1ERNTV1cW6detiy5YtHdcsX748qqurY/z48Xu8b0NDQ7S2tpYcDZ89vRPeIQAAsK9yXcdUX18fixYtigcffDAGDRrUMSNSU1MT/fv3j5qamrjsssti7ty5MWTIkKiuro4rr7wy6urq4tRTT42IiClTpsT48ePj4osvjttvvz2am5vj+uuvj/r6+qiqqtrjfauqqt72WtGSLgAAyFWu/0Y+b968iIg488wzS84vWLAgLr300oiIuPPOO6OysjJmzZoVhUIh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AABJEE4AAIAkWNYFAABlsJNwdnROAACAJAgnAABAEizretP23X/IuwQAAOjRhBMAACiDrYSzY1kXAACQBOEEAABIQq7h5NFHH43zzjsvRo0aFRUVFbF48eKS14vFYtx4440xcuTI6N+/f0yePDmee+65kmteffXVuOiii6K6ujoGDx4cl112WWzfvr0L3wUAAD1Ze7HYbY/U5BpOduzYESeeeGLcc889e3z99ttvj7vvvjvmz58fTz75ZAwYMCCmTp0aO3fu7LjmoosuimeeeSaWL18eS5YsiUcffTQuv/zyrnoLAABARnIdiJ82bVpMmzZtj68Vi8W466674vrrr4/zzz8/IiK+853vxIgRI2Lx4sXxyU9+Mn7zm9/EsmXLYvXq1XHyySdHRMTXv/71+MhHPhJf/epXY9SoUV32XgAAgPIkO3PywgsvRHNzc0yePLnjXE1NTUyaNCmampoiIqKpqSkGDx7cEUwiIiZPnhyVlZXx5JNPdnnNAADAgUt2K+Hm5uaIiBgxYkTJ+REjRnS81tzcHMOHDy95vXfv3jFkyJCOa/akUChEoVAoPde2O6qq+mRROgAAPYithLOTbOekMzU2NkZNTU3JcfdXf5x3WQAA0KMlG05qa2sjIqKlpaXkfEtLS8drtbW1sWXLlpLX33jjjXj11Vc7rtmThoaGaG1tLTmu+sL0jN8BAACwP5INJ2PGjIna2tpYsWJFx7lt27bFk08+GXV1dRERUVdXF1u3bo01a9Z0XPOzn/0s2tvbY9KkSe/4s6uqqqK6urrksKQLAADylevMyfbt22PDhg0dX7/wwguxdu3aGDJkSIwePTquvvrq+PKXvxxjx46NMWPGxA033BCjRo2KGTNmRETEscceG+eee2587nOfi/nz58fu3btjzpw58clPftJOXQAAdIm2BD8vpLvKNZw8/fTT8eEPf7jj67lz50ZExOzZs2PhwoXxxS9+MXbs2BGXX355bN26NU4//fRYtmxZ9OvXr+N7vv/978ecOXPi7LPPjsrKypg1a1bcfffdXf5egHS9/Hpb3iUAAPugolgU9SIiWv64MO8S6EIPvfBU3iXQhZ59dXfeJQCQga9+6Jt5l7BHn11xWd4lHLB/PvtbeZdQItmthAEAoDtoa8+7goNHsgPxAABAzyKcAAAASRBOAACAJJg5AQCAMthKODs6JwAA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WhXHHXdcTlXR2bZv3x4XXXRRfPOb34wvf/nLeZdDJ+rdu3fU1tbmXQZd4O///u/j8MMPjwULFnScGzNmTI4VQefQOenhWltbIyJiyJAhOVdCZ2tra4v77rsvduzYEXV1dXmXQyeqr6+P6dOnx+TJk/MuhU723HPPxahRo+LII4+Miy66KDZu3Jh3SXSS//W//lecfPLJ8Vd/9VcxfPjw+Mu//Mv45je/mXdZkDmdkx6svb09rr766jjttNPi+OOPz7scOsm6deuirq4udu7cGQMHDowHHnggxo8fn3dZdJL77rsvfvGLX8Tq1avzLoVONmnSpFi4cGEcc8wxsXnz5rjlllviQx/6UPzqV7+KQYMG5V0eGfvtb38b8+bNi7lz58aXvvSlWL16dVx11VXRt2/fmD17dt7lQWZ8QnwPdsUVV8TSpUvjsccei8MOOyzvcugku3btio0bN0Zra2v86Ec/in/+53+OlStXCigHod///vdx8sknx/LlyztmTc4888w46aST4q677sq3ODrd1q1b44gjjog77rgjLrvssrzLIWN9+/aNk08+OZ544omOc1dddVWsXr06mpqacqwMsmVZVw81Z86cWLJkSfz85z8XTA5yffv2jaOPPjomTpwYjY2NceKJJ8bXvva1vMuiE6xZsya2bNkS73//+6N3797Ru3fvWLlyZdx9993Ru3fvaGtry7tEOtHgwYPjfe97X2zYsCHvUugEI0eOfNsflY499lhL+TjoWNbVwxSLxbjyyivjgQceiEceecQwXQ/U3t4ehUIh7zLoBGeffXasW7eu5NxnPvOZGDduXFx33XXRq1evnCqjK2zfvj2ef/75uPjii/MuhU5w2mmnvW3r/3/7t3+LI444IqeKoHMIJz1MfX19LFq0KB588MEYNGhQNDc3R0RETU1N9O/fP+fqyFpDQ0NMmzYtRo8eHa+99losWrQoHnnkkXj44YfzLo1OMGjQoLfNjw0YMCCGDh1qruwg9IUvfCHOO++8OOKII2LTpk1x0003Ra9eveLCCy/MuzQ6wTXXXBMf/OAH4+/+7u/iE5/4RDz11FPxjW98I77xjW/kXRpkSjjpYebNmxcR/28d+p9asGBBXHrppV1fEJ1qy5Ytcckll8TmzZujpqYmJkyYEA8//HCcc845eZcGlOnFF1+MCy+8MF555ZUYNmxYnH766bFq1aoYNmxY3qXRCU455ZR44IEHoqGhIW699dYYM2ZM3HXXXXHRRRflXRpkykA8AACQBAPxAABAEoQTAAAgCcIJAACQBOEEAABIgnACAAAkQTgBAACSIJwAAABJEE4AAIAkCCcAibr00kujoqLibce5556bd2kA0Cl6510AAO/s3HPPjQULFpScq6qqyqkaAOhcOicACauqqora2tqS4z3veU9ERDz77LNx+umnR79+/WL8+PHx05/+NCoqKmLx4sUd3//EE0/ESSedFP369YuTTz45Fi9eHBUVFbF27dqIiPjDH/4QF110UQwbNiz69+8fY8eOfVsYAoCuonMC0A21tbXFjBkzYvTo0fHkk0/Ga6+9Fv/lv/yXkmu2bdsW5513XnzkIx+JRYsWxe9+97u4+uqrS6654YYb4te//nUsXbo0Dj300NiwYUO8/vrrXfhOAOD/E04AErZkyZIYOHBgybkvfelL8f73vz+ef/75eOSRR6K2tjYiIr7yla/EOeec03HdokWLoqKiIr75zW92dFf+/d//PT73uc91XLNx48b4y7/8yzj55JMjIuK9731v578pAHgHwglAwj784Q/HvHnzSs4NGTIkvvvd78bhhx/eEUwiIj7wgQ+UXLd+/fqYMGFC9OvX7x2vueKKK2LWrFnxi1/8IqZMmRIzZsyID37wg53wTgDg3QknAAkbMGBAHH300Z3286dNmxa/+93v4ic/+UksX748zj777Kivr4+vfvWrnXZPAHgnBuIBuqFjjjkmfv/730dLS0vHudWrV7/tmnXr1kWhUHjHayIihg0bFrNnz47vfe97cdddd8U3vvGNziscAPZCOAFIWKFQiObm5pLj5ZdfjnPOOSeOOuqomD17dvzyl7+Mxx9/PK6//vqIiKioqIiIiE996lPR3t4el19+efzmN7+Jhx9+uKMj8tY1N954Yzz44IOxYcOGeOaZZ2LJkiVx7LHH5vNmAejxhBOAhC1btixGjhxZcpx++unRq1evWLx4cWzfvj1OOeWU+OxnPxt/8zd/ExHRMWNSXV0dDz30UKxduzZOOumk+Ju/+Zu48cYbS67p27dvNDQ0xIQJE+KMM86IXr16xX333ZfPmwWgx6soFovFvIsAoHyPP/54nH766bFhw4Y46qij9njN97///fjMZz4Tra2t0b9//y6uEAD2zkA8QDf1wAMPxMCBA2Ps2LGxYcOG+Ou//us47bTTSoLJd77znTjyyCPjL/7iL+Jf//Vf47rrrotPfOITggkASRJOALqp1157La677rrYuHFjHHrooTF58uT4x3/8x5Jrmpub48Ybb4zm5uYYOXJk/NVf/VV85StfyaliANg7y7oAAIAkGIgHAACSIJwAAABJEE4AAIAkCCcAAEAShBMAACAJwgkAAJAE4QQAAEiCcAIAACRBOAEAAJLwfwF8NhaobU1AoAAAAABJRU5ErkJggg==",
"text/plain": [
"<Figure size 1000x1200 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import seaborn as sns\n",
"import numpy as np\n",
"%matplotlib inline\n",
"\n",
"# Plot heatmap\n",
"plt.figure(figsize=(10, 12))\n",
"g = sns.heatmap(df.drop(labels=[1], axis=1), cmap='RdYlGn_r')\n",
"plt.yticks(np.arange(min(df.index), max(df.index)+1, 100), labels=df.index[::100])\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "b949ce20-6b40-4f1e-8bf4-6a2045ddfa46",
"metadata": {},
"source": [
"**Observation**: Looks like these uniform \"blocks\" of a given color span many floors (for sufficiently large $k, n$), which means all of those calls return the same number of drops!\n",
"\n",
"The same observation stated differently by fellow Recurser, AdamL (SP1'23):\n",
"\n",
"\n",
">I could be wrong on this but my thoughts are that to reduce the search space you have to skip floors. But the question of how many floors you can skip is a function of how many eggs you have. For example if you only have one egg you have to start at the bottom and never skip a floor. But if you have two eggs you start at the bottom and can skip 1 floor at a time, because if you try floor one and it doesn't break, you can go to floor three and if it breaks, you still have an egg to go back to floor two and test it.\n",
"\n",
">so I wonder if there is some function that tells us the number of floors we can skip per number of eggs. Then if you could use that to prune the search space somehow?\n"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "314214cf-5ba7-4b2d-b4b4-3b1545adef79",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAA1YAAAIRCAYAAABJdiwLAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAACN/0lEQVR4nOzdd3hUZfrG8e/0SSY9kELoHZQuCK6gi13RFXVXXXWVn65119W1bXHtdWUtq6trL2t3VWxr7yjSQZBO6CEJhPSZTD2/P5IMhATIJDOZlPtzXVzCnDPnPOORmDvv+z6vyTAMAxEREREREWkxc7wLEBERERER6egUrERERERERFpJwUpERERERKSVFKxERERERERaScFKRERERESklRSsREREREREWknBSkREREREpJUUrPayevVqVq9eHe8yRERERESkA1Gw2ovP56Oqqgqv1xvvUiTKvF4vCxcu1LPthPRsOy89285Lz7bz0rPt3PR8903Bah+CwWC8S5Aoq3+meradj55t56Vn23np2XZeeradm57vvilYiYiIiIiItJKClYiIiIiISCspWImIiIiIiLSSgpWIiIiIiEgrKViJiIiIiIi0kjXeBYiIiIiISPsQDAbx+/37PF7fZt3r9WI2d/wxGpvNhsViicq1FKxERERERLo4wzAoLCykrKxsv+eFQiGsVisFBQWdIlgBpKWlkZOTg8lkatV1FKxERERERLq4+lCVlZVFYmLiPkNGMBjE6/XicDiiNtITL4Zh4Ha7KS4uBiA3N7dV11OwEhERERHpwoLBYDhUZWZmHvBcAKfT2eGDFUBCQgIAxcXFZGVlteozdY7xOxERERERaZH6NVWJiYlxriQ+6j/3/taWNYeClYiIiIiItHqNUUcVrc+tYCUiIiIiItJKClYiIiIiIiKtpOYVIiIiIiLSIn/60594++2393m8W7dufPfdd21YUfwoWImIiIiISIt1796dRx55pMljNputjauJHwUrERERERFpMbvdzujRo+NdRtxpjZWIiIiIiMTc008/zVFHHcXIkSM566yz+OKLLxgyZAhz584Nn/PVV19x2mmnMXLkSI477jjef/99jjnmGB5++OHwOc8//zzHH388I0aMYPLkydxyyy1UVVXF4yM1oBErERERERFplUAg0OTrFosFk8nEI488wr/+9S8uvPBCJk6cyLfffstVV13V4NwffviByy+/nJ///Of84Q9/YNOmTdx88814vd7wOe+//z733XcfN9xwA0OGDCE/P597770Xj8fDvffeG8uPeEAKViIiIiIi0mLbtm3joIMOavLY9ddfz9lnn82TTz7JOeecw7XXXgvA4Ycfjsfj4bXXXguf+/DDDzNo0CAeeeSR8N5SmZmZ/PGPfwyfM2/ePHr27Mk555yD2WxmwoQJJCYmUl5eHsNP2DwKViIScwVbyvjfm8s4+uTh9B2QGe9yREREJIq6d+/OY4891uSx3NxclixZQk1NDccff3yDY9OmTQsHK5/Px+LFi7niiisabNh7/PHHc/3114f/PHHiRF577TVOO+00jj76aI444ghOPvnkdrG5sYKViMTcskXbKNhSzvpVxQpWIiIinYzdbmfEiBH7PP7DDz8AkJGR0eD1zMzd3xOUlZURDAYbvAa1UwnT0tLCfz7xxBMJhUK8/PLLPProozz88MPk5eVx7bXXcuKJJ0bh07ScmleISMyVl3oASE51xrkSERERaWs5OTkAlJSUNHh9165d4d9nZmZis9nYuXNng3NCoRBlZWUNXps2bRovv/wyc+fO5cEHHyQtLY3rrruOoqKi2HyAZlKwEpGYqw9WqWkJca5ERERE2trQoUNJTk7m008/bfD6J598Ev69xWJh7NixfP755w3O+eKLLxo0xrjqqqu44oorAEhOTuaEE07g8ssvJxAIUFxcHMNPcWCaCigiMRcOVhmJca5EREREos3n87FkyZJ9Hh8yZAgXXXQR//znP0lISGDChAnMmzePV155BQCzuXas58orr+S8887jyiuv5IwzzqCgoICHHnoIILyGauLEidx8883ce++9TJkyhYqKCh555BH69u3L0KFDY/tBD0DBSkRiyucN4K72AZCWrhErERGRzmbHjh2ceeaZ+zw+a9YsLrnkEgzD4LXXXuPpp59m1KhRXHvttdx9990kJtb+4PWQQw7h4Ycf5qGHHuLyyy8nLy+Pv/3tb1x99dW4XC4AzjrrLPx+P6+++iovv/wyTqeTSZMmcd1112Gz2drk8+6LgpWIxFRFWQ0AdocVh1NfckRERDqTe+65h3vuuWe/5wQCAd555x1OPfVULrvssvDrL730EmazmV69egHw+eefk5uby3vvvRc+Z+3atQD07t07/Np5553HeeedF82PERX6LkdEYqqs1A3Ujla1h1aoIiIi0rasVitPPvkkzz//PJdddhnp6emsWbOGBx98kFNPPZWUlBQAZs+ezf/+9z+uvfZa+vXrR1FREY899hj9+/fn8MMPj/OnODAFKxGJqfr1VSmaBigiItJl/fvf/+b+++/nlltuoaKigh49enD++edzySWXhM+54YYbcDqdPPbYYxQXF5OWlsbkyZO55pprcDgccay+eRSsRCSmystqg5XWV4mIiHRdvXr14oEHHtjvOU6nkxtuuIEbbrihjaqKLrVbF5GYCncEVLASERGRTkzBSkRiSntYiYiISFegYCUiMaURKxEREekKFKxEJGZCwRAV5bXt1lMzFKxERESk81KwEpGYqazwYoQMzGYTScnOeJcjIiIiEjMKViISM+FW62kJmM3aw0pEREQ6LwUrEYmZ8rrNgbW+SkRERNpCWVkZN910E1OmTGHs2LGcffbZLFiwoE3urWAlIjFTXla3vkrBSkRERNrAH//4RxYvXsz999/Pm2++ybBhw7jwwgvJz8+P+b0VrEQkZjRiJSIiIm1l06ZNfPfdd9xyyy0ccsgh9OvXj7/97W9kZWXx3nvvxfz+1pjfQUS6rLK6NVZpClYiIiIdjmEYeH3BBq8FQ0FqfEEwB7CYjZje32G3YDI1f412eno6TzzxBCNGjAi/ZjKZMJlMVFRUxKLEBhSsRCRmKvZoXiEiIiIdh2EY3PDIbFZu3BW3Gob1zeDe3x3e7HCVkpLCEUcc0eC1jz/+mE2bNvGXv/wlFiU2oKmAIhIThmHsHrHSHlYiIiLSxhYtWsSf//xnjj32WI488siY308jViISEx63H3/d9AGNWImIiHQsJpOJe393eNNTAWu8OJ0OLGZLTGuIdCrgnj777DOuvfZaxo4dy8yZM6NcWdMUrEQkJur3sHIl2bHZYvuFV0RERKLPZDLhdDSMC8GgCUIBnHYrFkv7/P/7iy++yJ133snxxx/Pvffei91ub5P7aiqgiMREfbBSR0ARERFpKy+//DK3334755xzDvfff3+bhSrQiJWIxEh5mYKViIiItJ0NGzZw1113ccwxx3DJJZewc+fO8DGn00lycnJM769gJSIxsXvEKjHOlYiIiEhX8PHHH+P3+/n000/59NNPGxybPn0699xzT0zvr2AlIjGhzYFFRESkLV166aVceumlcbu/1liJSEyER6zUEVBERES6AAUrEYkJNa8QERGRrkTBSkSizu8PUl3lA7Q5sIiIiHQNClYiEnUVdR0BbXYLzgRbnKsRERERiT0FKxGJurJdtcEqLT2hxTumi4iIiHQkClYiEnX166tStL5KREREuggFKxGJuvrNgdMUrERERKSLiHuwKisr46abbmLKlCmMHTuWs88+mwULFoSPz5kzh9NOO41Ro0Zx/PHH88EHHzR4v9fr5dZbb2XSpEmMGTOGa665hl27drX1xxCRPWhzYBEREelq4h6s/vjHP7J48WLuv/9+3nzzTYYNG8aFF15Ifn4+69ev55JLLmHy5Mm89dZb/PKXv+T6669nzpw54fffcsstzJ49m4cffpjnn3+e/Px8rrzyyjh+IhEJbw6c5oxzJSIiIiJtwxrPm2/atInvvvuOl19+mXHjxgHwt7/9jW+//Zb33nuPkpIShgwZwtVXXw3AgAEDWLFiBU899RSTJk2iqKiIWbNm8e9//5tDDjkEgPvvv5/jjz+exYsXM2bMmLh9NpGurLy0BtCIlYiIiHQdcQ1W6enpPPHEE4wYMSL8mslkwmQyUVFRwYIFCzj66KMbvGfixInceeedGIbBwoULw6/V69evH9nZ2cyfP79Vwcrj8bT4vdI+1T9TPdvYCoWMcLt1ewK43e6Y31PPtvPSs+289Gw7Lz3bjsfr9RIKhQgGgwSDwf2eaxhG+J8HOjdeSkpK+Pvf/87s2bOpqalh/PjxXH/99fTv37/J84PBIKFQCI/HQygUanQ8MbF5PyiOa7BKSUnhiCOOaPDaxx9/zKZNm/jLX/7C22+/TU5OToPjWVlZeDweSktLKSoqIj09HYfD0eicwsLCVtW2cePGVr1f2i8929iqcQcJhQxMJtiyNR9zQdu1W9ez7bz0bDsvPdvOS8+2Y7FarXi93mafH8m5be2KK64gFArxz3/+k4SEBB577DFmzJjBrFmzSEho3FjL6/USCATIz89v8nr1M+sOJK7Bam+LFi3iz3/+M8ceeyxHHnkkNTU12O32BufU/9nn8+HxeBodB3A4HK1+2H379m3yX7x0XB6Ph40bN+rZxti2zeVAMcmpTg46aHib3FPPtvPSs+289Gw7Lz3bjsfr9VJQUIDD4cDp3P/6aMMw8Hq9OByOdrlXZXl5Ob169eLiiy9m0KBBQG3QOu2009i6dWuDmXJ7slqt9O7du9GATSTaTbD67LPPuPbaaxk7diwzZ84EagOSz+drcF79nxMSEnA6nY2OQ+1/HK39i5yQkNDsYT/pWPRsY8vrLgUgLSOxzf8969l2Xnq2nZeebeelZ9txmM1mzGYzFosFi8USft0wDAx/w8GKUDCI4fdimMG8x7mxYLJFHt4yMjK4//77w3/etWsX//nPf8jJyWHw4MENPl89i8WC2WwO54uWahfB6sUXX+TOO+/k+OOP59577w2PQuXm5lJcXNzg3OLiYhITE0lOTiYnJ4eysjJ8Pl+Dkavi4mKys7Pb9DOISK36PaxStYeViIhIh2UYBgUv/BXv1tVxq8HRcyg9fnNHi0fG/va3v/H6669jt9t57LHHYh70495u/eWXX+b222/nnHPO4f77728QkA455BDmzZvX4PwffviBsWPHYjabGTduHKFQKNzEAmDDhg0UFRUxfvz4NvsMIrLb7j2sFKxEREQ6tvY31S8S559/Pm+++SbTpk3jiiuu4Kefforp/eI6YrVhwwbuuusujjnmGC655BJ27twZPuZ0OjnvvPOYPn06M2fOZPr06Xz99dd89NFHPPXUUwBkZ2dz0kknceONN3LXXXeRkJDAzTffzIQJExg9enScPpVI11ZWH6zSFKxEREQ6KpPJRI/f3NFoKmAwGAyvsWpqWl1Ua2jBVMA9DRw4EIA777yTpUuX8uKLL3L33XdHq7xG4hqsPv74Y/x+P59++imffvppg2PTp0/nnnvu4dFHH+W+++7j+eefp2fPntx3331MmjQpfN7tt9/OXXfdxe9+9zsApkyZwo033timn0NEdqvQiJWIiEinYDKZMNkbrjkygkFMITDbnTFfY9USu3btYs6cORx33HFYrbVRx2w2M3DgwEZLjKItrsHq0ksv5dJLL93vOVOmTGHKlCn7PJ6YmMgdd9zBHXfcEe3yRCRChmGER6zStDmwiIiItLGdO3fyxz/+kaeeeorJkycD4Pf7WbFiBVOnTo3pveO+xkpEOo8ajx+fNwBASlrLu+qIiIiItMTgwYOZMmUKd9xxB/Pnz2fNmjX86U9/oqKiggsuuCCm91awEpGoKS+rASDRZcfuaBdNR0VERKSLuf/++5k0aRJXX301v/zlLykrK+Oll16iR48eMb2vvvMRkagp3+UGtL5KRERE4ic5OZlbbrmFW265pU3vqxErEYka7WElIiIiXZWClYhEjfawEhERka5KwUpEokbBSkRERLoqBSsRiZpybQ4sIiIiXZSClYhEjUasREREpKtSsBKRqAj4g1RVegFtDiwiIiJdj4KViERFRXntHlZWm5kEly3O1YiIiIi0LQUrEYmKsl210wDT0hMxmUxxrkZERESkbSlYiUhUlJfWbg6cosYVIiIi0gUpWIlIVNRvDpyWoWAlIiIiXY+ClYhEhToCioiISHuyYcMGxowZw1tvvdUm91OwEpGo0B5WIiIi0l74/X6uvfZa3G53m91TwUpEokIjViIiItJePPzwwyQlJbXpPa1tejcR6ZSMkEFFWW27dQUrERGRzsEwDLxBX4PXgsEg3oAXAiYshiWm93dY7C3qNDx//nxee+01Zs2axZFHHhn9wvZBwUpEWq2qykswGMJkguRUZ7zLERERkVYyDIObPp/J6pL8uNUwpNsAbpt6TUThqqKiguuvv54bb7yR3NzcGFbXmKYCikir1U8DTE51YrHoy4qIiEin0AH3pbzlllsYM2YMJ598cpvfWyNWItJq5bvq11clxrkSERERiQaTycRtU69peipgTQ0OpxOLpX1NBZw1axYLFizgvffei2FV+6ZgJSKtVr+HVWqapgGKiIh0FiaTCafV0eC1oCkIVgOn1RHzYBWpN998k5KSkkbrqm6++Wb+97//8dRTT8X0/gpWItJq5aW1rUxTMzRiJSIiIvExc+ZMampqGrx27LHHcuWVV3LKKafE/P4KViLSamXaw0pERETiLDs7u8nXMzMz93ksmrTKXERarUJ7WImIiEgXpxErEWm1+hGrNAUrERERaUdWr17dZvfSiJWItEqNx4+3JgBoxEpERES6LgUrEWmV+o6ACYk27A4NgouIiEjXpGAlIq1SrvVVIiIiIgpWItI65eoIKCIiIqJgJSKtEw5WGQpWIiIi0nUpWIlIq+yeCqjNgUVERKTrUrASkVbZPRXQGedKREREROJHwUpEWqW81A1oxEpERES6NgUrEWmxYCBEZaUX0ObAIiIi0rVp0xkRabGKcg8YYLWaSUyyx7scEREREYqKipgyZUqj1++++25OO+20mN1XwUpEWqxsjz2sTCZTnKsRERERgVWrVuFwOPjss88afH+SnJwc0/sqWIlIi5Xvqg1WKdrDSkRERNqJNWvW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5sDhaYBaXyUiIiJdgIKViBxQKBiiorwGgNT05nUAUkdAERER6UoUrETkgCorvBghA7PFRHJyM4OVGleIiIhIF6JgJSIHVFbqBmpbrZvMpgOeH/L58GzdBoCrX7+Y1iYiIiLSHihYicgBVdStr0pp5h5W7i1bMYJBrMlJ2DMzYlmaiIiISLugYCUiB1RWF6zSmtkRcM/GFSbTgUe4RERERDq6dhWsHn/8cc4777wGr914440MGTKkwa+pU6eGj4dCIf75z38yefJkRo8ezW9/+1u2bNnS1qWLdGqR7mGlxhUiIiLS1bSbYPXSSy/x4IMPNnp99erVXHrppcyePTv867///W/4+KOPPsrLL7/M7bffzquvvkooFOKiiy7C5/O1YfUinVuke1ipcYWIiIh0NXEPVkVFRVx66aXMnDmTvnvtd2MYBuvWrePggw+me/fu4V8ZGbVrNnw+H8888wxXXnklRx55JEOHDuWBBx6gsLCQTz75JA6fRqRzimTEyjCMPYKVGleIiIhI1xD3YPXTTz9hs9l49913GTVqVINjmzdvxu12079//ybfu2rVKqqrq5k0aVL4tZSUFIYPH878+fNjWrdIV2EYRkTByrtjB8HqakxWKwk982JdnoiIiEi7YI13AVOnTm2wZmpPa9asAeA///kP33zzDWazmSlTpnD11VeTnJxMYWEhALm5uQ3el5WVFT7WUh6Pp1Xvl/an/pnq2UbG4/bj9wUBsNkN3G73fs8vX1X799bRI5cavx/8/tjXqGfbaenZdl56tp2Xnm3n1hWfb2JiYrPOi3uw2p81a9ZgNpvJysri3//+N5s3b+bvf/87a9eu5fnnnw8/ULvd3uB9DoeD8vLyVt17Y93ie+l89GwjU76rNhg5nGbWrltzwPMDCxcC4EtLY+XKlTGtbW96tp2Xnm3npWfbeenZdm5d6fmOGzeuWee162B12WWX8etf/5r09HQABg8eTPfu3fnVr37FsmXLcDqdQO1aq/rfA3i9XhISmrfIfl/69u3b6mtI++LxeNi4caOebYTWrtgB7CS9WxLDhg074Pn5H31COZA7cgRZzTg/GvRsOy89285Lz7bz0rPt3PR8961dByuz2RwOVfUGDRoEQGFhYXgKYHFxMb179w6fU1xczJAhQ1p174SEhGYP+0nHomcbmRp37TTA9AxXs/69eTdvBSBtyOA2//esZ9t56dl2Xnq2nZeebeem59tY3JtX7M/111/PBRdc0OC1ZcuWATBw4ECGDh1KUlISc+fODR+vqKhgxYoVjB8/vi1LFem0yiJoXBFwu6mpW9/o2qvLp4iIiEhn1q6D1XHHHcecOXN45JFH2Lx5M19//TV/+ctfmDZtGgMGDMBut3Puuecyc+ZMPv/8c1atWsXVV19NTk4Oxx57bLzLF+kUKiLYw8q9aTMA9swMbCnJMa1LREREpD1p11MBjzrqKB588EGeeOIJnnzySZKTkzn55JO56qqrwudceeWVBAIBbrzxRmpqahg/fjxPP/00NpstfoWLdCL1rdbTmhGstH+ViIiIdFXtKljdc889jV474YQTOOGEE/b5HovFwnXXXcd1110Xy9JEuqxIpgJWb9gAgKtvn5jWJCIiItLetOupgCISX35/EHeVD2husNoEgKu/RqxERESka1GwEpF9qp8GaHdYcCbsf3qtEQzi3lQXrNS4QkRERLoYBSsR2afy8DTAREwm037P9WzfTsjnw+xw4MzJbovyRERERNoNBSsR2adwsEpzHuDMPaYB9u2DyWKJaV0iIiIi7Y2ClYjs054jVgdS37giUdMARUREpAtSsBKRfSovdQPN3MNq40YAXP3UEVBERES6HgUrEdmn8gg2Bw5PBdQeViIiItIFNWsfq/nz50d00fHjx7eoGBFpX8qbuYeVv7wc365dYDLh6tO7LUoTERERaVeaFazOO++8fXYEMwwDoMHxlStXRqE0EYmnUMigoqwGgNS0/Qer6g0bAXDm5mBJOPDoloiIiEhn06xg9cILL4R/X1BQwN/+9jdOP/10TjjhBLp3705ZWRlffPEFr776KrfddlvMihWRtlNVUUMoZGA2m0hO3X9XwPpgpf2rREREpKtqVrCaMGFC+PfnnXceF1xwAddcc02Dc8aOHYvT6eTZZ5/lxBNPjG6VItLmyuqmAaakOTGb97+HVXW4cUXfGFclIiIi0j5F3Lzixx9/ZNKkSU0eGzNmDGvWrGl1USISfxXhYNWcxhUbAQUrERER6boiDlY5OTl8++23TR776KOP6N1bC9dFOoP6Eau0AzSuCPn9eLZuAzQVUERERLquZk0F3NOMGTO45ZZbKC4u5uc//znp6ens3LmTjz76iK+++or7778/FnWKSBtr7ubA7i1bMIJBrMlJ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qWHu3Lkd1omIiODYsWOcP3/errygoAAvLy/uu+8+W9lXX31lV2fPnj0YDAYmTpzIsWPHmDx5MiUlJRgMBkaNGkVSUhLBwcH8+uuvnXtgIiLSbWjxChER6TUuXbrE8ePHgZbV+erq6igsLGTHjh1Mnz6d6OjoDl/73HPPUVBQQHx8PMuXL2fw4MHs2rWLQ4cOkZWVZffDwsePHyc5OZkZM2ZQVlbGhg0bmD17NsOHD8fb2xtXV1dSUlIwmUx4enry3Xff8dNPP/Hss8/+2x+BiIg4ieFG69O8IiIiPVhcXBxFRUW2bYPBQP/+/QkODmbWrFk888wztoUroqKimDBhAmvWrLF7j8rKSnJycvj2229pbGxk5MiRvPDCCzz22GO2OiEhIcTHx1NVVcXXX3+Nh4cHs2fPJiEhwTbN8OzZs+Tk5HD06FGsViv3338/cXFxzJkzpws+CRERcQYlViIiIrchJCSE5cuXYzKZnB2KiIh0I3rGSkRERERExEFKrERERERERBykqYAiIiIiIiIO0h0rERERERERBymxEhERERERcZASKxEREREREQcpsRIREREREXGQEisREREREREHKbESERERERFxkBIrERERERERBymxEhERERERcdD/AGfhRYTDmOdyAAAAAElFTkSuQmCC",
"text/plain": [
"<Figure size 1000x600 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Group by number of eggs and # drops\n",
"long_df = df.unstack().reset_index()\n",
"long_df = long_df.rename(columns={0: 'Drops'})\n",
"grouped = long_df.groupby(['Eggs', 'Drops']).count()\n",
"grouped = grouped.unstack().transpose().droplevel(level=0)\n",
"plt.figure(figsize=(10, 6))\n",
"sns.set(style=\"whitegrid\", palette=\"deep\")\n",
"for column in grouped.iloc[:,1:].columns:\n",
" sns.lineplot(data=grouped[column].dropna()[:-1], label=column)\n",
"\n",
"plt.ylabel('Floors Spanned')\n",
"ax = plt.gca()\n",
"ax.spines['right'].set_visible(False)\n",
"ax.spines['top'].set_visible(False)\n",
"ax.spines['bottom'].set_position('zero')\n",
"ax.spines['left'].set_position('zero')\n",
"ax.set_xlim(left=0)\n",
"ax.set_ylim(bottom=0)\n",
"plt.legend(title='Eggs')\n",
"\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"id": "cbe2780b-9ca2-48da-adae-ee3704839d87",
"metadata": {},
"source": [
"### Triangular Numbers, Pascal, and More\n",
"\n",
"In the `grouped` table, there looks to be the following recurrence (much like Pascal's Triangle):\n",
"\n",
"$$\n",
"f(d, k) = f(d-1, k) + f(d-1, k-1)\n",
"$$\n",
"\n",
"And if we take a cumulative sum along the columns (where the number of eggs up to $k$ are columns), each $i$th entry is the number of floors spanned by $i$ minimal drops.\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7545c673-508a-4da6-8b65-d9dd0fcec034",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>Eggs</th>\n",
" <th>1</th>\n",
" <th>2</th>\n",
" <th>3</th>\n",
" <th>4</th>\n",
" <th>5</th>\n",
" <th>6</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Drops</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>3.0</td>\n",
" <td>4.0</td>\n",
" <td>4.0</td>\n",
" <td>4.0</td>\n",
" <td>4.0</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>4.0</td>\n",
" <td>7.0</td>\n",
" <td>8.0</td>\n",
" <td>8.0</td>\n",
" <td>8.0</td>\n",
" <td>8.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>5.0</td>\n",
" <td>11.0</td>\n",
" <td>15.0</td>\n",
" <td>16.0</td>\n",
" <td>16.0</td>\n",
" <td>16.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>6.0</td>\n",
" <td>16.0</td>\n",
" <td>26.0</td>\n",
" <td>31.0</td>\n",
" <td>32.0</td>\n",
" <td>32.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>7.0</td>\n",
" <td>22.0</td>\n",
" <td>42.0</td>\n",
" <td>57.0</td>\n",
" <td>63.0</td>\n",
" <td>64.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>8.0</td>\n",
" <td>29.0</td>\n",
" <td>64.0</td>\n",
" <td>99.0</td>\n",
" <td>120.0</td>\n",
" <td>127.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>9.0</td>\n",
" <td>37.0</td>\n",
" <td>93.0</td>\n",
" <td>163.0</td>\n",
" <td>219.0</td>\n",
" <td>247.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>10.0</td>\n",
" <td>46.0</td>\n",
" <td>130.0</td>\n",
" <td>256.0</td>\n",
" <td>382.0</td>\n",
" <td>466.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"Eggs 1 2 3 4 5 6\n",
"Drops \n",
"0 1.0 1.0 1.0 1.0 1.0 1.0\n",
"1 2.0 2.0 2.0 2.0 2.0 2.0\n",
"2 3.0 4.0 4.0 4.0 4.0 4.0\n",
"3 4.0 7.0 8.0 8.0 8.0 8.0\n",
"4 5.0 11.0 15.0 16.0 16.0 16.0\n",
"5 6.0 16.0 26.0 31.0 32.0 32.0\n",
"6 7.0 22.0 42.0 57.0 63.0 64.0\n",
"7 8.0 29.0 64.0 99.0 120.0 127.0\n",
"8 9.0 37.0 93.0 163.0 219.0 247.0\n",
"9 10.0 46.0 130.0 256.0 382.0 466.0"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"grouped.iloc[:10,:].cumsum()"
]
},
{
"cell_type": "markdown",
"id": "4d6c51d0-0496-4ab7-93a7-3deec2251b02",
"metadata": {},
"source": [
"So, finding the minimal number of drops $i$ to determine the breaking floor with $k$ eggs in hand for a building with $n$ floors amounts to finding the row $i$ in the above table where the entry in the $k$th column is greater than or equal to $n$!"
]
},
{
"cell_type": "markdown",
"id": "6bf64352-a616-4d4a-96d6-9b187f35d4cc",
"metadata": {},
"source": [
"What's interesting when grouping on the floors spanned by the same number of drops for a given $k$ is that the series for increasing $k$ are the same up to a (discrete) difference!\n",
"\n",
"For example, the numbers of floors spanned (as the number of required drops increases) for $k = 3$ is the same thing as the series for $k = 4$, with its first differences taken! Similarly, the result for $k = 2$ is the same as the series for $k=4$ with its second differences taken."
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "d64df2b1-f4fb-40c5-b870-0fafd6c6dd7e",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>4</th>\n",
" <th>3</th>\n",
" <th>2</th>\n",
" </tr>\n",
" <tr>\n",
" <th>Drops</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" <td>NaN</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>1.0</td>\n",
" <td>0.0</td>\n",
" <td>1.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" <td>1.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" <td>2.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5</th>\n",
" <td>3.0</td>\n",
" <td>3.0</td>\n",
" <td>3.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>6</th>\n",
" <td>4.0</td>\n",
" <td>4.0</td>\n",
" <td>4.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>7</th>\n",
" <td>5.0</td>\n",
" <td>5.0</td>\n",
" <td>5.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>8</th>\n",
" <td>6.0</td>\n",
" <td>6.0</td>\n",
" <td>6.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>9</th>\n",
" <td>7.0</td>\n",
" <td>7.0</td>\n",
" <td>7.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>10</th>\n",
" <td>8.0</td>\n",
" <td>8.0</td>\n",
" <td>8.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" 4 3 2\n",
"Drops \n",
"0 NaN NaN NaN\n",
"1 NaN NaN NaN\n",
"2 1.0 0.0 1.0\n",
"3 1.0 1.0 1.0\n",
"4 2.0 2.0 2.0\n",
"5 3.0 3.0 3.0\n",
"6 4.0 4.0 4.0\n",
"7 5.0 5.0 5.0\n",
"8 6.0 6.0 6.0\n",
"9 7.0 7.0 7.0\n",
"10 8.0 8.0 8.0"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"pd.concat([grouped[4].diff().diff(), grouped[3].diff().shift(1), grouped[2].shift(2)], axis=1).head(11)"
]
},
{
"cell_type": "markdown",
"id": "ad721e37-75ae-4e8b-92fe-20349f16835a",
"metadata": {},
"source": [
"## (More) Optimal Solution\n",
"\n",
"The following just codifies the procedure described in the prior section:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "fcd9f0dc-f270-4828-9dca-2abcb8ce8bac",
"metadata": {},
"outputs": [],
"source": [
"def superEggDrop2(k: int, n: int) -> int:\n",
" if k == 1 or n == 1:\n",
" return n\n",
" memo, cumsum, i = [[0] * (k+1), [1] * (k+1)], 1, 1\n",
" while True:\n",
" i += 1\n",
" row = [0] * (k+1)\n",
" for j in range(1, k+1):\n",
" row[j] = 1 if j == 1 else memo[i-1][j] + memo[i-1][j-1]\n",
" if j == k:\n",
" cumsum += row[j]\n",
" if cumsum >= n:\n",
" return i\n",
" memo.append(row)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "2a1ddde2-7cd5-47d0-8be0-b94ef4831ff9",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"14"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Testing...1, 2, 3\n",
"superEggDrop2(2, 100)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.10"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment