문제

주어진 숫자 중 3개의 수를 더했을 때 소수가 되는 경우의 개수를 구하려고 합니다. 숫자들이 들어있는 배열 nums가 매개변수로 주어질 때, nums에 있는 숫자들 중 서로 다른 3개를 골라 더했을 때 소수가 되는 경우의 개수를 return 하도록 solution 함수를 완성해주세요.

제한사항

nums에 들어있는 숫자의 개수는 3개 이상 50개 이하입니다.
nums의 각 원소는 1 이상 1,000 이하의 자연수이며, 중복된 숫자가 들어있지 않습니다.

일단 소수를 구하는 방법을 찾아보기... 전에,

소수란 무엇인가 생각해보자.
소수는, 자기 자신과 1을 제외하고는 나누어 떨어지지 않는 숫자를 의미한다.

그 말은 즉, 짝수는 2를 제외하고 모두 소수가 아니다.

3개를 합했을 때 짝수가 나오면 그냥 생각도 않고 제외하면 되겠다.

근데 말이죠...

짝수끼리 더하면 무조건 짝수가 나오잖아요?

그럼 짝수만 더하는 경우의 수는 그냥 배제해도 되지 않을까요?

네, 됩니다.

사실 그 뿐만 아니라 홀수 2개와 짝수 1개를 더해도 무조건 짝수가 나오죠.

아니 어떻게 그렇게 확신하냐고요?

짝수와 홀수의 정의를 잘 생각해 보면 확신할 수 있습니다.

짝수는 2로 나눠 떨어지는 수, 홀수는 그렇지 않은 수 입니다.

짝수를 2로 나누면? 나머지가 없습니다. 그것이... 짝수니까!
홀수를 2로 나누면? 나머지가 항상 1입니다. 그것이... 홀수니까...!

그러면 나머지가 항상 1인 것들을 더하면 어떻게 될까요?
나머지가 2가 되네요?

그럼? 2로 나누어 떨어지는 짝수가 된 것이네요?
어 그럼?

// 정리해 보면 이렇게 되겠다:
짝수 3= (짝수 + 짝수) + 짝수
= 짝수 + 짝수
= 짝수

짝수 2+ 홀수 1= (짝수 + 짝수) + 홀수
= 짝수 + 홀수
= 홀수

홀수 2+ 짝수 1= (홀수 + 홀수) + 짝수
= 짝수 + 짝수
= 짝수

홀수 3= (홀수 + 홀수) + 홀수
= 짝수 + 홀수
= 홀수

이렇게 되겠네요.

소수를 판별하는 법

가장 빠른 방법은 에라토스테네스의 체를 이용하는 거라네요.

그 왜 그 중학생때 수학시간에서 배웠던 1부터 100까지 숫자 적어놓고 하나씩 지우는거요.

근데 이건 귀찮아서 스택오버플로우에서 긁어왔읍니다...

extension Int {
    var isPrime: Bool {
        guard self >= 2     else { return false }
        guard self != 2     else { return true  }
        guard self % 2 != 0 else { return false }
        return !stride(from: 3, through: Int(sqrt(Double(self))), by: 2).contains { self % $0 == 0 }
    }
}

아이 깔끔해 아이좋아

출처 링크

코드

뭔가 급전개가 되는 것 같다면 그게 맞습니다.

forEach 함수랑 놀다가 현타가 와서 피곤하거든요.

풀긴 풀었는데 쏟은 시간이 굉장히 아쉽네요... 그냥 for-in문 썼으면 바로 풀었을 것을...
removeLast를 활용해보려다가 질질 끌렸습니다.
여튼 이렇게 풀었습니다.

import Foundation

func solution(_ nums:[Int]) -> Int {
    let evenNumbers: [Int] = nums.filter { $0 % 2 == 0 }
    let oddNumbers: [Int] = nums.filter { $0 % 2 != 0 }
    var result = 0
    
    // 홀수 3개
    for x in 0..<oddNumbers.count {
        for y in x + 1..<oddNumbers.count {
            for z in y + 1..<oddNumbers.count {
                let sum = oddNumbers[x] + oddNumbers[y] + oddNumbers[z]
                if sum.isPrime {
                    result += 1
                }
            }
        }
    }
    
    // 짝수 2개 + 홀수 1개
    for x in 0..<oddNumbers.count {
        for y in 0..<evenNumbers.count {
            for z in y + 1..<evenNumbers.count {
                let sum = oddNumbers[x] + evenNumbers[y] + evenNumbers[z]
                if sum.isPrime {
                    result += 1
                }
            }
        }
    }

    return result
}

extension Int {
    var isPrime: Bool {
        guard self >= 2     else { return false }
        guard self != 2     else { return true  }
        guard self % 2 != 0 else { return false }
        return !stride(from: 3, through: Int(sqrt(Double(self))), by: 2).contains { self % $0 == 0 }
    }
}

예압.

2개의 댓글

comment-user-thumbnail
2024년 11월 5일

ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ소.소.소.소수점.롬아. ㅋㅋㅋㅋㅋ

1개의 답글