{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Euler Problem 26\n", "\n", "A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:\n", "\n", "~~~\n", "1/2\t = \t0.5\n", "1/3\t = \t0.(3)\n", "1/4\t = \t0.25\n", "1/5\t = \t0.2\n", "1/6\t = \t0.1(6)\n", "1/7\t = \t0.(142857)\n", "1/8\t = \t0.125\n", "1/9\t = \t0.(1)\n", "1/10 = \t0.1\n", "~~~\n", "\n", "Where 0.1(6) means 0.166666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.\n", "\n", "Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The trick here is to identify a cycle. The easiest way I see to do this is to memorize the remainders. If we have a remainder that we occurred previously there is a cycle.\n", "\n", "Let's consider 1/3. The initial remainder is 10. For ten divided by three the new remainder is again ten (or one times ten). So we have a one-cycle of 3." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def get_cycle_count(nominator, denominator):\n", " from itertools import count\n", " assert(nominator == 1)\n", " remainders = {}\n", " remainder = nominator\n", " results = []\n", " for i in count():\n", " result = remainder // denominator\n", " remainder = remainder % denominator\n", " results.append(result)\n", " if remainder in remainders:\n", " return i - remainders[remainder]\n", " else:\n", " remainders[remainder] = i\n", " if remainder == 0:\n", " return 0\n", " remainder *= 10\n", "\n", "assert(get_cycle_count(1, 7) == 6)\n", "assert(get_cycle_count(1, 10) == 0)\n", "assert(get_cycle_count(1, 6) == 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is a simple divison algorithm. The only special thing is the remainder and that we remember when it occurs the first time. If a remainder occurrs for the second time we substract the position and thus have the lenght of the cycle. With this solution we should be efficient enough to brute force." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "983\n" ] } ], "source": [ "s = max([(get_cycle_count(1, i), i)for i in range(1, 1000)])\n", "s = s[1]\n", "assert(s == 983)\n", "print(s)" ] } ], "metadata": { "completion_date": "Mon, 9 Nov 2015, 22:11", "kernelspec": { "display_name": "Python 3", "language": "python", "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.5.4" }, "tags": [ "reciprocal", "division", "nominator", "denominator" ] }, "nbformat": 4, "nbformat_minor": 0 }