Created
November 7, 2024 20:44
-
-
Save Per48edjes/3bc289815191c4348711d977e8fd85fb to your computer and use it in GitHub Desktop.
jane_street_puzzle_202411.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"nbformat": 4, | |
"nbformat_minor": 0, | |
"metadata": { | |
"colab": { | |
"provenance": [], | |
"authorship_tag": "ABX9TyNuALs/gGT6kVhEXnxzYael", | |
"include_colab_link": true | |
}, | |
"kernelspec": { | |
"name": "python3", | |
"display_name": "Python 3" | |
}, | |
"language_info": { | |
"name": "python" | |
} | |
}, | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": { | |
"id": "view-in-github", | |
"colab_type": "text" | |
}, | |
"source": [ | |
"<a href=\"https://colab.research.google.com/gist/Per48edjes/3bc289815191c4348711d977e8fd85fb/jane_street_puzzle_202411.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"# Jane Street Puzzle (November 2024)\n", | |
"\n", | |
"" | |
], | |
"metadata": { | |
"id": "2zxXE9fHXHD6" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"import numpy as np\n", | |
"import matplotlib.pyplot as plt\n", | |
"from typing import Callable\n", | |
"\n", | |
"\n", | |
"def generate_point(is_blue: bool) -> np.array:\n", | |
" r1 = np.random.rand()\n", | |
" r2 = np.random.rand()\n", | |
"\n", | |
" while is_blue and ((2 * r1) < (r1 + r2) or (r1 + r2) < 1):\n", | |
" r1 = np.random.rand()\n", | |
" r2 = np.random.rand()\n", | |
"\n", | |
" return np.array([r1, r2])\n", | |
"\n", | |
"def plot_decorator(func: Callable) -> Callable:\n", | |
" def wrapper(*args, **kwargs):\n", | |
" is_satisfied, c, r, b = func(*args, **kwargs)\n", | |
" plt.figure(figsize=(6, 6))\n", | |
" plt.scatter(r[0], r[1], color='red', label='r')\n", | |
" plt.scatter(b[0], b[1], color='blue', label='b')\n", | |
" plt.scatter(c[0], c[1], color='black', label='c')\n", | |
" if is_satisfied:\n", | |
" plt.plot([r[0], c[0]], [r[1], c[1]], color='red', linestyle='--')\n", | |
" plt.plot([b[0], c[0]], [b[1], c[1]], color='blue', linestyle='--')\n", | |
" plt.xlim(0, 1)\n", | |
" plt.ylim(0, 1)\n", | |
" plt.xlabel('x')\n", | |
" plt.ylabel('y')\n", | |
" plt.title(f'Satisfied? {is_satisfied}')\n", | |
" plt.legend()\n", | |
" plt.grid(True)\n", | |
" plt.show()\n", | |
" return is_satisfied, c, r, b\n", | |
" return wrapper\n", | |
"\n", | |
"def check_satisfiability(b: np.array, r: np.array) -> tuple[bool, np.array]:\n", | |
" x = r - b\n", | |
" r_x_prime, b_x_prime = 1 - r[0], 1 - b[0]\n", | |
" x_x, x_y = x[0], x[1]\n", | |
"\n", | |
" r_y_prime = ((r_x_prime ** 2) - (b_x_prime ** 2) - (x_y ** 2)) / (2 * x_y)\n", | |
" r_prime = np.array([r_x_prime, r_y_prime])\n", | |
" c = r + r_prime\n", | |
"\n", | |
" return 0 < c[1] < 1, c, r, b\n", | |
"\n", | |
"def generate_sample(b: np.array, r: np.array):\n", | |
" is_satisfied, c, r, b = check_satisfiability(b, r)\n", | |
" return is_satisfied, c, r, b\n", | |
"\n", | |
"def simulation(n: int, plot: bool = False) -> float:\n", | |
" global generate_sample\n", | |
" total_satisfied = 0\n", | |
" if plot:\n", | |
" generate_sample = plot_decorator(generate_sample)\n", | |
" for _ in range(n):\n", | |
" b, r = generate_point(True), generate_point(False)\n", | |
" is_satisfied, _, _, _ = generate_sample(b, r)\n", | |
" if is_satisfied:\n", | |
" total_satisfied += 1\n", | |
"\n", | |
" return total_satisfied / n" | |
], | |
"metadata": { | |
"id": "yFjI5ncyFn_u" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"def empirical_sampling_distribution(M: int, N: int) -> None:\n", | |
" sample_means = []\n", | |
" for _ in range(M):\n", | |
" sample_means.append(simulation(N))\n", | |
"\n", | |
" plt.figure(figsize=(10, 6))\n", | |
" plt.hist(sample_means, bins=30, density=True, alpha=0.7, color='skyblue', edgecolor='black')\n", | |
" plt.title(f'Empirical Sampling Distribution of the Sample Mean (M={M}, N={N})')\n", | |
" plt.xlabel('Sample Mean')\n", | |
" plt.ylabel('Density')\n", | |
" plt.grid(True)\n", | |
" plt.show()\n", | |
"\n", | |
" mean_of_sample_means = np.mean(sample_means)\n", | |
" print(f\"Mean of sample means: {mean_of_sample_means}\")" | |
], | |
"metadata": { | |
"id": "qvBcoF85LQuV" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"N = 10_000\n", | |
"M = 1_000\n", | |
"\n", | |
"empirical_sampling_distribution(M, N)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 581 | |
}, | |
"id": "4u6iNwtqDm5A", | |
"outputId": "0aaa76a4-f74b-4156-eeae-9088b653c28f" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"<Figure size 1000x600 with 1 Axes>" | |
], | |
"image/png": "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REdHZ3tuwvs43Q4eZz18Pm/ePF122WUqW7asOnXqpEOHDskYoylTpqhmzZoKCQlRt27ddOLECbcaderU0e23364vvvhCzZo1U3BwsK688kp98MEHbu1yur6kffv2aty4sbZv3662bduqbNmyeuKJJ1zrzj8nPzU1VRMnTlT9+vUVHBysqKgo9ezZU/v27XO1mTlzplq3bq2IiAiFhISoefPmhT61IqvuDTfckG1dcHCwwsLCXH///PPPGjRokC677DIFBwcrMjJSQ4YM0fHjx91ul3Xty+7du/Xvf/9b4eHhqlKlip5++mkZY3To0CHXN1KRkZGaNWtWjo/ju+++qyeeeEKRkZEqV66cunbtqkOHDl1wm86/JimrP3v37tWgQYNUoUIFhYeHa/DgwUpOTna7bUpKih588EFVrlxZ5cuXV9euXXX48OEiX+cUHR2tJUuWKD09XdOnT8+2rdbnzJ49e9SrVy9FRkYqODhYNWvWVN++fXXq1CnX9p09e1Zvvvmm69SarGvPsrb1999/V//+/VWxYkXXN7M5XZOUZfny5WrQoIGCg4PVvHlzffvtt27rc7r2K6eaefUtt2uS5s+fr0aNGikoKEjVq1fXyJEjlZSU5NYmaz/6/fff1aFDB5UtW1Y1atRweyzzkpGRoSlTpqhu3boKCgpSnTp19MQTTygtLc2t74sXL9bZs2ddfc/t9Jj27dvrv//9r+Lj411tz398MjMz9dxzz6lmzZoKDg5Wx44dtXfv3my1Nm/erC5duig8PFxly5ZVu3bt9MMPP1xwm/bt2yd/f39df/312daFhYUpODjY9fd3332n3r17q3bt2goKClKtWrX00EMPZTstbdCgQQoNDdXBgwd1++23KzQ0VDVq1NC8efMkSb/88otuuukmlStXTtHR0VqxYoXb7bPG+Ntvv9W9996riIgIhYWF6e6779bJkycvuE1paWl65plnVK9ePVc/H330UbdxupD+/fvrs88+c3sObd26VXv27FH//v1zvE1SUpLGjBmjWrVqKSgoSPXq1dO0adOUmZnp1i6/r71Z1/qtXr1ajRs3VlBQkBo1aqTPP/88X9uwevVq3XTTTbnur/369dO7777r1r9PPvlEycnJ2Y6gFUX58uVVqVKlC7az2+1au3at/v3vf7u9Z9x9990KDQ3Ve++951r2/vvvy9/fX8OHD3ctCw4O1tChQ7Vx40bXa3xBahZmux566CF98skn+vHHHwtdJy9BQUGKjIzMV9tVq1bp9ttvV+3atV3LYmNjVb9+fbft/Oijj+RwOHT//fe7ltlsNo0YMUJ//fWX25E+b9SUpJtvvlnx8fHauXNnvrYNnkNIQoGdOnVK//zzj9u/8z+0S+c+BM6fP18PPPCAHn74YX3zzTfq06ePnnrqKX3++ed67LHHNHz4cH3yyScaN25cttvv2bNH//rXv3TLLbfo+eefV5kyZdS7d+9cz6O2On78uG655RY1a9ZMc+bMUYcOHXJs53Q6dfvtt2vSpElq3ry5Zs2apdGjR+vUqVP69ddfXe1eeuklXX311Zo8ebKmTp3q6st///vfAjxy52Sd77506VIZY/Jsu3btWu3fv1+DBw/W3Llz1bdvX73zzju69dZbc7ztv/71L2VmZuqFF15Qy5Yt9eyzz2rOnDm6+eabVaNGDU2bNk316tXTuHHjsn0ol6TnnntO//3vf/XYY4/pwQcf1Nq1axUbG5vj9Qb50adPH50+fVrPP/+8+vTpoyVLlmjSpElubQYNGqS5c+fq1ltv1bRp0xQSEqLbbrutUPd3vlatWqlu3bp5PmfS09PVuXNnbdq0SQ888IDmzZun4cOHa//+/a4PfcuWLVNQUJDatGmjZcuWadmyZbr33nvd6vTu3VvJycmaOnWqhg0blme/vvnmG40ZM0b//ve/NXnyZB0/flxdunRxe87lV376ZjVx4kSNHDlS1atX16xZs9SrVy+9+uqr6tSpkxwOh1vbkydPqkuXLmratKlmzZqlhg0b6rHHHsvXaTf33HOPJkyYoGuuuUYvvvii2rVrp+eff97tVJJly5apTZs2CgoKcvW9bdu2OdZ78skn1axZM1WuXNnV9vzrk1544QV9+OGHGjdunMaPH69Nmzbprrvucmvz1VdfqW3btrLb7XrmmWc0depUJSUl6aabbtKWLVvy3Kbo6Gg5nU4tW7bsgtu/cuVKJScna8SIEZo7d646d+6suXPn6u67787W1ul06pZbblGtWrU0ffp01alTR6NGjdKSJUvUpUsXXXvttZo2bZrKly+vu+++W3FxcdlqjBo1Sn/88YcmTpyou+++W8uXL1f37t3zfI3JzMxU165dNXPmTN1xxx2aO3euunfvrhdffFH/+te/LriNWXr27Cmbzeb2JdaKFSvUsGFDXXPNNdnaJycnq127dnrrrbd099136+WXX9YNN9yg8ePHa+zYsW5tC/La+/333+v+++9X3759NX36dKWmpqpXr145vj9ZHT58WAcPHsyxr1n69++vo0ePun25smLFCnXs2FFVq1bN1t7hcGR7n8zt3/nBMD9++eUXZWRk6Nprr3VbHhgYqGbNmmnHjh2uZTt27FD9+vXdgo8k16mDWR++C1KzMEaPHq2KFSte8MuvzMzMfD92579m5cfhw4f1999/Z9tO6dxjcv5jV65cOV1xxRXZ2mWt91bNLFmnJ+bnixx4mE+PY+GiknW6XU7/goKCXO2yDp9XqVLFJCUluZaPHz/eSDJNmzY1DofDtbxfv34mMDDQpKamupZFR0cbSWbVqlWuZadOnTJRUVHm6quvdi3LOs3GejpCu3btjCSzcOHCbNtw/ukmixYtMpLM7Nmzs7W1HtpOTk52W5eenm4aN25sbrrpJrfl+TndLjk52TRo0MBIMtHR0WbQoEHmjTfeMAkJCTm2Pd/bb79tJJlvv/3WteyZZ54xkszw4cNdyzIyMkzNmjWNzWYzL7zwgmv5yZMnTUhIiFs/sx7HGjVqGLvd7lqedWrgSy+95FqW0+l2kswzzzyTrT9Dhgxxa9ejRw8TERHh+nv79u1GUrbTWAYNGpStZk7yc6pGt27djCTX6SPnP2d27NiRr1NlcjulLWtb+/Xrl+s6q6x9Ztu2ba5l8fHxJjg42PTo0cO1LLfTGnOqmVvfsvbZuLg4Y4wxf//9twkMDDSdOnUyTqfT1e6VV14xksyiRYtcy7L2o6VLl7qWpaWlmcjISNOrV69s92W1c+dOI8ncc889bsvHjRtnJJmvvvrKbTs9dbrdFVdcYdLS0lzLX3rpJSPJ/PLLL8aYc/v05Zdfbjp37pxt/46JiTE333xznvd/7NgxU6VKFSPJNGzY0Nx3331mxYoVbq9z1prne/75543NZnM7HWfgwIFGkpk6daprWdY+arPZzDvvvONa/ueff2bbL7LGuHnz5iY9Pd21POvUwI8++si17PzXv2XLlhk/Pz/z3XffufVz4cKFuZ5WaGUduzvvvNN07NjRGGOM0+k0kZGRZtKkSTnuo1OmTDHlypUzu3fvdqv3+OOPG39/f3Pw4EHXsvy+9koygYGBZu/eva5lP/30k5Fk5s6dm+d2fPnll0aS+eSTT7Ktyzrdzhhjrr32WjN06FBjzLkxCgwMNG+++WaOp3tmLcvPv6z983x5nW6Xtc76PpCld+/eJjIy0vV3o0aNsj1exhjz22+/ub1XFqRmQVgfw0mTJhlJZvv27caYnF/Ds5bl519upyLmdbpd1jrra1uWRx55xEhyfR657bbbzGWXXZat3dmzZ40k8/jjj3utplVgYKAZMWJEjtsK7+FIEgps3rx5Wrt2rdu/nL5Z7t27t8LDw11/t2zZUpL073//2+0i/5YtWyo9PV2HDx92u3316tXVo0cP199Zp5Ds2LHjgjO9BAUFafDgwRfcllWrVqly5cp64IEHsq2znnYREhLi+v+TJ0/q1KlTatOmTaFOGwgJCdHmzZv1yCOPSDp3uszQoUMVFRWlBx54wO00F+v9pqam6p9//nGd6pPTfd9zzz2u//f399e1114rY4yGDh3qWl6hQgU1aNBA+/fvz3b7u+++W+XLl3f9feeddyoqKkr/+9//CrydknTfffe5/d2mTRsdP35cdrtdklynwlhPO5CU43gUVtaF9KdPn85xfdZzdM2aNdlOBSyI87c1L61atXK7eLl27drq1q2b1qxZI6fTWeg+XMiXX36p9PR0jRkzRn5+//fyP2zYMIWFhWX7dj40NFT//ve/XX8HBgaqRYsWOT53rLKeL+cfFXj44YclqVBHYPNj8ODBbhdHt2nTRpJc/d25c6frFLDjx4+7vo0+e/asOnbsqG+//TbPb/WrVaumn376Sffdd59OnjyphQsXqn///qpataqmTJnidtTGuu+ePXtW//zzj1q3bi1jTI7fyFv33ax9tFy5cm6ncjVo0EAVKlTI8fEfPny4AgICXH+PGDFCZcqUyXPfXblypa644go1bNjQ7dv5m266SZK0fv36XG97vv79++vrr7/WsWPH9NVXX+nYsWO5nmq3cuVKtWnTRhUrVnS739jYWDmdTrej3AV57Y2NjVXdunVdf1911VUKCwu74PM160hTxYoVL7iNH3zwgdLT012nsFnfo6yaNm2a7X0yt3/5PUXMKuvofk6TsgQHB7sd/U9JScm1nbVWQWoWVtbRpPPPKLCKjIzM92PXtGnTAvfhQttpbeOpx64wNa2y9hUUL2a3Q4G1aNEix0PK57Oelyv934fRWrVq5bj8/PPn69Wrl+38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7rt9+vTR4cOH9frrr2dbl5KSkuO25qVDhw6aMmWKXnnllTxfo/v06aONGzdqzZo12dYlJSW59kdPv/bmpkaNGqpVq1aOH3DPd+edd+qZZ57R/Pnz8zyC4e1rksLDwxUbG6u33nrL7TV72bJlOnPmjHr37u3WZ6fTqddee821LC0tTYsXL1bLli1dRwwLUrOoxowZowoVKuT4A6neviZJOvfe/+mnn7r9xMW6deu0e/dut+3s1q2bAgIC3N6jjDFauHChatSoodatW3u1piRt375dkrIth/dxJAkF9tlnn+nPP//Mtrx169Zu304XVf369TV06FBt3bpV1apV06JFi5SQkODRbxHvvvtuLV26VGPHjtWWLVvUpk0bnT17Vl9++aXuv/9+devWTbfddptmz56tLl26qH///vr77781b9481atX74LXZuRk7dq1euaZZ9S1a1ddf/31Cg0N1f79+7Vo0SKlpaW5TlMJCwtT27ZtNX36dDkcDtWoUUNffPFFvr7tLKxKlSrpxhtv1ODBg5WQkKA5c+aoXr16F5zSurCaN2+uXr16ac6cOTp+/Liuv/56ffPNN64jhvn9dvvHH3/UW2+9pczMTCUlJWnr1q1atWqVbDabli1blueRsK+++kqjRo1S7969Vb9+fWVkZGjZsmXy9/dXr1693Pr65Zdfavbs2apevbpiYmJck5EUVOPGjdW5c2c9+OCDCgoKcr1ZWi9m7tu3rx577DH16NFDDz74oJKTk7VgwQLVr18/20Xr+e1blSpVNH78eE2aNEldunRR165dtWvXLs2fP1/XXXddvo645UfTpk01cOBAvfbaa0pKSlK7du20ZcsWvfnmm+revXu+v2E/X/PmzfXuu+9q7Nixuu666xQaGqo77rgj37f38/PTf/7zH91yyy1q1KiRBg8erBo1aujw4cNav369wsLC9Mknn+R6+2XLlmn58uXq0aOHmjdvrsDAQP3xxx9atGiRgoODXb/H1rBhQ9WtW1fjxo3T4cOHFRYWplWrVuX72pjCSE9PV8eOHdWnTx/XmN54443q2rVrrrcZMGCA3nvvPd13331av369brjhBjmdTv3555967733tGbNmnxdf5rFz89PTz311AXbPfLII/r44491++23a9CgQWrevLnOnj2rX375Re+//74OHDigypUre/y1Ny/dunXThx9+eMFrP8LDw/P1+21FuSYp6+j1b7/9Junc8+7777+XJLfH97nnnlPr1q3Vrl07DR8+XH/99ZdmzZqlTp06qUuXLq52LVu2VO/evTV+/Hj9/fffqlevnt58800dOHBAb7zxhtt957emdO71uV27dm7ToudXeHi4Ro8eneMEDkW5JumVV15RUlKSjhw5Iuncb1n99ddfks5NCJR1nekTTzyhlStXqkOHDho9erTOnDmjGTNmqEmTJm6TPtWsWVNjxozRjBkz5HA4dN1112n16tX67rvvtHz5crfTJL1RUzr3maF27dq6+uqrC/WYoAiKbyI9XOzymgJclqk2c5uWOadpUq11t27d6loWHR1tbrvtNrNmzRpz1VVXmaCgINOwYcNst81tCvCs6UbPl9MvzicnJ5snn3zSxMTEmICAABMZGWnuvPNOs2/fPlebN954w1x++eWufixevDjHqZjzMwX4/v37zYQJE8z1119vqlatasqUKWOqVKlibrvtNrepkY0598vcPXr0MBUqVDDh4eGmd+/e5siRI7lOuZ2YmOh2+9ymVz7/Mcp6HN9++20zfvx4U7VqVRMSEmJuu+02t+mKs2rmdwrw8/tz/pTUxpyb9nTkyJGmUqVKJjQ01HTv3t3s2rXLSHKbujwn508VW6ZMGVOpUiXTsmVLM378+Gx9t25r1nNm//79ZsiQIaZu3bomODjYVKpUyXTo0MF8+eWXbrf7888/Tdu2bU1ISIiR5Brn3LbVuu78x2rkyJHmrbfecj2nrr766hynsv3iiy9M48aNTWBgoGnQoIF56623cqyZW99yeryNOTfld8OGDU1AQICpVq2aGTFihDl58qRbm9z2o9ymJj+fw+EwkyZNcu1XtWrVMuPHj3eb6j+rXn6nAD9z5ozp37+/qVChgtH/n0LfmNxfW7KeH+dPA7xjxw7Ts2dPExERYYKCgkx0dLTp06ePWbduXZ73//PPP5tHHnnEXHPNNaZSpUqmTJkyJioqyvTu3dv8+OOPbm1///13Exsba0JDQ03lypXNsGHDXFNSW/uT3300S9ZrY5asMf7mm2/M8OHDTcWKFU1oaKi56667zPHjx7PVPP/1Lz093UybNs00atTIBAUFmYoVK5rmzZubSZMmuabNz01+xi6394PTp0+b8ePHm3r16pnAwEBTuXJl07p1azNz5ky3qczz+9qb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uLPzjx/9S18vWyC73U5IAnBRISQBgA9ERNVUZHSMx+smHjnk8Zq4NEREVnd/TjozpD8OqVqtaMmfjwsALi286gEAAK/J6XonT+KaJwDeQEgCAABekdv1Tp7ENU8AvIGQBAAAvCK36508hWueAHgLIQkAAHhVtuudAKCEK9R0Nfv37/d0PwAAAACgRChUSKpXr546dOigt956S6mp3vmtDwAAAADwhUKFpB9//FFXXXWVxo4dq8jISN17773asmWLp/sGAAAAAMWuUCGpWbNmeumll3TkyBEtWrRIR48e1Y033qjGjRtr9uzZSkxM9HQ/AQAAAKBYFO4ntP+/MmXKqGfPnlq5cqWmTZumvXv3aty4capVq5buvvtuHT161FP9BAAAAIBiUaSQtG3bNt1///2KiorS7NmzNW7cOO3bt09r167VkSNH1K1bN0/1EwAAAACKRaGmAJ89e7YWL16sXbt26dZbb9XSpUt16623ys/vXOaKiYnRkiVLVKdOHU/2FQAAAAC8rlAhacGCBRoyZIgGDRqkqKioHNtUrVpVb7zxRpE6BwAAAADFrVAhae3atapdu7bryFEWY4wOHTqk2rVrKzAwUAMHDvRIJwEAAACguBTqmqS6devqn3/+ybb8xIkTionhF7UBAAAAXLwKFZKMMTkuP3PmjIKDg4vUIQAAAADwpQKdbjd27FhJks1m04QJE1S2bFnXOqfTqc2bN6tZs2Ye7SAAAAAAFKcChaQdO3ZIOnck6ZdfflFgYKBrXWBgoJo2bapx48Z5tocAAAAAUIwKFJLWr18vSRo8eLBeeuklhYWFeaVTAAAAAOArhZrdbvHixZ7uBwAAAACUCPkOST179tSSJUsUFhamnj175tn2gw8+KHLHAAAAAMAX8h2SwsPDZbPZXP8PAAAAAKVRvkOS9RQ7TrcDAAAAUFoV6neSUlJSlJyc7Po7Pj5ec+bM0RdffOGxjgEAAACALxQqJHXr1k1Lly6VJCUlJalFixaaNWuWunXrpgULFni0gwAAAABQnAoVkn788Ue1adNGkvT+++8rMjJS8fHxWrp0qV5++WWPdhAAAAAAilOhQlJycrLKly8vSfriiy/Us2dP+fn56frrr1d8fLxHOwgAAAAAxalQIalevXpavXq1Dh06pDVr1qhTp06SpL///psfmAUAAABwUStUSJowYYLGjRun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giIiInT11VdrxowZysjIKNyGwGtj2bp1a3388cc6fPiwjDFav369du/erU6dOkmStm/fLofD4Xa/DRs2VO3atfO8X+TNV+OZZfny5apcubIaN26s8ePHKzk52TMbdonyxnimpaVJktspIX5+fgoKCtL3338vif3TW3w1nlnYPz2rsON55swZRUdHq1atWurWrZt+++0317q4uDgdO3bMrWZ4eLhatmzpqrlx40ZVqFBB1157ratNbGys/Pz8tHnzZk9u4iXFV+OZhc+2+VfG1x3Iyz///COn06lq1aq5La9WrZr+/PPPHG/z/fff64033tDOnTvzdR9vvvmmypcvr549e7otf/DBB3XNNdeoUqVK2rBhg8aPH6+jR49q9uzZhdqWS523xnLu3LkaPny4atasqTJlysjPz0+vv/662rZtK0k6duyYAgMDVaFChWz3e+zYsSJt06XMV+MpSf3791d0dLSqV6+un3/+WY899ph27dqlDz74wCPbdinyxnhmhZ3x48fr1VdfVbly5fTiiy/qr7/+0tGjRyWxf3qLr8ZTYv/0hsKMZ4MGDbRo0SJdddVVOnXqlGbOnKnWrVvrt99+U82aNV37V041s9YdO3ZMVatWdVtfpkwZVapUif2zCHw1nhKfbQuqRIekgjp9+rQGDBig119/XZUrV87XbRYtWqS77ror2wVwY8eOdf3/VVddpcDAQN177716/vnnFRQU5NF+I7v8juXcuXO1adMmffzxx4qOjta3336rkSNHqnr16m7fqMC3PDmew4cPd7Vv0qSJoqKi1LFjR+3bt09169b1+rYgf+MZEBCgDz74QEOHDlWlSpXk7++v2NhY3XLLLTLGFHOPkRdPjif7Z8nQqlUrtWrVyvV369atdcUVV+jVV1/VlClTfNgzFIanxpPPtgVTokNS5cqV5e/vn22mo4SEBEVGRmZrv2/fPh04cEB33HGHa1lmZqakc99+7Nq1y+1F+rvvvtOuXbv07rvvXrAvLVu2VEZGhg4cOKAGDRoUdpMuWd4Yy+rVq+uJJ57Qhx9+qNtuu03SuZ1+586dmjlzpmJjYxUZGan09HQlJSW5fVud2/0if3w1njlp2bKlJGnv3r18CCskb73WNm/eXDt37tSpU6eUnp6uKlWqqGXLlq7Td9g/vcNX45kT9s+iK+h45iQgIEBXX3219u7dK0mu2yUkJCgqKsqtZrNmzVxt/v77b7c6GRkZOnHiBPtnEfhqPHPCZ9u8lehrkgIDA9W8eXOtW7fOtSwzM1Pr1q1zS9RZGjZsqF9++UU7d+50/evatas6dOignTt3qlatWm7t33jjDTVv3lxNmza9YF927twpPz+/bIeekT/eGEuHwyGHwyE/P/ensb+/v+sNvnnz5goICHC73127dungwYM53i/yx1fjmZOs04OsbwwoGG+/1oaHh6tKlSras2ePtm3bpm7dukli//QWX41nTtg/i66g45kTp9OpX375xTUOMTExioyMdKtpt9u1efNmV81WrVopKSlJ27dvd7X56quvlJmZ6Qq/KDhfjWdO+Gx7Ab6dN+LC3nnnHRMUFGSWLFlifv/9dzN8+HBToUIF19SHAwYMMI8//niut89tdrtTp06ZsmXLmgULFmRbt2HDBvPiiy+anTt3mn379pm33nrLVKlSxdx9990e265LkTfGsl27dqZRo0Zm/fr1Zv/+/Wbx4sUmODjYzJ8/39XmvvvuM7Vr1zZfffWV2bZtm2nVqpVp1aqVV7bxUuKL8dy7d6+ZPHmy2bZtm4mLizMfffSRueyyy0zbtm29tp2XCm+M53vvvWfWr19v9u3bZ1avXm2io6NNz5493dqwf3qHL8aT/dN7CjqekyZNMmvWrDH79u0z27dvN3379jXBwcHmt99+c7V54YUXTIUKFcxHH31kfv75Z9OtW7ccpwC/+uqrzebNm833339vLr/8cqYA9wBfjCefbQuuxIckY4yZO3euqV27tgkMDDQtWrQwmzZtcq1r166dGThwYK63zS0kvfrqqyYkJMQkJSVlW7d9+3bTsmVLEx4eboKDg80VV1xhpk6dalJTUz2xOZc0T4/l0aNHzaBBg0z16tVNcHCwadCggZk1a5bJzMx0tUlJSTH333+/qVixoilbtqzp0aOHOXr0qKc37ZJU3ON58OBB07ZtW1OpUiUTFBRk6tWrZx555BF+h8VDPD2eL730kqlZs6YJCAgwtWvXNk899ZRJS0tza8P+6T3FPZ7sn95VkPEcM2aMq221atXMrbfean788Ue3epmZmebpp5821apVM0FBQaZjx45m165dbm2OHz9u+vXrZ0JDQ01YWJgZPHiwOX36tFe381JR3OPJZ9uCsxnDFbQAAAAAkKVEX5MEAAAAAMWNkAQAAAAAFoQkAAAAALAgJAEAAACABSEJAAAAACwISQAAAABgQUgCAAAAAAtCEgAAAABYEJIAAKWKzWbT6tWrfd0NAMBFjJAEACiQxMREjRgxQrVr11ZQUJAiIyPVuXNn/fDDD77umkccOHBANptN/v7+Onz4sNu6o0ePqkyZMrLZbDpw4IBvOggA8DpCEgCgQHr16qUdO3bozTff1O7du/Xxxx+rffv2On78uK+75lE1atTQ0qVL3Za9+eabqlGjho96BAAoLoQkAEC+JSUl6bvvvtO0adPUoUMHRUdHq0WLFho/fry6du3qajd79mw1adJE5cqVU61atXT//ffrzJkzrvVLlixRhQoV9Omnn6pBgwYqW7as7rzzTiUnJ+vNN99UnTp1VLFiRT344INyOp2u29WpU0dTpkxRv379VK5cOdWoUUPz5s3Ls8+HDh1Snz59VKFCBVWqVEndunXL11GggQMHavHixW7LFi9erIEDB2Zr++uvv+qWW25RaGioqlWrpgEDBuiff/5xrf/888914403qkKFCoqIiNDtt9+uffv2udZnHb364IMP1KFDB5UtW1ZNmzbVxo0bL9hPAIDnEZIAAPkWGhqq0NBQrV69Wmlpabm28/Pz08svv6zffvtNb775pr766is9+uijbm2Sk5P18ssv65133tHnn3+ur7/+Wj169ND//vc//e9//9OyZcv06quv6v3333e73YwZM9S0aVPt2LFDjz/+uEaPHq21a9fm2A+Hw6HOnTurfPny+u677/TDDz8oNDRUXbp0UXp6ep7b2rVrV508eVLff/+9JOn777/XyZMndccdd7i1S0pK0k033aSrr75a27Zt0+eff66EhAT16dPH1ebs2bMaO3astm3bpnXr1snPz089evRQZmamW60nn3xS48aN086dO1W/fn3169dPGRkZefYTAOAFBgCAAnj//fdNxYoVTXBwsGndurUZP368+emnn/K8zcqVK01ERITr78WLFxtJZu/eva5l9957rylbtqw5ffq0a1nnzp3Nvffe6/o7OjradOnSxa32v/71L3PLLbe4/pZkPvzwQ2OMMcuWLTMNGjQwmZmZrvVpaWkmJCTErFmzJse+xsXFGUlmx44dZsyYMWbw4MHGGGMGDx5sHnroIbNjxw4jycTFxRljjJkyZYrp1KmTW41Dhw4ZSWbXrl053kdiYqKRZH755Re3+/zPf/7javPbb78ZSeaPP/7IsQYAwHs4kgQAKJBevXrpyJEj+vjjj9WlSxd9/fXXuuaaa7RkyRJXmy+//FIdO3ZUjRo1VL58eQ0YMEDHjx9XcnKyq03ZsmVVt25d19/VqlVTnTp1FBoa6rbs77//drv/Vq1aZfv7jz/+yLGvP/30k/bu3avy5cu7joJVqlRJqampbqe75WbIkCFauXKljh07ppUrV2rIkCE53sf69etd9UNDQ9WwYUNJct3Hnj171K9fP1122WUKCwtTnTp1JEkHDx50q3XVVVe5/j8qKkqSsm0/AMD7yvi6AwCAi09wcLBuvvlm3XzzzXr66ad1zz336JlnntGgQYN04MAB3X777RoxYoSee+45VapUSd9//72GDh2q9PR0lS1bVpIUEBDgVtNms+W47PxT0grizJkzat68uZYvX55tXZUqVS54+yZNmqhhw4bq16+frrjiCjVu3Fg7d+7Mdh933HGHpk2blu32WUHnjjvuUHR0tF5//XVVr15dmZmZaty4cbZT/qzbb7PZJKlI2w8AKBxCEgCgyK688krXbxNt375dmZmZmjVrlvz8zp2w8N5773nsvjZt2pTt7yuuuCLHttdcc43effddVa1aVWFhYYW6vyFDhuj+++/XggULcr2PVatWqU6dOipTJvvb6vHjx7Vr1y69/vrratOmjSS5rnMCAJRMnG4HAMi348eP66abbtJbb72ln3/+WXFxcVq5cqWmT5+ubt26SZLq1asnh8OhuXPnav/+/Vq2bJkWLlzosT788MMPmj59unbv3q158+Zp5cqVGj16dI5t77rrLlWuXFndunXTd999p7i4OH399dd68MEH9ddff+Xr/oYNG6bExETdc889Oa4fOXKkTpw4oX79+mnr1q3at2+f1qxZo8GDB8vpdKpixYqKiIjQa6+9pr179+qrr77S2LFjC739AADvIyQBAPItNDRULVu21Isvvqi2bduqcePGevrppzVs2DC98sorkqSmTZtq9uzZmjZtmho3bqzly5fr+eef91gfHn74YW3btk1XX321nn32Wc2ePVudO3fOsW3ZsmX17bffqnbt2urZs6euuOIKDR06VKmpqfk+slSmTBlVrlw5x6NEklS9enX98MMPcjqd6tSpk5o0aaIxY8aoQoUK8vPzk5+fn9555x1t375djRs31kMPPaQZM2YUevsBAN5nM8YYX3cCAID8qFOnjsaMGaMxY8b4uisAgFKMI0kAAAAAYEFIAgAAAAALTrcDAAAAAAuOJAEAAACABSEJAAAAACwISQAAAABgQUgCAAAAAAtCEgAAAABYEJIAAAAAwIKQBAAAAAAWhCQAAAAAsPh/e8Chs0lL2NUAAAAASUVORK5CYII=\n" | |
}, | |
"metadata": {} | |
}, | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Mean of sample means: 0.4914361\n" | |
] | |
} | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"# Generate a blue point\n", | |
"# blue_point = generate_point(True)\n", | |
"blue_point = np.array([.9, .5])\n", | |
"\n", | |
"# Determine the closest edge\n", | |
"distances = [blue_point[0], blue_point[1], 1 - blue_point[0], 1 - blue_point[1]]\n", | |
"closest_edge = np.argmin(distances)\n", | |
"\n", | |
"# Generate grid points\n", | |
"grid_size = 1000\n", | |
"x = np.linspace(0, 1, grid_size)\n", | |
"y = np.linspace(0, 1, grid_size)\n", | |
"X, Y = np.meshgrid(x, y)\n", | |
"\n", | |
"red_points = []\n", | |
"for i in range(grid_size):\n", | |
" for j in range(grid_size):\n", | |
" red_point = np.array([X[i,j], Y[i,j]])\n", | |
" is_satisfied, _, _, _ = generate_sample(blue_point, red_point)\n", | |
" if is_satisfied:\n", | |
" red_points.append(red_point)\n", | |
"red_points = np.array(red_points)\n", | |
"\n", | |
"# Plot\n", | |
"plt.figure(figsize=(6, 6))\n", | |
"plt.scatter(red_points[:, 0], red_points[:, 1], color='red', s=1, label='Possible Red Points')\n", | |
"plt.scatter(blue_point[0], blue_point[1], color='blue', label='Blue Point', s=10)\n", | |
"plt.xlim(0, 1)\n", | |
"plt.ylim(0, 1)\n", | |
"plt.xlabel(\"X\")\n", | |
"plt.ylabel(\"Y\")\n", | |
"plt.legend()\n", | |
"plt.show()" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/", | |
"height": 547 | |
}, | |
"id": "f-MldlgGP2r3", | |
"outputId": "3157cb56-262c-4eb3-cc85-9bf9cfc00c41" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "display_data", | |
"data": { | |
"text/plain": [ | |
"<Figure size 600x600 with 1 Axes>" | |
], | |
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAiMAAAISCAYAAAAeDM+5AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA5DUlEQVR4nO3df1yV9f3/8ecB5JcEmj8AHUlqlpo/UpSwmmtjo18ub31WLP2KeSsb6Mokl5omWqbWrPlpmhT9sE+NcNunlTM/lmO5NnNBKmVJWoo/tglqKSQYCFzfPxxnIj8EPOe8r3PO4367nZtx8b7O9ToXB86z9/t9vS+HZVmWAAAADAkwXQAAAPBvhBEAAGAUYQQAABhFGAEAAEYRRgAAgFGEEQAAYBRhBAAAGEUYAQAARhFGAACAUYQRAABglNEw8v7772vcuHHq1auXHA6H3nzzzfPus3nzZo0YMUIhISHq37+/1qxZ4/Y6AQCA+xgNI5WVlRo2bJhWrVrVpvYlJSW6+eabdf3116uoqEgPPPCA7rnnHr3zzjturhQAALiLwy43ynM4HPrDH/6g8ePHt9hm9uzZevvtt/Xpp586t/30pz/ViRMntHHjRg9UCQAAXC3IdAHtsXXrViUnJzfalpKSogceeKDFfaqrq1VdXe38ur6+Xl9//bW6desmh8PhrlIBAPA5lmXpm2++Ua9evRQQ4LrBFa8KI6WlpYqOjm60LTo6WhUVFTp16pTCwsKa7LN06VItWrTIUyUCAODzDh06pO985zsuez6vCiMdMXfuXGVmZjq/Li8v1yWXXKJDhw4pMjLSYGUAFBVlugIA7VAhKU7SRRdd5NLn9aowEhMTo7KyskbbysrKFBkZ2WyviCSFhIQoJCSkyfbIyEjCCAAAHeDqaQ5etc5IUlKS8vPzG23btGmTkpKSDFUEAAAulNEwcvLkSRUVFamoqEjSmUt3i4qKdPDgQUlnhljS0tKc7dPT07Vv3z499NBD+vzzz/Xss8/qt7/9rWbOnGmifAAA4AJGw8hHH32kq666SldddZUkKTMzU1dddZUWLFggSTp8+LAzmEjSpZdeqrffflubNm3SsGHD9NRTT+mFF15QSkqKkfoBAMCFs806I55SUVGhqKgolZeXtzhnxLIs1dbWqq6uzsPVAa4XGBiooKAge17KbseaALSoQlKU1OpnaEd41QRWT6ipqdHhw4dVVVVluhTAZcLDwxUbG6vg4GDTpQBAE4SRs9TX16ukpESBgYHq1auXgoOD7fl/k0AbWZalmpoaHT16VCUlJbrssstculARALgCYeQsNTU1qq+vV1xcnMLDw02XA7hEWFiYOnXqpAMHDqimpkahoaGmS/qP8HCJXkjA7/G/SM3g/xzha2z7nn7qKdMVALABm/6FAuAX0tNNVwDABggjAADAKMIILsj+/fvlcDicC9dt3rxZDodDJ06caHGfNWvWqEuXLh6pr73OfT3usHDhQg0fPtxtzw8A3oYw4iPuuusuORwOORwOBQcHq3///nr00UdVW1vr1uPGxcXp8OHDuvLKK916nHMtXLjQ+XoDAwMVFxene++9V19//bXbj/29733PeezQ0FANGjRIzz77bJv3nzVrVpPbGpxPfHy8VqxY0c5KAcA7EEZ8yA033KDDhw/riy++0IMPPqiFCxfql7/8pVuPGRgYqJiYGAUFef7CrMGDBztX6X355Ze1ceNGZWRkeOTYU6dO1eHDh7Vr1y7dcccdmj59ul5//fU27RsREaFu3bq5uUIA8B6EER8SEhKimJgY9enTRxkZGUpOTta6deskScePH1daWpq6du2q8PBw3Xjjjfriiy+c+x44cEDjxo1T165d1blzZw0ePFgbNmxw7jtx4kT16NFDYWFhuuyyy/Tyyy9LanlYY8uWLRo6dKhCQ0N19dVX69NPP2219rfeeksjRoxQaGio+vbtq0WLFp23VycoKEgxMTHq3bu3kpOTdfvtt2vTpk2N2rzwwgsaOHCgQkNDdcUVVzTpwSgoKNBVV12l0NBQJSQkaMeOHa0es0F4eLhiYmLUt29fLVy4UJdddpnzXB88eFC33nqrIiIiFBkZqTvuuKPR3abPHaa56667NH78eC1fvlyxsbHq1q2bpk+frtOnT0s60xNz4MABzZw509kjI7X+MwMAb8I6Iz4sLCxMX331laQzH3hffPGF1q1bp8jISM2ePVs33XSTdu3apU6dOmn69OmqqanR+++/r86dO2vXrl2KiIiQJD3yyCPatWuX/u///k/du3fXl19+qVOnTrV67F/84hf67//+b8XExOjhhx/WuHHjtGfPHnXq1KlJ27/+9a9KS0vTM888o+uuu0579+7VvffeK0nKyspq02vdv3+/3nnnnUYrjP7mN7/RggULtHLlSl111VXasWOHpk6dqs6dO2vy5Mk6efKkbrnlFv3whz/Ua6+9ppKSEs2YMaNNxztXWFiYc52ahiDyl7/8RbW1tZo+fbpSU1O1efPmFvd/7733FBsbq/fee09ffvmlUlNTNXz4cE2dOlVvvPGGhg0bpnvvvVdTp0517tPazwwAvIrlZ8rLyy1JVnl5eZPvnTp1ytq1a5d16tQpA5VdmMmTJ1u33nqrZVmWVV9fb23atMkKCQmxZs2aZe3Zs8eSZG3ZssXZ/tixY1ZYWJj129/+1rIsyxoyZIi1cOHCZp973Lhx1pQpU5r9XklJiSXJ2rFjh2VZlvXee+9Zkqy8vDxnm6+++soKCwuz1q5da1mWZb388stWVFSU8/s/+MEPrCVLljR63ldffdWKjY1t8fVmZWVZAQEBVufOna3Q0FBLkiXJevrpp51t+vXrZ+Xm5jba77HHHrOSkpIsy7Ks5557zurWrVujn/fq1asbvZ7mjB071poxY4ZlWZZVW1trvfrqq5Yka+XKlda7775rBQYGWgcPHnS2/+yzzyxJVkFBgbP2YcOGOb8/efJkq0+fPlZtba1z2+23326lpqY6v+7Tp4/1q1/9qlEdrf3MzmXr97bEgwcPL3mU68zf2uY+Qy8EwzTulJ0txcef+dcD1q9fr4iICIWGhurGG29UamqqFi5cqOLiYgUFBSkxMdHZtlu3brr88stVXFwsSbr//vu1ePFiXXPNNcrKytInn3zibJuRkaG8vDwNHz5cDz30kD744IPz1pKUlOT874svvrjRsc718ccf69FHH1VERITz0TAno7V7BF1++eUqKipSYWGhZs+erZSUFN13332SpMrKSu3du1d33313o+ddvHix9u7dK0kqLi52DiU1V3drnn32WUVERCgsLExTp07VzJkzlZGRoeLiYsXFxSkuLs7ZdtCgQerSpUuLr186M/8lMDDQ+XVsbKyOHDnSag2t/cwAwJsQRtxp2TLpwIEz/3rA9ddfr6KiIn3xxRc6deqUXnnlFXXu3LlN+95zzz3at2+fJk2apJ07dyohIUG//vWvJUk33nijc87Cv/71L/3gBz/QrFmzXFb3yZMntWjRIhUVFTkfO3fu1BdffNHq0uUNVw1deeWVWrZsmQIDA7Vo0SLnc0pSTk5Oo+f99NNP9fe///2Ca544caKKiopUUlKiyspKPf300xe0yum5w1cOh0P19fWt7tPazwwAvAlhxJ3mzJH69Dnzrwd07txZ/fv31yWXXNLo6paBAweqtrZWH374oXPbV199pd27d2vQoEHObXFxcUpPT9cbb7yhBx98UDk5Oc7v9ejRQ5MnT9Zrr72mFStW6Pnnn2+1lrM/8I8fP649e/Zo4MCBzbYdMWKEdu/erf79+zd5tOcDfv78+Vq+fLn+9a9/KTo6Wr169dK+ffuaPOell17qPC+ffPKJvv3222brbk1UVJT69++v3r17N6px4MCBOnTokA4dOuTctmvXLp04caLRuW6v4OBg1dXVNdne2s8MALwFE1jdKT3dFstdX3bZZbr11ls1depUPffcc7rooos0Z84c9e7dW7feeqsk6YEHHtCNN96oAQMG6Pjx43rvvfec4WHBggUaOXKkBg8erOrqaq1fv77FYNHg0UcfVbdu3RQdHa158+ape/fuGj9+fLNtFyxYoFtuuUWXXHKJfvKTnyggIEAff/yxPv30Uy1evLjNrzMpKUlDhw7VkiVLtHLlSi1atEj333+/oqKidMMNN6i6ulofffSRjh8/rszMTE2YMEHz5s3T1KlTNXfuXO3fv1/Lly9v8/Gak5ycrCFDhmjixIlasWKFamtrNW3aNI0dO1YJCQkdft74+Hi9//77+ulPf6qQkBB179691Z8ZAHgTekb8xMsvv6yRI0fqlltuUVJSkizL0oYNG5zDA3V1dZo+fboGDhyoG264QQMGDHBeBhscHKy5c+dq6NCh+u53v6vAwEDl5eW1erxly5ZpxowZGjlypEpLS/XHP/6x0ZUuZ0tJSdH69ev17rvvatSoUbr66qv1q1/9Sn369Gn365w5c6ZeeOEFHTp0SPfcc49eeOEFvfzyyxoyZIjGjh2rNWvWOHtGIiIi9Mc//lE7d+7UVVddpXnz5umJJ55o9zHP5nA49NZbb6lr16767ne/q+TkZPXt21dr1669oOd99NFHtX//fvXr1089evSQ1PrPzKvceafpCgAY5jgzmd1/VFRUKCoqSuXl5YqMjGz0vW+//VYlJSW69NJL7XWbdeAC2f69/e+1UwDYW4WkKKnZz9ALQc8IAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAwj7VGAL9GGAFgXm6u6QoAGEQYAQAARhFG/Mj+/fvlcDhUVFRkupRWbd68WQ6HQydOnDBdCgDAAwgjPuKuu+6Sw+FwPrp166YbbrhBn3zyicdrWbhwobOOoKAgxcfHa+bMmTp58mSb9h8zZowOHz6sqKioNh/zrrvuavFGfAAAeyOM+JAbbrhBhw8f1uHDh5Wfn6+goCDdcsstRmoZPHiwDh8+rP379+uJJ57Q888/rwcffLBN+wYHBysmJkYO7lcCAH6BMOJDQkJCFBMTo5iYGA0fPlxz5szRoUOHdPTo0Wbbr1mzRl26dGm07c0332wSAt566y2NGDFCoaGh6tu3rxYtWqTa2tpWawkKClJMTIy+853vKDU1VRMnTtS6deskSdXV1br//vvVs2dPhYaG6tprr1VhYaFz33OHaRrqfOeddzRw4EBFREQ4g5d0pifmlVde0VtvveXskdm8eXM7zhxsITzcdAUADCGMuNGHH0qvvnrmX087efKkXnvtNfXv31/dunXr8PP89a9/VVpammbMmKFdu3bpueee05o1a/T444+363nCwsJUU1MjSXrooYf0v//7v3rllVe0fft29e/fXykpKfr6669b3L+qqkrLly/Xq6++qvfff18HDx7UrFmzJEmzZs3SHXfc0ahnaMyYMR1+zTDkqadMVwDAEMKIm8yeLV19tZSWdubf2bPdf8z169crIiJCERERuuiii7Ru3TqtXbtWAQEd/zEvWrRIc+bM0eTJk9W3b1/98Ic/1GOPPabnnnuuzc+xbds25ebm6vvf/74qKyu1evVq/fKXv9SNN96oQYMGKScnR2FhYXrxxRdbfI7Tp08rOztbCQkJGjFihH7+858rPz9fkhQREaGwsLBGPUPBwcEdfs0wJD3ddAUADAkyXYAv+vBD6cknG2978knpttukxET3Hff666/X6tWrJUnHjx/Xs88+qxtvvFEFBQXq06dPh57z448/1pYtWxr1hNTV1enbb79VVVWVwlvoWt+5c6ciIiJUV1enmpoa3XzzzVq5cqX27t2r06dP65prrnG27dSpk0aPHq3i4uIW6wgPD1e/fv2cX8fGxurIkSMdek0AAHshjLjBnj0tb3dnGOncubP69+/v/PqFF15QVFSUcnJytHjx4ibtAwICZFlWo22nT59u9PXJkye1aNEi3XbbbU32Dw0NbbGWyy+/XOvWrVNQUJB69erl7KkoKytr12tq0KlT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owgjAADAKMIIAAAwijACAACMIowAAACjCCMAAMAowggAADCKMAIAAIwijAAAAKMIIwAAwCjCCAAAMIowAsCcCRNMVwDABggjAMzJyzNdAQAbIIwAMMeyTFcAwAYIIwAAwCjCCAAAMIowAgAAjLJFGFm1apXi4+MVGhqqxMREFRQUtNr+d7/7na644gqFhoZqyJAh2rBhg4cqBQAArmY8jKxdu1aZmZnKysrS9u3bNWzYMKWkpOjIkSPNtv/ggw9055136u6779aOHTs0fvx4jR8/Xp9++qmHKwcAAK7gsCyz09kTExM1atQorVy5UpJUX1+vuLg43XfffZozZ06T9qmpqaqsrNT69eud266++moNHz5c2dnZ5z1eRUWFoqKiVF5ersjISNe9EADt53CYrgBAO1RIipJc/hka5LJn6oCamhpt27ZNc+fOdW4LCAhQcnKytm7d2uw+W7duVWZmZqNtKSkpevPNN5ttX11drerqaufX5eXlks6EEgAA0HYNn5yu7scwGkaOHTumuro6RUdHN9oeHR2tzz//vNl9SktLm21fWlrabPulS5dq0aJFTbbHxcV1sGoAAPzbV199paioKJc9n9Ew4glz585t1JNy4sQJ9enTRwcPHnTpiUTLKioqFBcXp0OHDjE05iGcc8/jnHse59zzysvLdckll+jiiy926fMaDSPdu3dXYGCgysrKGm0vKytTTExMs/vExMS0q31ISIhCQkKabI+KiuLN62GRkZGccw/jnHse59zzOOeeFxDg2utfjF5NExwcrJEjRyo/P9+5rb6+Xvn5+UpKSmp2n6SkpEbtJWnTpk0ttgcAAPZmfJgmMzNTkydPVkJCgkaPHq0VK1aosrJSU6ZMkSSlpaWpd+/eWrp0qSRpxowZGjt2rJ566indfPPNysvL00cffaTnn3/e5MsAAAAdZDyMpKam6ujRo1qwYIFKS0s1fPhwbdy40TlJ9eDBg426g8aMGaPc3FzNnz9fDz/8sC677DK9+eabuvLKK9t0vJCQEGVlZTU7dAP34Jx7Hufc8zjnnsc59zx3nXPj64wAAAD/ZnwFVgAA4N8IIwAAwCjCCAAAMIowAgAAjPLJMLJq1SrFx8crNDRUiYmJKigoaLX97373O11xxRUKDQ3VkCFDtGHDBg9V6jvac85zcnJ03XXXqWvXruratauSk5PP+zNCU+19nzfIy8uTw+HQ+PHj3VugD2rvOT9x4oSmT5+u2NhYhYSEaMCAAfx9aaf2nvMVK1bo8ssvV1hYmOLi4jRz5kx9++23HqrW+73//vsaN26cevXqJYfD0eJ93862efNmjRgxQiEhIerfv7/WrFnT/gNbPiYvL88KDg62XnrpJeuzzz6zpk6danXp0sUqKytrtv2WLVuswMBA68knn7R27dplzZ8/3+rUqZO1c+dOD1fuvdp7zidMmGCtWrXK2rFjh1VcXGzdddddVlRUlPWPf/zDw5V7r/ae8wYlJSVW7969reuuu8669dZbPVOsj2jvOa+urrYSEhKsm266yfrb3/5mlZSUWJs3b7aKioo8XLn3au85/81vfmOFhIRYv/nNb6ySkhLrnXfesWJjY62ZM2d6uHLvtWHDBmvevHnWG2+8YUmy/vCHP7Taft++fVZ4eLiVmZlp7dq1y/r1r39tBQYGWhs3bmzXcX0ujIwePdqaPn268+u6ujqrV69e1tKlS5ttf8cdd1g333xzo22JiYnWz372M7fW6Uvae87PVVtba1100UXWK6+84q4SfU5Hznltba01ZswY64UXXrAmT55MGGmn9p7z1atXW3379rVqamo8VaLPae85nz59uvX973+/0bbMzEzrmmuucWudvqotYeShhx6yBg8e3GhbamqqlZKS0q5j+dQwTU1NjbZt26bk5GTntoCAACUnJ2vr1q3N7rN169ZG7SUpJSWlxfZorCPn/FxVVVU6ffq0y2+85Ks6es4fffRR9ezZU3fffbcnyvQpHTnn69atU1JSkqZPn67o6GhdeeWVWrJkierq6jxVtlfryDkfM2aMtm3b5hzK2bdvnzZs2KCbbrrJIzX7I1d9hhpfgdWVjh07prq6OufqrQ2io6P1+eefN7tPaWlps+1LS0vdVqcv6cg5P9fs2bPVq1evJm9oNK8j5/xvf/ubXnzxRRUVFXmgQt/TkXO+b98+/fnPf9bEiRO1YcMGffnll5o2bZpOnz6trKwsT5Tt1TpyzidMmKBjx47p2muvlWVZqq2tVXp6uh5++GFPlOyXWvoMraio0KlTpxQWFtam5/GpnhF4n2XLlikvL09/+MMfFBoaarocn/TNN99o0qRJysnJUffu3U2X4zfq6+vVs2dPPf/88xo5cqRSU1M1b948ZWdnmy7NZ23evFlLlizRs88+q+3bt+uNN97Q22+/rccee8x0aTgPn+oZ6d69uwIDA1VWVtZoe1lZmWJiYprdJyYmpl3t0VhHznmD5cuXa9myZfrTn/6koUOHurNMn9Lec753717t379f48aNc26rr6+XJAUFBWn37t3q16+fe4v2ch15n8fGxqpTp04KDAx0bhs4cKBKS0tVU1Oj4OBgt9bs7Tpyzh955BFNmjRJ99xzjyRpyJAhqqys1L333qt58+a5/Lb3aPkzNDIyss29IpKP9YwEBwdr5MiRys/Pd26rr69Xfn6+kpKSmt0nKSmpUXtJ2rRpU4vt0VhHzrkkPfnkk3rssce0ceNGJSQkeKJUn9Hec37FFVdo586dKioqcj5+/OMf6/rrr1dRUZHi4uI8Wb5X6sj7/JprrtGXX37pDH6StGfPHsXGxhJE2qAj57yqqqpJ4GgIgxa3YXMLl32Gtm9urf3l5eVZISEh1po1a6xdu3ZZ9957r9WlSxertLTUsizLmjRpkjVnzhxn+y1btlhBQUHW8uXLreLiYisrK4tLe9upved82bJlVnBwsPX73//eOnz4sPPxzTffmHoJXqe95/xcXE3Tfu095wcPHrQuuugi6+c//7m1e/dua/369VbPnj2txYsXm3oJXqe95zwrK8u66KKLrNdff93at2+f9e6771r9+vWz7rjjDlMvwet888031o4dO6wdO3ZYkqynn37a2rFjh3XgwAHLsixrzpw51qRJk5ztGy7t/cUvfmEVFxdbq1at4tLeBr/+9a+tSy65xAoODrZGjx5t/f3vf3d+b+zYsdbkyZMbtf/tb39rDRgwwAoODrYGDx5svf322x6u2Pu155z36dPHktTkkZWV5fnCvVh73+dnI4x0THvP+QcffGAlJiZaISEhVt++fa3HH3/cqq2t9XDV3q095/z06dPWwoULrX79+lmhoaFWXFycNW3aNOv48eOeL9xLvffee83+fW44z5MnT7bGjh3bZJ/hw4dbwcHBVt++fa2XX3653cd1WBZ9VwAAwByfmjMCAAC8D2EEAAAYRRgBAABGEUYAAIBRhBEAAGAUYQQAABhFGAEAAEYRRgAAgFGEEQAAYBRhBIBRdXV1GjNmjG677bZG28vLyxUXF6d58+YZqgyAp7AcPADj9uzZo+HDhysnJ0cTJ06UJKWlpenjjz9WYWEhd7kFfBxhBIAtPPPMM1q4cKE+++wzFRQU6Pbbb1dhYaGGDRtmujQAbkYYAWALlmXp+9//vgIDA7Vz507dd999mj9/vumyAHgAYQSAbXz++ecaOHCghgwZou3btysoKMh0SQA8gAmsAGzjpZdeUnh4uEpKSvSPf/zDdDkAPISeEQC28MEHH2js2LF69913tXjxYknSn/70JzkcDsOVAXA3ekYAGFdVVaW77rpLGRkZuv766/Xiiy+qoKBA2dnZpksD4AH0jAAwbsaMGdqwYYM+/vhjhYeHS5Kee+45zZo1Szt37lR8fLzZAgG4FWEEgFF/+ctf9IMf/ECbN2/Wtdde2+h7KSkpqq2tZbgG8HGEEQAAYBRzRgAAgFGEEQAAYBRhBAAAGEUYAQAARhFGAACAUYQRAABgFGEEAAAYRRgBAABGEUYAAIBRhBEAAGAUYQQAABj1/wH9sVaIn8QSCgAAAABJRU5ErkJggg==\n" | |
}, | |
"metadata": {} | |
} | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"This function gives the probability that a red point exists satisfying the problem's conditions given $\\vec{b}$:\n", | |
"\n", | |
"$$\n", | |
"f(b_x, b_y) = \\frac{\\pi r_0^2}{4} + \\frac{\\pi r_1^2}{4} - 2 \\int_0^{1 - b_x} \\sqrt{r_0^2 - x^2} + \\sqrt{r_1^2 - x^2} - 1 \\, dx\n", | |
"$$\n", | |
"\n", | |
"where $r_{0} = \\sqrt{(1-b_{x})^{2} + b_{y}^{2}}, r_{1} = \\sqrt{(1-b_{x})^{2} + (1-b_{y})^{2}}$.\n", | |
"\n", | |
"What we're looking for is the area under this contour over the \"wedge\" of the unit square given by $1 < b_{x} + b_{y} < 2b_{x}$.\n" | |
], | |
"metadata": { | |
"id": "wyb-1lqriQVS" | |
} | |
}, | |
{ | |
"cell_type": "markdown", | |
"source": [ | |
"Below, I proceed by estimating the final probability by generating a sample of points, $T$, in the \"wedge\" and computing $\\frac{1}{|T|} \\sum_{(b_x, b_y) \\in T} f(b_x,b_y)$." | |
], | |
"metadata": { | |
"id": "jaG5f80EvOJV" | |
} | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"from mpmath import mp, quad\n", | |
"\n", | |
"# Set the precision to ensure accuracy in intermediate calculations\n", | |
"mp.dps = 20\n", | |
"\n", | |
"def f(b_x, b_y):\n", | |
" r0 = mp.sqrt((1 - b_x)**2 + b_y**2)\n", | |
" r1 = mp.sqrt((1 - b_x)**2 + (1 - b_y)**2)\n", | |
"\n", | |
" def overlap_integral(x):\n", | |
" return mp.sqrt(r0**2 - x**2) + mp.sqrt(r1**2 - x**2) - 1\n", | |
"\n", | |
" area_quarters = (mp.pi * r0**2 / 4) + (mp.pi * r1**2 / 4)\n", | |
" overlap_area = quad(overlap_integral, [0, 1 - b_x])\n", | |
"\n", | |
" return area_quarters - 2 * overlap_area\n" | |
], | |
"metadata": { | |
"id": "eiOxne9Eka1K" | |
}, | |
"execution_count": null, | |
"outputs": [] | |
}, | |
{ | |
"cell_type": "code", | |
"source": [ | |
"T = [generate_point(True) for _ in range(N)]\n", | |
"p = sum(f(*b) for b in T) / (N)\n", | |
"\n", | |
"print(f\"Empirical total probability over the region ({N} samples):\", p)" | |
], | |
"metadata": { | |
"colab": { | |
"base_uri": "https://localhost:8080/" | |
}, | |
"id": "DUm5Ly3EwFe2", | |
"outputId": "a2176a0d-4e92-4807-e560-242a5903667c" | |
}, | |
"execution_count": null, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": [ | |
"Empirical total probability over the region (10000 samples): 0.49179896501722237376\n" | |
] | |
} | |
] | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment