From 32f026119b68302bb6e6dd61ebd1a8b7d12db996 Mon Sep 17 00:00:00 2001 From: filifa Date: Mon, 7 Jul 2025 22:08:55 -0400 Subject: [PATCH] add problem 88 --- notebooks/problem0088.ipynb | 132 ++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 notebooks/problem0088.ipynb diff --git a/notebooks/problem0088.ipynb b/notebooks/problem0088.ipynb new file mode 100644 index 0000000..828d150 --- /dev/null +++ b/notebooks/problem0088.ipynb @@ -0,0 +1,132 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "07e32e17", + "metadata": {}, + "source": [ + "# [Product-sum Numbers](https://projecteuler.net/problem=88)\n", + "\n", + "For any set size $k$, we can always construct a product-sum number as $1+1+1+\\cdots+1+2+k = 2k$, where there are $k-2$ 1s in the sum and product. $2k$ is not necessarily the *minimal* product-sum number for $k$ - nevertheless, it serves as an upper bound." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "f2fbfe35", + "metadata": {}, + "outputs": [], + "source": [ + "limit = 12000\n", + "mins = {k: 2*k for k in range(2, limit + 1)}\n", + "mins[1] = 1" + ] + }, + { + "cell_type": "markdown", + "id": "bc89bb94", + "metadata": {}, + "source": [ + "If we have a set of numbers with product $p$ and sum $s$, we can construct a product-sum number by simply adding 1s to the set until $p = s$. With this fact, we can simply run a search over all the sets of factors and compute the product and sum of each, stopping if either exceeds 24000. Instead of tracking each set, we only need to keep track of the product, sum, and number of non-one elements in each set." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "a63c9c05", + "metadata": {}, + "outputs": [], + "source": [ + "from itertools import count\n", + "\n", + "visited = set()\n", + "stack = [(n, n, 1) for n in range(2, limit + 1)]\n", + "while stack != []:\n", + " # m: number of non-one elements\n", + " p, s, m = stack.pop()\n", + " if (p, s, m) in visited:\n", + " continue\n", + " visited.add((p, s, m))\n", + " \n", + " m += 1\n", + " for x in count(2):\n", + " product = p * x\n", + " if product > 2 * limit:\n", + " break\n", + " \n", + " total = s + x\n", + " if total > 2 * limit:\n", + " break\n", + " \n", + " k = product - total\n", + " if k + m > limit:\n", + " break\n", + "\n", + " mins[k + m] = min(mins[k + m], product)\n", + " \n", + " stack.append((product, total, m))" + ] + }, + { + "cell_type": "markdown", + "id": "be98da43", + "metadata": {}, + "source": [ + "After the search ends, the dictionary will hold the minimal product-sum number for each value of $k$." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "98a74337", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "7587457" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "del mins[1]\n", + "sum(set(mins.values()))" + ] + }, + { + "cell_type": "markdown", + "id": "0e9ff8c0", + "metadata": {}, + "source": [ + "## Relevant sequences\n", + "* Minimal product-sum numbers: [A104173](https://oeis.org/A104173)\n", + "* Set sizes $k$ with a minimal product-sum number of $2k$: [A033179](https://oeis.org/A033179)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "SageMath 9.5", + "language": "sage", + "name": "sagemath" + }, + "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.11.2" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +}