All square roots are periodic when written as continued fractions and can be written in the form:
1 | |||
a | 1 +1 | ||
a | 2 +1 | ||
a | 3 + ...
For example, let us consider 23:
1 | = 4 + | 1 | ||
1 | 1 + | 7 |
If we continue we would get the following expansion:
1 | ||||
1 + | 1 | |||
3 + | 1 | |||
1 + | 1 | |||
8 + ... |
The process can be summarised as follows:
a | 0 = 4,1 | = | 7 | = 1 + | 7 | |
a | 1 = 1,7 | = | 7( 14 | = 3 + | 2 | |
a | 2 = 3,2 | = | 2( 14 | = 1 + | 7 | |
a | 3 = 1,7 | = | 7( 7 | = 8 + | ||
a | 4 = 8,1 | = | 7 | = 1 + | 7 | |
a | 5 = 1,7 | = | 7( 14 | = 3 + | 2 | |
a | 6 = 3,2 | = | 2( 14 | = 1 + | 7 | |
a | 7 = 1,7 | = | 7( 7 | = 8 + |
It can be seen that the sequence is repeating. For conciseness, we use the notation 23 = [4;(1,3,1,8)], to indicate that the block (1,3,1,8) repeats indefinitely.
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?
This was certainly an education in continued fractions. Having understood them the trick is to find a way to calculate the salient numbers for the next iteration. 62.5 ms. Uncomment the foreach loop to print the series.
using System;
using System.Collections.Generic;
namespace project_euler
{
class Program
{
static void Main()
{
//Problem 64
DateTime start = DateTime.Now;
Dictionary<int, List<int>> numbers = new Dictionary<int, List<int>>();
for (int number = 2; number <= 10000; number++)
{
bool repeat = false;
int a = (int)Math.Sqrt(number);
List<int> sequence = new List<int> { a };
numbers.Add(number, sequence);
int x = 1;
do
{
if (Math.Sqrt(number) - (int)Math.Sqrt(number) == 0) break;
int b = number - a * a;
int integerPart = x * ((int)Math.Sqrt(number) + a) / b;
numbers[number].Add(integerPart);
a = -(a - integerPart * (b / x));
x = (b / x);
if (integerPart == 2 * numbers[number][0]) repeat = true;
} while (!repeat);
}
int oddSequence=0;
foreach (KeyValuePair<int, List<int>> pair in numbers)
{
if ((pair.Value.Count - 1)%2 != 0)
oddSequence++;
//Console.Write(pair.Key + ": ");
//foreach (int sequence in pair.Value)
// Console.Write(sequence + ", ");
//Console.WriteLine();
}
Console.WriteLine(oddSequence);
TimeSpan time = DateTime.Now - start;
Console.WriteLine("This took {0}", time);
Console.ReadKey();
}
}
}
No comments:
Post a Comment