{ "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 }