From b28b59fc7d8148904c0b83b1a3706a0c5ac9ddf8 Mon Sep 17 00:00:00 2001 From: Felix Martin Date: Tue, 22 Jan 2019 00:12:10 -0500 Subject: [PATCH] Solved 64. --- ipython/EulerProblem063.ipynb | 58 +- ipython/EulerProblem064.ipynb | 213 + ipython/html/EulerProblem063.html | 59 +- ipython/html/EulerProblem064.html | 11952 ++++++++++++++++++++++++++++ ipython/html/index.html | 24 +- 5 files changed, 12300 insertions(+), 6 deletions(-) create mode 100644 ipython/EulerProblem064.ipynb create mode 100644 ipython/html/EulerProblem064.html diff --git a/ipython/EulerProblem063.ipynb b/ipython/EulerProblem063.ipynb index 2e15469..4a6cb71 100644 --- a/ipython/EulerProblem063.ipynb +++ b/ipython/EulerProblem063.ipynb @@ -13,11 +13,61 @@ "collapsed": true }, "source": [ - "The 5-digit number, 16807=75, is also a fifth power. Similarly, the 9-digit number, 134217728=89, is a ninth power.\n", + "The 5-digit number, 16807=$7^5$, is also a fifth power. Similarly, the 9-digit number, 134217728=$8^9$, is a ninth power.\n", "\n", "How many n-digit positive integers exist which are also an nth power?" ] }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "def get_digit_count(n):\n", + " if n < 10:\n", + " return 1\n", + " c = 0\n", + " while n:\n", + " n //= 10\n", + " c += 1\n", + " return c\n", + "\n", + "assert(get_digit_count(0) == 1)\n", + "assert(get_digit_count(1) == 1)\n", + "assert(get_digit_count(33) == 2)\n", + "assert(get_digit_count(100) == 3)" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "49\n" + ] + } + ], + "source": [ + "def get_n_digit_positive_integers(n):\n", + " r = []\n", + " i = 1\n", + " while True:\n", + " if get_digit_count(i ** n) == n:\n", + " r.append(i ** n)\n", + " if get_digit_count(i ** n) > n:\n", + " return r\n", + " i += 1\n", + "\n", + "s = sum([len(get_n_digit_positive_integers(n)) for n in range(1, 1000)])\n", + "print(s)\n", + "assert(s == 49)" + ] + }, { "cell_type": "code", "execution_count": null, @@ -29,7 +79,7 @@ } ], "metadata": { - "completion_date": "", + "completion_date": "Sun, 6 Jan 2019, 06:17", "kernelspec": { "display_name": "Python 3", "language": "python3.6", @@ -47,7 +97,9 @@ "pygments_lexer": "ipython3", "version": "3.6.5" }, - "tags": [] + "tags": [ + "powers" + ] }, "nbformat": 4, "nbformat_minor": 2 diff --git a/ipython/EulerProblem064.ipynb b/ipython/EulerProblem064.ipynb new file mode 100644 index 0000000..3f53012 --- /dev/null +++ b/ipython/EulerProblem064.ipynb @@ -0,0 +1,213 @@ +{ + "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 +} diff --git a/ipython/html/EulerProblem063.html b/ipython/html/EulerProblem063.html index ce8c2fe..64c5fd6 100644 --- a/ipython/html/EulerProblem063.html +++ b/ipython/html/EulerProblem063.html @@ -11778,13 +11778,70 @@ div#notebook {
-

The 5-digit number, 16807=75, is also a fifth power. Similarly, the 9-digit number, 134217728=89, is a ninth power.

+

The 5-digit number, 16807=$7^5$, is also a fifth power. Similarly, the 9-digit number, 134217728=$8^9$, is a ninth power.

How many n-digit positive integers exist which are also an nth power?

+
In [1]:
+
+
+
def get_digit_count(n):
+    if n < 10:
+        return 1
+    c = 0
+    while n:
+        n //= 10
+        c += 1
+    return c
+
+assert(get_digit_count(0) == 1)
+assert(get_digit_count(1) == 1)
+assert(get_digit_count(33) == 2)
+assert(get_digit_count(100) == 3)
+
+
+
+
+
+
+
+
In [2]:
+
+
+
def get_n_digit_positive_integers(n):
+    r = []
+    i = 1
+    while True:
+        if get_digit_count(i ** n) == n:
+            r.append(i ** n)
+        if get_digit_count(i ** n) > n:
+            return r
+        i += 1
+
+s = sum([len(get_n_digit_positive_integers(n)) for n in range(1, 1000)])
+print(s)
+assert(s == 49)
+
+
+
+
+
+
+
+
+
+
49
+
+
+
+
+
+
+
+
In [ ]:
diff --git a/ipython/html/EulerProblem064.html b/ipython/html/EulerProblem064.html new file mode 100644 index 0000000..8a29024 --- /dev/null +++ b/ipython/html/EulerProblem064.html @@ -0,0 +1,11952 @@ + + + + +EulerProblem064 + + + + + + + + + + + + + + +
+
+
+
+
+
+

Odd period square roots (Euler Problem 64)

Back to overview.

+
+
+
+
+
+
+
+

https://projecteuler.net/problem=64

+

The first ten continued fraction representations of (irrational) square roots are:

+

√2=[1;(2)], period=1

+

√3=[1;(1,2)], period=2

+

√5=[2;(4)], period=1

+

√6=[2;(2,4)], period=2

+

√7=[2;(1,1,1,4)], period=4

+

√8=[2;(1,4)], period=2

+

√10=[3;(6)], period=1

+

√11=[3;(3,6)], period=2

+

√12= [3;(2,6)], period=2

+

√13=[3;(1,1,1,1,6)], period=5

+

Exactly four continued fractions, for N ≤ 13, have an odd period.

+

How many continued fractions for N ≤ 10000 have an odd period?

+
+
+
+
+
+
In [1]:
+
+
+
import math
+
+def get_floor_sqrt(n):
+    return math.floor(math.sqrt(n))
+
+assert(get_floor_sqrt(5) == 2)
+assert(get_floor_sqrt(23) == 4)
+
+
+
+
+
+
+
+
In [2]:
+
+
+
def next_expansion(current_a, current_nominator, current_denominator, original_number):
+    # Less typing
+    cn = current_nominator
+    cd = current_denominator
+
+    # Step 1: Multiply the fraction so that we can use the third binomial formula.
+    # Make sure we can reduce the nominator.
+    assert((original_number - cd * cd) % cn == 0)
+    # The new nominator is the denominator since we multiply with (x + cd) and then
+    # reduce the previous nominator.
+    # The new denominator is calculated by applying the third binomial formula and
+    # then by divided by the previous nominator.
+    cn, cd = cd, (original_number - cd * cd) // cn
+    
+    # Step 2: Calculate the next a by finding the next floor square root.
+    next_a = math.floor((math.sqrt(original_number) + cn) // cd)
+    
+    # Step 3: Remove next a from the fraction by substracting it.
+    cn = cn - next_a * cd
+    cn *= -1
+    
+    return next_a, cn, cd
+
+next_expansion(1, 7, 3, 23)
+
+
+
+
+
+
+
+
Out[2]:
+
+
(3, 3, 2)
+
+
+
+
+
+
+
+
In [3]:
+
+
+
def get_continued_fraction_sequence(n):
+    
+    # If number is a square number we return it.
+    floor_sqrt = get_floor_sqrt(n)
+    if n == floor_sqrt * floor_sqrt:
+        return ((floor_sqrt), [])
+    
+    # Otherwise, we calculate the next expansion till we
+    # encounter a step a second time.    
+    a = floor_sqrt
+    cn = a
+    cd = 1
+    sequence = []
+    previous_steps = []
+    
+    while not (a, cn, cd) in previous_steps :
+        #print("a: {} cn: {} cd: {}".format(a, cn, cd))
+        previous_steps.append((a, cn, cd))
+        a, cn, cd = next_expansion(a, cd, cn, n)
+        sequence.append(a)
+    sequence.pop()
+    return ((floor_sqrt), sequence)
+
+assert(get_continued_fraction_sequence(1) == ((1), []))
+assert(get_continued_fraction_sequence(4) == ((2), []))
+assert(get_continued_fraction_sequence(25) == ((5), []))
+assert(get_continued_fraction_sequence(2) == ((1), [2]))
+assert(get_continued_fraction_sequence(3) == ((1), [1,2]))
+assert(get_continued_fraction_sequence(5) == ((2), [4]))
+assert(get_continued_fraction_sequence(13) == ((3), [1,1,1,1,6]))
+
+
+
+
+
+
+
+
In [4]:
+
+
+
def get_period(n):
+    _, sequence = get_continued_fraction_sequence(n)
+    return len(sequence)
+
+assert(get_period(23) == 4)
+
+
+
+
+
+
+
+
In [5]:
+
+
+
s = len([n for n in range(1, 10001) if get_period(n) % 2 != 0])
+print(s)
+assert(s == 1322)
+
+
+
+
+
+
+
+
+
+
1322
+
+
+
+
+
+
+
+
+
In [ ]:
+
+
+
 
+
+
+
+
+
+
+
+ + diff --git a/ipython/html/index.html b/ipython/html/index.html index 8d72278..417885f 100644 --- a/ipython/html/index.html +++ b/ipython/html/index.html @@ -993,12 +993,32 @@ - + Problem 063 - + Sun, 6 Jan 2019, 06:17 + powers + + + + + + + + Problem 064 + Tue, 22 Jan 2019, 05:10 + + + fractions + + square roots + + sequence + + periodic +