Files
freeCodeCamp/curriculum/challenges/ukrainian/10-coding-interview-prep/project-euler/problem-75-singular-integer-right-triangles.md

3.7 KiB
Raw Permalink Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5900f3b71000cf542c50feca Завдання 75: Одиничні цілочисельні прямокутні трикутники 5 302188 problem-75-singular-integer-right-triangles

--description--

Виявилось, що 12 см — це найменша довжина проводу, який можна зігнути так, щоб сформувати прямокутний трикутник лише одним способом, проте існує набагато більше прикладів.

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

На противагу, дріт певної довжини, наприклад, 20 см, не можна зігнути так, щоб сформувати цілий прямокутний трикутник; у той час як інша довжина дроту дозволяє зробити це більш, ніж в один спосіб. Наприклад, при використанні 120 см можливо сформувати рівно три різних правильних прямокутних трикутники.

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

Враховуючи, що L — це довжина дроту, то для скількох значень L ≤ n може бути сформований лише один, цілочисельний прямокутний трикутник?

--hints--

singularIntRightTriangles(48) повинен повертатися як число.

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

singularIntRightTriangles(48) повинен повертатися як 6.

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

singularIntRightTriangles(700000) повинен повертатися як 75783.

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

singularIntRightTriangles(1000000) повинен повертатися як 107876.

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

singularIntRightTriangles(1500000) повинен повертатися як 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;
}