214 lines
5.5 KiB
Plaintext
214 lines
5.5 KiB
Plaintext
|
{
|
||
|
"cells": [
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {},
|
||
|
"source": [
|
||
|
"# Odd period square roots (Euler Problem 64)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "markdown",
|
||
|
"metadata": {
|
||
|
"collapsed": true
|
||
|
},
|
||
|
"source": [
|
||
|
"[https://projecteuler.net/problem=64](https://projecteuler.net/problem=64)\n",
|
||
|
"\n",
|
||
|
"The first ten continued fraction representations of (irrational) square roots are:\n",
|
||
|
"\n",
|
||
|
"√2=[1;(2)], period=1\n",
|
||
|
"\n",
|
||
|
"√3=[1;(1,2)], period=2\n",
|
||
|
"\n",
|
||
|
"√5=[2;(4)], period=1\n",
|
||
|
"\n",
|
||
|
"√6=[2;(2,4)], period=2\n",
|
||
|
"\n",
|
||
|
"√7=[2;(1,1,1,4)], period=4\n",
|
||
|
"\n",
|
||
|
"√8=[2;(1,4)], period=2\n",
|
||
|
"\n",
|
||
|
"√10=[3;(6)], period=1\n",
|
||
|
"\n",
|
||
|
"√11=[3;(3,6)], period=2\n",
|
||
|
"\n",
|
||
|
"√12= [3;(2,6)], period=2\n",
|
||
|
"\n",
|
||
|
"√13=[3;(1,1,1,1,6)], period=5\n",
|
||
|
"\n",
|
||
|
"Exactly four continued fractions, for N ≤ 13, have an odd period.\n",
|
||
|
"\n",
|
||
|
"How many continued fractions for N ≤ 10000 have an odd period?"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 1,
|
||
|
"metadata": {},
|
||
|
"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)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 2,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"data": {
|
||
|
"text/plain": [
|
||
|
"(3, 3, 2)"
|
||
|
]
|
||
|
},
|
||
|
"execution_count": 2,
|
||
|
"metadata": {},
|
||
|
"output_type": "execute_result"
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"def next_expansion(current_a, current_nominator, current_denominator, original_number):\n",
|
||
|
" # Less typing\n",
|
||
|
" cn = current_nominator\n",
|
||
|
" cd = current_denominator\n",
|
||
|
"\n",
|
||
|
" # Step 1: Multiply the fraction so that we can use the third binomial formula.\n",
|
||
|
" # Make sure we can reduce the nominator.\n",
|
||
|
" assert((original_number - cd * cd) % cn == 0)\n",
|
||
|
" # The new nominator is the denominator since we multiply with (x + cd) and then\n",
|
||
|
" # reduce the previous nominator.\n",
|
||
|
" # The new denominator is calculated by applying the third binomial formula and\n",
|
||
|
" # then by divided by the previous nominator.\n",
|
||
|
" cn, cd = cd, (original_number - cd * cd) // cn\n",
|
||
|
" \n",
|
||
|
" # Step 2: Calculate the next a by finding the next floor square root.\n",
|
||
|
" next_a = math.floor((math.sqrt(original_number) + cn) // cd)\n",
|
||
|
" \n",
|
||
|
" # Step 3: Remove next a from the fraction by substracting it.\n",
|
||
|
" cn = cn - next_a * cd\n",
|
||
|
" cn *= -1\n",
|
||
|
" \n",
|
||
|
" return next_a, cn, cd\n",
|
||
|
"\n",
|
||
|
"next_expansion(1, 7, 3, 23)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 3,
|
||
|
"metadata": {},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"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(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": 4,
|
||
|
"metadata": {
|
||
|
"collapsed": true
|
||
|
},
|
||
|
"outputs": [],
|
||
|
"source": [
|
||
|
"def get_period(n):\n",
|
||
|
" _, sequence = get_continued_fraction_sequence(n)\n",
|
||
|
" return len(sequence)\n",
|
||
|
"\n",
|
||
|
"assert(get_period(23) == 4)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"cell_type": "code",
|
||
|
"execution_count": 5,
|
||
|
"metadata": {},
|
||
|
"outputs": [
|
||
|
{
|
||
|
"name": "stdout",
|
||
|
"output_type": "stream",
|
||
|
"text": [
|
||
|
"1322\n"
|
||
|
]
|
||
|
}
|
||
|
],
|
||
|
"source": [
|
||
|
"s = len([n for n in range(1, 10001) if get_period(n) % 2 != 0])\n",
|
||
|
"print(s)\n",
|
||
|
"assert(s == 1322)"
|
||
|
]
|
||
|
},
|
||
|
{
|
||
|
"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
|
||
|
}
|