130 lines
2.9 KiB
Markdown
130 lines
2.9 KiB
Markdown
---
|
||
id: 5900f3ae1000cf542c50fec1
|
||
title: 'Problema 66: Equação Diofantina'
|
||
challengeType: 5
|
||
forumTopicId: 302178
|
||
dashedName: problem-66-diophantine-equation
|
||
---
|
||
|
||
# --description--
|
||
|
||
Considere a fórmula da equação Diofantina:
|
||
|
||
<div style='text-align: center;'>x<sup>2</sup> – Dy<sup>2</sup> = 1</div>
|
||
|
||
Por exemplo, quando D = 13, a solução mínima de x é 649<sup>2</sup> - 13×180<sup>2</sup> = 1.
|
||
|
||
Podemos partir do princípio de que não há soluções para números inteiros positivos quando D é o resultado de um número elevado ao quadrado.
|
||
|
||
Ao encontrar soluções mínimas de x onde D = {2, 3, 5, 6, 7}, obtemos o seguinte:
|
||
|
||
<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>
|
||
|
||
Portanto, considerando soluções mínimas de `x` onde D ≤ 7, o maior `x` é obtido quando D = 5.
|
||
|
||
Calcule o valor de D ≤ `n` em soluções mínimas de `x` para as quais o maior valor de `x` é obtido.
|
||
|
||
# --hints--
|
||
|
||
`diophantineEquation(7)` deve retornar um número.
|
||
|
||
```js
|
||
assert(typeof diophantineEquation(7) === 'number');
|
||
```
|
||
|
||
`diophantineEquation(7)` deve retornar `5`.
|
||
|
||
```
|
||
assert.strictEqual(diophantineEquation(7), 5);
|
||
```
|
||
|
||
`diophantineEquation(100)` deve retornar `61`.
|
||
|
||
```
|
||
assert.strictEqual(diophantineEquation(100), 61);
|
||
```
|
||
|
||
`diophantineEquation(409)` deve retornar `409`.
|
||
|
||
```
|
||
assert.strictEqual(diophantineEquation(409), 409);
|
||
```
|
||
|
||
`diophantineEquation(500)` deve retornar `421`.
|
||
|
||
```
|
||
assert.strictEqual(diophantineEquation(500), 421);
|
||
```
|
||
|
||
`diophantineEquation(1000)` deve retornar `661`.
|
||
|
||
```js
|
||
assert.strictEqual(diophantineEquation(1000), 661);
|
||
```
|
||
|
||
# --seed--
|
||
|
||
## --seed-contents--
|
||
|
||
```js
|
||
function diophantineEquation(n) {
|
||
|
||
return true;
|
||
}
|
||
|
||
diophantineEquation(7);
|
||
```
|
||
|
||
# --solutions--
|
||
|
||
```js
|
||
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;
|
||
}
|
||
```
|