본문 바로가기
개발/Coding Test

[프로그래머스 LV2] 두 원 사이의 정수 쌍 - Java, Kotlin, Python, Go

by dwony26 2023. 4. 16.
반응형

https://school.programmers.co.kr/learn/courses/30/lessons/181187

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

반지름을 나타내는 두 정수 r1, r2가 주어질 때, 두 원 사이의 공간에 x좌표와 y좌표가 모두 정수인 점의 개수를 구하는 문제입니다.

모든 좌표를 탐색할 필요 없이 1사분면에서 해당하는 점의 개수를 구한 후 X 4를 하면 전체 개수를 구할 수 있습니다.

1사분면의 점의 개수는 피타고라스 정리를 이용하여 x가 1, 2, ..., r2일 때 r1, r2의 y 좌표를 구한 뒤 두 좌표 사이에 있는 값을 세어 주면 됩니다.

x = 0일 때 또는 y = 0일 때 중 하나를 선택하여 포함시켜야 하는데 y = 0일 때를 포함시키는 것이 더 간단합니다.

 

 

Java

import java.util.stream.IntStream;

class Solution {
    public long solution(int r1, int r2) {
        return IntStream.range(1, r2 + 1).mapToLong(x -> {
            long inner = (long) Math.ceil(Math.sqrt(Math.pow(r1, 2) - Math.pow(x, 2)));
            long outer = (long) Math.floor(Math.sqrt(Math.pow(r2, 2) - Math.pow(x, 2)));
            return outer - inner + 1;
        }).sum() * 4;
    }
}

IntStream을 이용하여 구해줍니다.

Math.sqrt 함수에 음수 값이 들어가면 NaN이 리턴되는데 long으로 변환하는 과정에서 0이 되므로 따로 처리를 하지 않아도 됩니다.

 

Kotlin

import kotlin.math.*

class Solution {
    fun solution(r1: Int, r2: Int): Long {
        return (1 .. r2).sumOf { 
            val inner = ceil(sqrt((r1.toDouble().pow(2) - it.toDouble().pow(2)))).toLong()
            val outer = floor(sqrt((r2.toDouble().pow(2) - it.toDouble().pow(2)))).toLong()
            outer - inner + 1
        } * 4
    }
}

Java와 유사합니다.

 

Python

import math

def solution(r1, r2):
    answer = 0
    for x in range(1, r2 + 1):
        inner = math.ceil(math.sqrt(pow(r1, 2) - pow(x, 2))) if r1 > x else 0
        outer = math.floor(math.sqrt(r2 ** 2 - x ** 2))
        answer += outer - inner + 1
    return answer * 4

python에서는 math.sqrt함수에 음수 값이 들어가면 오류가 발생하므로 예외 조건을 추가하였습니다.

 

Go

import "math"

func solution(r1 int, r2 int) int64 {
	answer := int64(0)
	for x := 1; x <= r2; x++ {
		inner := int64(0)
		if r1 > x {
			inner = int64(math.Ceil(math.Sqrt(math.Pow(float64(r1), 2) - math.Pow(float64(x), 2))))
		}
		outer := int64(math.Floor(math.Sqrt(math.Pow(float64(r2), 2) - math.Pow(float64(x), 2))))
		answer += outer - inner + 1
	}
	return answer * 4
}

Go에서는 예외 조건을 추가하지 않아도 테스트는 통과하는데, 값을 찍어보면 -9223372036854775766와 같은 값이 나옵니다.

ChatGPT에 물어보니 처음에는 int로 변환하면 0이 된다고 했는데, 다시 물어보니 1.13버전 이후로는 예측할 수 없는 값이 될 수 있다고 합니다.

반응형

댓글