eulerbooks/notebooks/problem0068.ipynb

194 lines
5.0 KiB
Plaintext

{
"cells": [
{
"cell_type": "markdown",
"id": "371d0171",
"metadata": {},
"source": [
"# [Magic 5-gon ring](https://projecteuler.net/problem=68)\n",
"\n",
"We can brute force this by considering all permutations of 1 through 10. For each permutation, we'll assign the first five values to the five external nodes, and the last five values will go in the internal ring. By assigning this way, we can easily obtain the indices of all the nodes along any given line in the 5-gon. The first node along a line will have index $i$, the second $i + 5$, and the third $i + 6$ (except if $i=4$, in which case the third index will be 5).\n",
"\n",
"Here's a function to handle the index logic (this and following methods are written to work for any $n$-gon)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "72c416e9",
"metadata": {},
"outputs": [],
"source": [
"def line_indices(i, n):\n",
" j = i + n\n",
" k = (i + 1) % n + n\n",
" return (i, j, k)"
]
},
{
"cell_type": "markdown",
"id": "3510bee0",
"metadata": {},
"source": [
"We'll have $10!=3628800$ permutations to check. If all the lines add to the same value as the first line, we have a magic ring."
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "37ea9e61",
"metadata": {},
"outputs": [],
"source": [
"from itertools import permutations\n",
"\n",
"def is_magic_ring(x, n):\n",
" line_sum = x[0] + x[n] + x[n + 1]\n",
" for i in range(1, n):\n",
" i, j, k = line_indices(i, n)\n",
" if x[i] + x[j] + x[k] != line_sum:\n",
" return False\n",
" \n",
" return True\n",
"\n",
"\n",
"def magic_rings(n):\n",
" for x in permutations(range(1, 2*n + 1)):\n",
" if is_magic_ring(x, n):\n",
" yield x"
]
},
{
"cell_type": "markdown",
"id": "515484ce",
"metadata": {},
"source": [
"We'll need to reformat any magic rings we find in the form described in the problem. The solution string always starts with the lowest external node, so we use a [deque](https://docs.python.org/3/library/collections.html) to rotate."
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "669c130b",
"metadata": {},
"outputs": [],
"source": [
"from collections import deque\n",
"\n",
"def solution_string(x):\n",
" lines = deque()\n",
" n = len(x) // 2\n",
" for i in range(0, n):\n",
" i, j, k = line_indices(i, n)\n",
" lines.append((x[i], x[j], x[k]))\n",
" \n",
" lowest_ext = min(range(0, n), key=lambda i: lines[i][0])\n",
" lines.rotate(-lowest_ext)\n",
" \n",
" return \"\".join(str(m) for line in lines for m in line)"
]
},
{
"cell_type": "markdown",
"id": "6db5a5a6",
"metadata": {},
"source": [
"Then we can just map this function over all the magic rings we find."
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "07928c04",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'11069627285843410',\n",
" '11085864693972710',\n",
" '16103104548782926',\n",
" '18102107379496568',\n",
" '21049436378715110',\n",
" '24105101817673934',\n",
" '2594936378711015',\n",
" '27858434106101917',\n",
" '28797161103104548',\n",
" '2951051817673439',\n",
" '6357528249411013',\n",
" '6531031914842725'}"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sols = {solution_string(x) for x in magic_rings(5)}\n",
"sols"
]
},
{
"cell_type": "markdown",
"id": "b1f8a706",
"metadata": {},
"source": [
"Note that we're only considering 16-digit solution strings."
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "9b0e2f19",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'6531031914842725'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"max((s for s in sols if len(s) == 16), key=int)"
]
},
{
"cell_type": "markdown",
"id": "e5000191",
"metadata": {},
"source": [
"#### Copyright (C) 2025 filifa\n",
"\n",
"This work is licensed under the [Creative Commons Attribution-ShareAlike 4.0 International license](https://creativecommons.org/licenses/by-sa/4.0/) and the [BSD Zero Clause license](https://spdx.org/licenses/0BSD.html)."
]
}
],
"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
}