코딩테스트 연습

프로그래머스 - 두 원 사이의 정수 쌍

gurwhddl 2023. 4. 17. 21:53

문제

x축과 y축으로 이루어진 2차원 직교 좌표계에 중심이 원점인 서로 다른 크기의 원이 두 개 주어집니다. 반지름을 나타내는 두 정수 r1, r2가 매개변수로 주어질 때, 두 원 사이의 공간에 x좌표와 y좌표가 모두 정수인 점의 개수를 return하도록 solution 함수를 완성해주세요.
※ 각 원 위의 점도 포함하여 셉니다.

풀이

예시img

두 원 사이에 있는 정수 좌표는 x좌표 0일때 y좌표 가능한거 몇개 - 1일때 몇개 ~ r2일 때 몇개인지 구하면 됨


그렇다면 두 원 사이에 있는지를 판단하려면 ? x좌표가 n일때 반지름이 r1인 원에서의 y값을 알아내면 됨


원 넓이 공식 - x^2 + y^2 = r^2 (원 중심이 (0,0)일때만)을 이용해서 반복문으로 x값을 0부터 r2까지 설정해놓고 r1^2 - x좌표^2보다 크고, r2^2 - x좌표^2보다 작은 값이 y좌표가 됨(각각 제곱이기 때문에 루트 씌워줘야함)


계산해보면 1.74....<y<2.46363.... 같은 값이 나오는데, 이 사이의 정수 x는 몇개 있는지는 어떻게 구할까 생각해보면 어차피 정수만 구하면 되기 때문에 달리 생각해보면 y는 2부터 가능하고, 2까지만 가능하다는 소리가 됨 => 앞의 수는 소수점 올림, 뒤는 버림해줘서 뒤-앞+1이 사이의 정수의 수


여기까진 좋았으나... x좌표 값이 작은 원인 r1값보다 커지게 되면 ? Math.sqrt가 계산을 못해주기 때문에 오류가 발생함


그럼 어떻게 해야되나? 어차피 x좌표가 작은 원을 반지름 값보다 커지게 되면 어차피 y값은 0부터 시작 가능하기 때문에(당연한거임) 예외처리해줌


좌표평면이기 때문에 한쪽값 * 4 해주면 되지만 , x나 y좌표가 0일 때는 곱해버리면 겹치는 경우가 발생함


-그래서 애초에 0인 경우는 계산 안하고, 어차피 x좌표가 0인 겹치는 값은 r2-r1+1이고 여기에 4 곱해줌

코드

function solution(r1, r2) {
    const square1 = r1 ** 2
    const square2 = r2 ** 2
    let sum = 0
    for(let x=1;x<r2;x++){
        let min = square1 - x**2 <= 0 ? 1 : Math.ceil((square1 - x**2) ** 0.5)
        let max = parseInt(Math.sqrt(square2 - x**2))
        sum += max-min+1
    }
        sum*= 4
        sum += (r2-r1+1) * 4
        return sum
    }

그렇게 어렵진 않았는데 은근 시간 오래걸림