Project Euler/64: Difference between revisions
From charlesreid1
(→Code) |
|||
| Line 30: | Line 30: | ||
Problem064.java uses the ContinuedFractionBig class to solve the problem: https://charlesreid1.com:3000/cs/euler/src/master/scratch/Round2_050-070/064/Problem064.java | Problem064.java uses the ContinuedFractionBig class to solve the problem: https://charlesreid1.com:3000/cs/euler/src/master/scratch/Round2_050-070/064/Problem064.java | ||
===Magic Method for Square Roots=== | |||
In the process of implementing this, I needed to compute square roots to arbitrary precision - something that BigDecimal does NOT do! | |||
I found this (magical) arbitrary precision BigDecimal square root algorithm that is extremely handy: | |||
<pre> | |||
/** Find the square root of a BigDecimal to precision SCALE. */ | |||
public static BigDecimal sqrtBig(BigDecimal A, final int SCALE) { | |||
BigDecimal x0 = new BigDecimal("0"); | |||
BigDecimal x1 = new BigDecimal(Math.sqrt(A.doubleValue())); | |||
while (!x0.equals(x1)) { | |||
x0 = x1; | |||
x1 = A.divide(x0, SCALE, RoundingMode.HALF_UP); | |||
x1 = x1.add(x0); | |||
x1 = x1.divide(BigDecimal.valueOf(2), SCALE, RoundingMode.HALF_UP); | |||
} | |||
return x1; | |||
} | |||
</pre> | |||
==Flags== | ==Flags== | ||
{{ProjectEulerFlag}} | {{ProjectEulerFlag}} | ||
Revision as of 10:41, 8 January 2018
Problem Statement
More investigation of continued fractions and the continued fraction representation of square roots.
Link: https://projecteuler.net/problem=64
Blog post: Computing square roots using continued fractions: https://charlesreid1.com:3000/cs/euler/src/master/scratch/Round2_050-070/063/Problem063.java
Solution Technique
The blog post linked above contains some of the code used to solve this problem, but it basically boils down to implementing the recurrence relation formula that we already saw in Project Euler/57, with various initial conditions.
Continued fractions are implemented as a class. Key functionality includes:
- Check if integer is perfect square
- Solve the Pell equation
- Find the convergents P, Q of a continued fraction
- Find the (shorter than 10-long) continued fraction representation of an integer (uses normal float type)
- Find the (really long) continued fraction representation of an integer (uses arbitrary precision BigDecimal type)
$ \dfrac{P_n}{Q_n} = \dfrac{ a_n P_{n-1} + P_{n-2} }{ a_n Q_{n-1} + Q_{n-2} } $
Code
Link: https://charlesreid1.com:3000/cs/euler/src/master/scratch/Round2_050-070/064
ContinuedFractionBig.java defines the ContinuedFractionBig class: https://charlesreid1.com:3000/cs/euler/src/master/scratch/Round2_050-070/064/ContinuedFractionBig.java
Problem064.java uses the ContinuedFractionBig class to solve the problem: https://charlesreid1.com:3000/cs/euler/src/master/scratch/Round2_050-070/064/Problem064.java
Magic Method for Square Roots
In the process of implementing this, I needed to compute square roots to arbitrary precision - something that BigDecimal does NOT do!
I found this (magical) arbitrary precision BigDecimal square root algorithm that is extremely handy:
/** Find the square root of a BigDecimal to precision SCALE. */
public static BigDecimal sqrtBig(BigDecimal A, final int SCALE) {
BigDecimal x0 = new BigDecimal("0");
BigDecimal x1 = new BigDecimal(Math.sqrt(A.doubleValue()));
while (!x0.equals(x1)) {
x0 = x1;
x1 = A.divide(x0, SCALE, RoundingMode.HALF_UP);
x1 = x1.add(x0);
x1 = x1.divide(BigDecimal.valueOf(2), SCALE, RoundingMode.HALF_UP);
}
return x1;
}
Flags