| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | --- | 
					
						
							|  |  |  |  | id: 5900f3ae1000cf542c50fec1 | 
					
						
							|  |  |  |  | title: 'Problem 66: Diophantine equation' | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | challengeType: 5 | 
					
						
							| 
									
										
										
										
											2019-08-05 09:17:33 -07:00
										 |  |  |  | forumTopicId: 302178 | 
					
						
							| 
									
										
										
										
											2021-01-13 03:31:00 +01:00
										 |  |  |  | dashedName: problem-66-diophantine-equation | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | --- | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | # --description--
 | 
					
						
							| 
									
										
										
										
											2020-02-28 21:39:47 +09:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | Consider quadratic Diophantine equations of the form: | 
					
						
							| 
									
										
										
										
											2020-02-28 21:39:47 +09:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | <div style='text-align: center;'>x<sup>2</sup> – Dy<sup>2</sup> = 1</div> | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | For example, when D=13, the minimal solution in x is 649<sup>2</sup> – 13×180<sup>2</sup> = 1. | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | It can be assumed that there are no solutions in positive integers when D is square. | 
					
						
							| 
									
										
										
										
											2020-02-28 21:39:47 +09:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | By finding minimal solutions in x for D = {2, 3, 5, 6, 7}, we obtain the following: | 
					
						
							| 
									
										
										
										
											2020-02-28 21:39:47 +09:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | <div style='margin-left: 2em;'> | 
					
						
							|  |  |  |  |   3<sup>2</sup> – 2×2<sup>2</sup> = 1<br> | 
					
						
							|  |  |  |  |   2<sup>2</sup> – 3×1<sup>2</sup> = 1<br> | 
					
						
							|  |  |  |  |   <strong><span style='color: red;'>9</span></strong><sup>2</sup> – 5×4<sup>2</sup> = 1<br> | 
					
						
							|  |  |  |  |   5<sup>2</sup> – 6×2<sup>2</sup> = 1<br> | 
					
						
							|  |  |  |  |   8<sup>2</sup> – 7×3<sup>2</sup> = 1<br> | 
					
						
							|  |  |  |  | </div> | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | Hence, by considering minimal solutions in `x` for D ≤ 7, the largest `x` is obtained when D=5. | 
					
						
							| 
									
										
										
										
											2020-02-28 21:39:47 +09:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | Find the value of D ≤ `n` in minimal solutions of `x` for which the largest value of `x` is obtained. | 
					
						
							| 
									
										
										
										
											2020-02-28 21:39:47 +09:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | # --hints--
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | `diophantineEquation(7)` should return a number. | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | assert(typeof diophantineEquation(7) === 'number'); | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | ``` | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | `diophantineEquation(7)` should return `5`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | assert.strictEqual(diophantineEquation(7), 5); | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | `diophantineEquation(100)` should return `61`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | assert.strictEqual(diophantineEquation(100), 61); | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | `diophantineEquation(409)` should return `409`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | assert.strictEqual(diophantineEquation(409), 409); | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | `diophantineEquation(500)` should return `421`. | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | assert.strictEqual(diophantineEquation(500), 421); | 
					
						
							|  |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | `diophantineEquation(1000)` should return `661`. | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | assert.strictEqual(diophantineEquation(1000), 661); | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | # --seed--
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | ## --seed-contents--
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | function diophantineEquation(n) { | 
					
						
							| 
									
										
										
										
											2020-09-15 09:57:40 -07:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  |   return true; | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | diophantineEquation(7); | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | ``` | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |  | # --solutions--
 | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | 
 | 
					
						
							|  |  |  |  | ```js | 
					
						
							| 
									
										
										
										
											2021-05-05 09:54:49 +02:00
										 |  |  |  | function diophantineEquation(n) { | 
					
						
							|  |  |  |  |   // Based on https://www.mathblog.dk/project-euler-66-diophantine-equation/ | 
					
						
							|  |  |  |  |   function isSolution(D, numerator, denominator) { | 
					
						
							|  |  |  |  |     return numerator * numerator - BigInt(D) * denominator * denominator === 1n; | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   let result = 0; | 
					
						
							|  |  |  |  |   let biggestX = 0; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |   for (let D = 2; D <= n; D++) { | 
					
						
							|  |  |  |  |     let boundary = Math.floor(Math.sqrt(D)); | 
					
						
							|  |  |  |  |     if (boundary ** 2 === D) { | 
					
						
							|  |  |  |  |       continue; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     let m = 0n; | 
					
						
							|  |  |  |  |     let d = 1n; | 
					
						
							|  |  |  |  |     let a = BigInt(boundary); | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     let [numerator, prevNumerator] = [a, 1n]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     let [denominator, prevDenominator] = [1n, 0n]; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     while (!isSolution(D, numerator, denominator)) { | 
					
						
							|  |  |  |  |       m = d * a - m; | 
					
						
							|  |  |  |  |       d = (BigInt(D) - m * m) / d; | 
					
						
							|  |  |  |  |       a = (BigInt(boundary) + m) / d; | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |       [numerator, prevNumerator] = [a * numerator + prevNumerator, numerator]; | 
					
						
							|  |  |  |  |       [denominator, prevDenominator] = [ | 
					
						
							|  |  |  |  |         a * denominator + prevDenominator, | 
					
						
							|  |  |  |  |         denominator | 
					
						
							|  |  |  |  |       ]; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  |     if (numerator > biggestX) { | 
					
						
							|  |  |  |  |       biggestX = numerator; | 
					
						
							|  |  |  |  |       result = D; | 
					
						
							|  |  |  |  |     } | 
					
						
							|  |  |  |  |   } | 
					
						
							|  |  |  |  |   return result; | 
					
						
							|  |  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-09-30 23:01:58 +01:00
										 |  |  |  | ``` |