Solved 66.

main
Felix Martin 2019-01-28 16:59:13 -05:00
parent 340911de33
commit baa915041c
3 changed files with 12315 additions and 0 deletions

View File

@ -0,0 +1,276 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Diophantine equation (Euler Problem 66)"
]
},
{
"cell_type": "markdown",
"metadata": {
"collapsed": true
},
"source": [
"Consider quadratic Diophantine equations of the form:\n",
"\n",
"$x^2 Dy^2 = 1$\n",
"\n",
"For example, when D=13, the minimal solution in x is 6492 13×1802 = 1.\n",
"\n",
"It can be assumed that there are no solutions in positive integers when D is square.\n",
"\n",
"By finding minimal solutions in x for D = {2, 3, 5, 6, 7}, we obtain the following:\n",
"\n",
"$3^2 2×2^2 = 1$\n",
"\n",
"$2^2 3×1^2 = 1$\n",
"\n",
"$9^2 5×4^2 = 1$\n",
"\n",
"$5^2 6×2^2 = 1$\n",
"\n",
"$8^2 7×3^2 = 1$\n",
"\n",
"Hence, by considering minimal solutions in x for D ≤ 7, the largest x is obtained when D=5.\n",
"\n",
"Find the value of D ≤ 1000 in minimal solutions of x for which the largest value of x is obtained.\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import math\n",
"\n",
"def get_floor_sqrt(n):\n",
" return math.floor(math.sqrt(n))\n",
"\n",
"assert(get_floor_sqrt(5) == 2)\n",
"assert(get_floor_sqrt(23) == 4)\n",
"\n",
"def next_expansion_1(current_a, current_nominator, current_denominator, original_number):\n",
" cn = current_nominator\n",
" cd = current_denominator\n",
" cn, cd = cd, (original_number - cd * cd) // cn\n",
" next_a = math.floor((math.sqrt(original_number) + cn) // cd)\n",
" cn = cn - next_a * cd\n",
" cn *= -1\n",
" \n",
" return next_a, cn, cd\n",
"\n",
"def get_continued_fraction_sequence(n):\n",
" \n",
" # If number is a square number we return it.\n",
" floor_sqrt = get_floor_sqrt(n)\n",
" if n == floor_sqrt * floor_sqrt:\n",
" return ((floor_sqrt), [])\n",
" \n",
" # Otherwise, we calculate the next expansion till we\n",
" # encounter a step a second time. \n",
" a = floor_sqrt\n",
" cn = a\n",
" cd = 1\n",
" sequence = []\n",
" previous_steps = []\n",
" \n",
" while not (a, cn, cd) in previous_steps :\n",
" #print(\"a: {} cn: {} cd: {}\".format(a, cn, cd))\n",
" previous_steps.append((a, cn, cd))\n",
" a, cn, cd = next_expansion_1(a, cd, cn, n)\n",
" sequence.append(a)\n",
" sequence.pop()\n",
" return ((floor_sqrt), sequence)\n",
"\n",
"def get_continued_fraction_sequence(n):\n",
" \n",
" # If number is a square number we return it.\n",
" floor_sqrt = get_floor_sqrt(n)\n",
" if n == floor_sqrt * floor_sqrt:\n",
" return ((floor_sqrt), [])\n",
" \n",
" # Otherwise, we calculate the next expansion till we\n",
" # encounter a step a second time. \n",
" a = floor_sqrt\n",
" cn = a\n",
" cd = 1\n",
" sequence = []\n",
" previous_steps = []\n",
" \n",
" while not (a, cn, cd) in previous_steps :\n",
" #print(\"a: {} cn: {} cd: {}\".format(a, cn, cd))\n",
" previous_steps.append((a, cn, cd))\n",
" a, cn, cd = next_expansion_1(a, cd, cn, n)\n",
" sequence.append(a)\n",
" sequence.pop()\n",
" return ((floor_sqrt), sequence)\n",
"\n",
"assert(get_continued_fraction_sequence(1) == ((1), []))\n",
"assert(get_continued_fraction_sequence(4) == ((2), []))\n",
"assert(get_continued_fraction_sequence(25) == ((5), []))\n",
"assert(get_continued_fraction_sequence(2) == ((1), [2]))\n",
"assert(get_continued_fraction_sequence(3) == ((1), [1,2]))\n",
"assert(get_continued_fraction_sequence(5) == ((2), [4]))\n",
"assert(get_continued_fraction_sequence(13) == ((3), [1,1,1,1,6]))"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [],
"source": [
"def gcd(a, b):\n",
" if b > a:\n",
" a, b = b, a\n",
" while a % b != 0:\n",
" a, b = b, a % b\n",
" return b\n",
"\n",
"def add_fractions(n1, d1, n2, d2):\n",
" d = d1 * d2\n",
" n1 = n1 * (d // d1)\n",
" n2 = n2 * (d // d2)\n",
" n = n1 + n2\n",
" p = gcd(n, d)\n",
" return (n // p, d // p)\n",
"\n",
"def next_expansion_2(previous_numerator, previous_denumerator, value):\n",
" if previous_numerator == 0:\n",
" return (value, 1)\n",
" return add_fractions(previous_denumerator, previous_numerator, value, 1)\n",
" \n",
"def get_fractions(n, x):\n",
" #print(\"get_fractions(n={}, x={})\".format(n, x))\n",
" # Get sequence of a_x\n",
" first_value, sequence = get_continued_fraction_sequence(n)\n",
" sequence = [first_value] + math.ceil(x / len(sequence)) * sequence\n",
" sequence = sequence[:x + 1]\n",
" sequence = sequence[::-1]\n",
" \n",
" n, d = 0, 1\n",
" for s in sequence:\n",
" n, d = next_expansion_2(n, d, s)\n",
" return (n, d)\n",
"\n",
"assert(get_fractions(7, 0) == (2, 1))\n",
"assert(get_fractions(7, 1) == (3, 1))\n",
"assert(get_fractions(7, 2) == (5, 2))\n",
"assert(get_fractions(7, 3) == (8, 3))"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"def get_minimal_solution(d):\n",
" for i in range(0, 100):\n",
" x, y = get_fractions(d, i)\n",
" if x * x - d * y * y == 1:\n",
" return((x, y))\n",
"\n",
"assert(get_minimal_solution(2) == (3, 2))\n",
"assert(get_minimal_solution(3) == (2, 1))\n",
"assert(get_minimal_solution(85) == (285769, 30996))\n",
"assert(get_minimal_solution(109) == (158070671986249, 15140424455100))"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"True\n"
]
}
],
"source": [
"from math import sqrt\n",
"\n",
"def is_square(n):\n",
" return sqrt(n).is_integer()\n",
"\n",
"print(is_square(4))"
]
},
{
"cell_type": "code",
"execution_count": 55,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"d: 661 x: 16421658242965910275055840472270471049\n"
]
}
],
"source": [
"x_max = 0\n",
"d_max = 0\n",
"\n",
"for d in range(2, 1001):\n",
" if is_square(d):\n",
" continue\n",
" \n",
" x, y = get_minimal_solution(d)\n",
" if x > x_max:\n",
" x_max = x\n",
" d_max = d\n",
"\n",
"print(\"d: {} x: {}\".format(d_max, x_max))\n",
"s = d_max\n",
"assert(s == 661)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": []
}
],
"metadata": {
"completion_date": "Tue, 22 Jan 2019, 05:10",
"kernelspec": {
"display_name": "Python 3",
"language": "python3.6",
"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.6.5"
},
"tags": [
"fractions",
"square roots",
"sequence",
"periodic"
]
},
"nbformat": 4,
"nbformat_minor": 2
}

File diff suppressed because it is too large Load Diff

View File

@ -1039,6 +1039,24 @@
</tr>
<tr>
<td><a href="EulerProblem066.html">Problem 066</a></td>
<td>Tue, 22 Jan 2019, 05:10</td>
<td>
<kbd>fractions</kbd>
<kbd>square roots</kbd>
<kbd>sequence</kbd>
<kbd>periodic</kbd>
</td>
</tr>
<tr>
<td><a href="EulerProblem067.html">Problem 067</a></td>