From 53d201e5916e40ba33335312f66cf57a09d122f4 Mon Sep 17 00:00:00 2001 From: filifa Date: Fri, 18 Apr 2025 21:38:21 -0400 Subject: [PATCH] add problem 37 --- notebooks/problem0037.ipynb | 250 ++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) create mode 100644 notebooks/problem0037.ipynb diff --git a/notebooks/problem0037.ipynb b/notebooks/problem0037.ipynb new file mode 100644 index 0000000..76f7845 --- /dev/null +++ b/notebooks/problem0037.ipynb @@ -0,0 +1,250 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "6fcde6bd", + "metadata": {}, + "source": [ + "# [Truncatable Primes](https://projecteuler.net/problem=37)\n", + "\n", + "Apparently another term for these sorts of numbers is a [two-sided prime](https://en.wikipedia.org/wiki/Truncatable_prime).\n", + "\n", + "In case you're curious how we know there's only eleven of these primes (not including 2, 3, 5, or 7), this solution will outline it.\n", + "\n", + "We start by generating all the right-truncatable primes - the two-sided primes are necessarily a subset of these. If we know a number $n$ is *not* a right-truncatable prime, we know any number with $n$ as a prefix is *also* not a right-truncatable prime. This means we can start by looking at one-digit primes (2, 3, 5, and 7) and for each, try appending each of 1, 3, 7, and 9 and see which, if any, are also prime (appending any other digit would clearly result in a number divisible by 2 or 5). If we find another prime, we'll want to repeat the process of appending 1, 3, 7, or 9 to see if we can find more right-truncatable primes. We use a [depth-first search](https://en.wikipedia.org/wiki/Depth-first_search) for this." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "fecd8e1a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{23,\n", + " 29,\n", + " 31,\n", + " 37,\n", + " 53,\n", + " 59,\n", + " 71,\n", + " 73,\n", + " 79,\n", + " 233,\n", + " 239,\n", + " 293,\n", + " 311,\n", + " 313,\n", + " 317,\n", + " 373,\n", + " 379,\n", + " 593,\n", + " 599,\n", + " 719,\n", + " 733,\n", + " 739,\n", + " 797,\n", + " 2333,\n", + " 2339,\n", + " 2393,\n", + " 2399,\n", + " 2939,\n", + " 3119,\n", + " 3137,\n", + " 3733,\n", + " 3739,\n", + " 3793,\n", + " 3797,\n", + " 5939,\n", + " 7193,\n", + " 7331,\n", + " 7333,\n", + " 7393,\n", + " 23333,\n", + " 23339,\n", + " 23399,\n", + " 23993,\n", + " 29399,\n", + " 31193,\n", + " 31379,\n", + " 37337,\n", + " 37339,\n", + " 37397,\n", + " 59393,\n", + " 59399,\n", + " 71933,\n", + " 73331,\n", + " 73939,\n", + " 233993,\n", + " 239933,\n", + " 293999,\n", + " 373379,\n", + " 373393,\n", + " 593933,\n", + " 593993,\n", + " 719333,\n", + " 739391,\n", + " 739393,\n", + " 739397,\n", + " 739399,\n", + " 2339933,\n", + " 2399333,\n", + " 2939999,\n", + " 3733799,\n", + " 5939333,\n", + " 7393913,\n", + " 7393931,\n", + " 7393933,\n", + " 23399339,\n", + " 29399999,\n", + " 37337999,\n", + " 59393339,\n", + " 73939133}" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "right_truncatable_primes = set()\n", + "\n", + "visited = set()\n", + "stack = [2, 3, 5, 7]\n", + "while stack != []:\n", + " n = stack.pop()\n", + " if n in visited:\n", + " continue\n", + " visited.add(n)\n", + " \n", + " for d in (1,3,7,9):\n", + " m = 10*n + d\n", + " if is_prime(m):\n", + " right_truncatable_primes.add(m)\n", + " stack.append(m)\n", + "\n", + "right_truncatable_primes" + ] + }, + { + "cell_type": "markdown", + "id": "95481066", + "metadata": {}, + "source": [ + "Next, we write a function for checking if a prime is left-truncatable." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "6922aa89", + "metadata": {}, + "outputs": [], + "source": [ + "from itertools import count\n", + "\n", + "def is_left_truncatable_prime(p):\n", + " for k in count(1):\n", + " t = p % 10^k\n", + " if not is_prime(t):\n", + " return False\n", + " if t == p:\n", + " break\n", + " \n", + " return True" + ] + }, + { + "cell_type": "markdown", + "id": "f20fe991", + "metadata": {}, + "source": [ + "Now just check all our right-truncatable primes to see if they are also left-truncatable." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "995c5372", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "{23, 37, 53, 73, 313, 317, 373, 797, 3137, 3797, 739397}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "two_sided_primes = {p for p in right_truncatable_primes if is_left_truncatable_prime(p)}\n", + "two_sided_primes" + ] + }, + { + "cell_type": "markdown", + "id": "97f60cbd", + "metadata": {}, + "source": [ + "Sure enough, only eleven two-sided primes." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "3851ffee", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "748317" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "sum(two_sided_primes)" + ] + }, + { + "cell_type": "markdown", + "id": "8f55a757", + "metadata": {}, + "source": [ + "## Relevant sequences\n", + "* Two-sided primes: [A020994](https://oeis.org/A020994)" + ] + } + ], + "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 +}