본문 바로가기
코딩테스트 연습

구슬을 나누는 경우의 수

by 신재은👩🏼‍💻 2024. 5. 5.

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

 

프로그래머스

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

programmers.co.kr

 

팩토리얼!

 

내가 처음에 제출했던 코드를 보자.

class Solution {
    public int solution(int balls, int share) {
        // balls! / ((balls-share)! * share!)
        return factorial(balls) / (factorial(balls-share) * factorial(share));
    }
    
    int factorial(int n) {
        if(n>=2) {
            return n * factorial(n-1);
        }
        return 1;
    }
}

 

코드 상으로는 문제 될 게 없다고 생각했는데 정확도가 42.9/100...

이 건에 대해서는 도저히 알 수가 없어서 GPT한테 물었다.

일단 문제가 될 수 있는 건 '오버플로우'.

그래서 아래처럼 수정했더니 아무 오류도 나지 않았다.

import java.math.BigInteger;

class Solution {
    public int solution(int balls, int share) {
        // balls! / ((balls-share)! * share!)
        BigInteger result = factorial(balls)
            .divide(factorial(balls-share)
            .multiply(factorial(share)));
        return result.intValue();
    }
    
    BigInteger factorial(int n) {
        BigInteger result = BigInteger.ONE;
        for(int i=2; i<=n; i++) {
            result = result.multiply(BigInteger.valueOf(i));
        }
        return result;
    }
}

 

리턴값이나 변수에 다 BigInteger를 적용했다.

팩토리얼 함수는 그냥 for문 돌리는 걸로 고쳤다.

 

오버플로우 날 확률을 줄이기 위해 식을 나눗셈을 먼저 하는 걸로 진행해야 하느냐 곱셈을 먼저 하는 걸로 진행해야 하느냐 GPT한테 물었는데

그때 그때마다 뱉는 답변이 다르다.

우선, / / 하나 * 먼저 하고 / 하나 속도에는 별 차이가 없다.

그 외 내부적으로는 어딘가에서 중간 결과가 데이터 타입의 범위를 초과하는 일이 생기겠지만

내가 그 지점까지는 그릴 수가 없어서...

그래서 우선은 팩토리얼 할 때 오버플로우 조심하자 정도가 이번 문제에서 얻은 교훈이 되겠다.

그리고 빅인티저 잘 쓰자.

 

주의할 것:

  1. 정수 오버플로우: int 형으로 팩토리얼 값을 계산하면 빠르게 정수 범위를 초과할 수 있습니다. 예를 들어, 13! 이상부터는 int 범위를 넘어서며, long 타입을 사용해도 20! 이상에서는 범위를 초과합니다.
  2. 해결: 팩토리얼을 계산하는 부분을 BigInteger를 사용하여 다시 작성할 수 있습니다. BigInteger는 아주 큰 정수를 다룰 수 있는 클래스로, 사실상 무제한의 크기를 지원합니다.

이런 문제에서는 걍 애초부터 맘 편하게 빅인티저 쓸 것.

'코딩테스트 연습' 카테고리의 다른 글

최대공약수와 최소공배수  (0) 2024.05.06
같은 숫자는 싫어  (0) 2024.05.06
영어가 싫어요  (0) 2024.05.05
공 던지기  (0) 2024.05.05
문자열 다루기 기본  (0) 2024.05.05