freeCodeCamp/curriculum/challenges/portuguese/10-coding-interview-prep/project-euler/problem-75-singular-integer...

3.1 KiB

id title challengeType forumTopicId dashedName
5900f3b71000cf542c50feca Problema 75: Triângulos retângulos de lados inteiros e singulares 5 302188 problem-75-singular-integer-right-triangles

--description--

12 cm parece ser o menor comprimento de linha que pode ser determinado para formar um triângulo com ângulo reto inteiro exatamente de uma maneira, mas há muitos outros exemplos.

12 cm: (3,4,5)
24 cm: (6,8,10)
30 cm: (5,12,13)
36 cm: (9,12,15)
40 cm: (8,15,17)
48 cm: (12,16,20)

Por outro lado, alguns comprimentos de linha, como 20 cm, não podem ser dobrados de modo a formar um triângulo retângulo com lados inteiros singulares, enquanto outros comprimentos permitem que se encontre mais de uma solução. Por exemplo, usar 120 cm torna possível formar exatamente três triângulos retângulos com lados inteiros singulares.

120 cm: (30,40,50), (20,48,52), (24,45,51)

Considerando que L é o comprimento do fio, para quantos valores de L ≤ n é possível formar exatamente um triângulo retângulo de lados inteiros e singulares?

--hints--

singularIntRightTriangles(48) deve retornar um número.

assert(typeof singularIntRightTriangles(48) === 'number');

singularIntRightTriangles(48) deve retornar 6.

assert.strictEqual(singularIntRightTriangles(48), 6);

singularIntRightTriangles(700000) deve retornar 75783.

assert.strictEqual(singularIntRightTriangles(700000), 75783);

singularIntRightTriangles(1000000) deve retornar 107876.

assert.strictEqual(singularIntRightTriangles(1000000), 107876);

singularIntRightTriangles(1500000) deve retornar 161667.

assert.strictEqual(singularIntRightTriangles(1500000), 161667);

--seed--

--seed-contents--

function singularIntRightTriangles(n) {

  return true;
}

singularIntRightTriangles(48);

--solutions--

function singularIntRightTriangles(limit) {
  function euclidFormula(m, n) {
    return [m ** 2 - n ** 2, 2 * m * n, m ** 2 + n ** 2];
  }

  function gcd(numberA, numberB) {
    if (numberB === 0) {
      return numberA;
    }
    return gcd(numberB, numberA % numberB);
  }

  function notBothOdd(numberA, numberB) {
    return (numberA + numberB) % 2 === 1;
  }

  function areCoprime(numberA, numberB) {
    return gcd(numberA, numberB) === 1;
  }

  const trianglesWithPerimeter = new Array(limit + 1).fill(0);
  const mLimit = Math.sqrt(limit / 2);

  for (let m = 2; m < mLimit; m++) {
    for (let n = 1; n < m; n++) {
      if (notBothOdd(m, n) && areCoprime(m, n)) {
        const [sideA, sideB, sideC] = euclidFormula(m, n);
        const perimeter = sideA + sideB + sideC;
        let curPerimeter = perimeter;
        while (curPerimeter <= limit) {
          trianglesWithPerimeter[curPerimeter]++;
          curPerimeter += perimeter;
        }
      }
    }
  }
  return trianglesWithPerimeter.filter(trianglesCount => trianglesCount === 1)
    .length;
}