--- 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:
x2 – Dy2 = 1
Por exemplo, quando D = 13, a solução mínima de x é 6492 - 13×1802 = 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:
32 – 2×22 = 1
22 – 3×12 = 1
92 – 5×42 = 1
52 – 6×22 = 1
82 – 7×32 = 1
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; } ```