0218

개발

[백준] 4153번 - 직각삼각형

문제 링크 : https://www.acmicpc.net/problem/4153

문제 탐색하기

1) 문제 분석

  • 한 줄에 삼각형 세 변이 주어진다.

  • 마지막 입력은 0 0 0 을 입력한다.

  • 직각 삼각형이 맞다면 'right', 아니라면 'wrong'을 출력한다.

2) 가능한 시간복잡도

(1) 입력 처리

  • 전체 입력을 한 번에 받아서 N줄로 나눔 → O(N)

  • 각 줄마다 반복 처리 → O(N)

(2) 한 줄 처리

  • 공백 기준 split → O(1) (길이 3 고정)

  • Number 변환 → O(1)

  • sort() 정렬 → O(1) (정렬 대상 길이 3)

  • 조건 비교 및 출력 → O(1)

(4) 전체 시간 복잡도

  • 각 줄마다 O(1) 작업을 N번 반복하므로 → O(N)

3) 알고리즘 선택 이유

  • 이 문제는 세 수 중 가장 큰 값을 기준으로 피타고라스 정리를 판단하는 단순한 조건 비교 문제이다.

  • 세 수만 정렬하면 조건 검사가 쉬워지며, 입력도 고정 길이라 연산 비용이 매우 낮다.-> 따라서, 정렬 후 수학적 조건을 판단하는 방식이 직관적이고 효율적이다.

코드 설계하기

1. 실행 구조

1) 숫자를 입력 받는다.

2) 입력된 행 수만큼 반복하고, 공백을 기준으로 분리한다.

3) 분리된 각 값을 정수형으로 변환한다.

4) 변환된 각 행의 배열을 오름차순으로 정렬한다.

5) 결과값을 출력한다.

2. 고민이 되었던 부분

1) 처음에 작성한 코드

JavaScript
const fs = require('fs');

// 입력을 한 줄씩 받아와 문자열 배열로 변환
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

for (let i = 0; i < input.length; i++){
    let separatedArr = input[i].toString().trim().split(' ');
    let numArr = [];
    for (let j = 0; j < separatedArr.length; j++){
        numArr.push(Number(seperateArr[j]));
    }
    numArr.sort((a, b) => a - b);

    if (numArr[0] === 0 && numArr[1] === 0 && numArr[2] === 0) {
        process.exit();
    }
    else if (numArr[0] * numArr[0] + numArr[1] * numArr[1] === numArr[2] * numArr[2]) {
        console.log('right');
    } else {
        console.log('wrong');
    }
}

(1) input[i].toString의 불필요
: input 자체가 이미 문자열 배열이기에, 중복된 변환을 할 필요가 없다.

(2) Number 변환은 map으로 간결하게

: 현재 for문으로 직접 변환 후 push하는 과정은 map(Number)로 간단하게 처리 가능하다.

(3) 종료 조건 확인을 먼저 진행

: 정렬 전에 0 0 0 조건을 먼저 체크하면, 정렬 연산을 하지 않아도 된다.

정답 코드

JavaScript
// 사용 언어 : Javascript

const fs = require('fs');

// 입력을 한 줄씩 받아와 문자열 배열로 변환 (각 줄: "3 4 5" 같은 형식)
const input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');

// 각 줄에 대해 반복 처리
for (let i = 0; i < input.length; i++) {
    // 공백 기준으로 분리하고 숫자(Number)로 변환 → [a, b, c]
    let separatedArr = input[i].trim().split(' ').map(Number); 
    
    // 구조 분해 할당으로 세 수를 각각 변수에 저장
    const [a, b, c] = separatedArr;

    // 종료 조건: 세 수가 모두 0이면 반복 종료
    if (a === 0 && b === 0 && c === 0) break;
    
    // 오름차순 정렬하여 가장 큰 값을 마지막에 위치시킴
    const sorted = [a, b, c].sort((x, y) => x - y);
    const [x, y, z] = sorted; // 가장 큰 수 z를 빼고 피타고라스 판별 준비

    // 피타고라스 정리: x² + y² == z² 이면 직각삼각형
    console.log(x * x + y * y === z * z ? 'right' : 'wrong');
}

마무리하며

오랜만에 수학 공식을 접할 수 있던 순간이었다. 문제 자체는 쉽고 간단했지만, 그 안에서 최적화를 하기 위한 방법에 대해서 고민해볼 수 있던 점이 인상 깊은 문제였다. javascript의 장점 중 하나인 구조 분해 할당을 사용하면 더욱 효율적이고 간결하게 코드를 작성할 수 있다는 사실을 다시금 느낄 수 있었다. 또한, 삼항 연산자를 더욱 잘 사용해야겠다는 생각도 들었다. 아직은 readFileSync의 전체 문장을 작성하는 것에 미숙하여 copay & post를 하고 있는데, 이 부분에 대해서도 최대한 손으로 적어보려고 하는 연습을 해야겠다.