Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

자바스크립트로 주어진 둘레를 만족하는 모든 직각삼각형 찾기

문제 이해하기

하나의 숫자를 인수로 받는 자바스크립트 함수를 작성해야 합니다. 이 숫자는 삼각형의 둘레, 즉 세 변 길이의 합을 의미합니다. 함수는 입력된 둘레와 정확히 일치하는 모든 직각삼각형의 세 변 조합을 배열 형태로 반환해야 합니다.

예를 들어 둘레가 120이라면, 세 변의 합이 120이면서 동시에 피타고라스 정리를 만족하는 모든 (a, b, c) 조합을 찾아야 합니다.

접근 방법

직각삼각형의 세 변 a, b, c(단, c는 빗변)는 다음 두 조건을 동시에 만족해야 합니다.

  • 둘레 조건: a + b + c = perimeter
  • 피타고라스 정리: a² + b² = c²

세 개의 중첩 반복문으로 모든 조합을 무차별 대입할 수도 있지만, 아래와 같이 탐색 범위를 좁히면 성능을 크게 개선할 수 있습니다.

  • 가장 짧은 변 a는 항상 둘레의 1/3보다 작거나 같습니다. (a ≤ perimeter / 3)
  • 두 번째 변 b는 a보다 커야 하며, 남은 길이의 절반을 넘지 않습니다. (b ≤ (perimeter − a) / 2)
  • 빗변 c는 반복문으로 찾을 필요 없이 c = perimeter − a − b로 바로 계산할 수 있습니다.

이렇게 하면 시간 복잡도가 O(n³)에서 O(n²)으로 줄어들어, 둘레가 클 때도 빠르게 결과를 얻을 수 있습니다.

예제 코드

const perimeter = 120;

const findAllRightTriangles = (perimeter = 1) => {
  const res = [];
  // 가장 짧은 변 a는 둘레의 1/3을 넘을 수 없습니다.
  for(let a = 1; a <= perimeter / 3; a++){
    // 두 번째 변 b는 a보다 커야 하며, 남은 길이의 절반을 넘지 않습니다.
    for(let b = a + 1; b <= (perimeter - a) / 2; b++){
      // 빗변 c는 둘레에서 a와 b를 빼서 바로 구합니다.
      const c = perimeter - a - b;
      // 피타고라스 정리를 만족하면 직각삼각형입니다.
      if(a * a + b * b === c * c){
        res.push([a, b, c]);
      }
    }
  }
  return res;
};

console.log(findAllRightTriangles(perimeter));

출력 결과

[ [ 20, 48, 52 ], [ 24, 45, 51 ], [ 30, 40, 50 ] ]

코드 설명 및 검증

출력된 세 조합을 직접 검증해 보면 다음과 같습니다.

  • (20, 48, 52): 20 + 48 + 52 = 120, 20² + 48² = 400 + 2304 = 2704 = 52² ✓
  • (24, 45, 51): 24 + 45 + 51 = 120, 24² + 45² = 576 + 2025 = 2601 = 51² ✓
  • (30, 40, 50): 30 + 40 + 50 = 120, 30² + 40² = 900 + 1600 = 2500 = 50² ✓

모든 조합이 둘레 120과 피타고라스 정리를 동시에 만족하므로 올바른 직각삼각형입니다.

주의할 점: 변의 관계를 단순히 a + b = c로 판정하면 안 됩니다. a + b = c를 만족하는 세 변은 세 꼭짓점이 한 직선 위에 놓이는 퇴화(degenerate) 삼각형일 뿐, 실제 직각삼각형이 아닙니다. 반드시 각 변을 제곱하여 비교하는 피타고라스 정리 검증을 사용해야 정확한 결과를 얻을 수 있습니다.