TIL/알고리즘 공부
프로그래머스 Lv. 2 Swift 알고리즘 - 소수 찾기
여의도사노비
2023. 1. 24. 17:09
728x90
소수 찾기도 해보고 순열도 풀어봤는데... 이 문제는 요상하게 안풀리더라..!
그래서 마지막 설 연휴인만큼 내 자신과 조금 타협해서 타 블로그 분의 풀이를 참고하였다 ^^
참고한 분의 코드가 정말 상당히 나의 머릿속 논리와 흐름이 같아서 모범답안 같은 느낌으로 가져가고자한다 :)
(참고: https://jeong9216.tistory.com/358)
이 문제를 풀면서 생각한 논리적 흐름
- 완전탐색 문제인 만큼 모든 경우의 수를 다 고려해야한다.
- 먼저 주어진 numbers를 String으로 변환한 뒤 순열 방식을 사용하여 나올 수 있는 조합의 경우의 수를 전부 numSet에 insert해준다. (중복값을 제거하기 위한 Set)
- 순열 방식을 이용하기 위해서 재귀식을 사용하는데 numbers에 있는 값들 중 사용을 했는지 안했는지를 확인하기 위해 visited를 이용한 bool 타입을 이용한다.
- 이미 사용했으면 true로 바꾼뒤 다시 재귀식을 돌려서 계속 False, False, False, False 인 배열을 T, F, F, F / T, T, F, F ... 이런 식으로 원하는 위치의 값을 경우의 수로 셀 수 있도록 누적해준다.
- 그렇게 numSet에 누적된 값들을 filter에서 isPrime 메서드를 적용하여 소수인 값들만 count해준다.
* 코드
import Foundation
func solution(_ numbers:String) -> Int {
let nums: [String] = numbers.map { String($0) }
var visited: [Bool] = []
var numSet: Set<Int> = []
for i in 1...nums.count {
visited = Array(repeating: false, count: nums.count)
permutation([], count: 0, rCount: i)
}
func permutation(_ numArr: [String], count: Int, rCount: Int) {
if count == rCount {
numSet.insert(Int(numArr.joined())!)
return
}
for (i, n) in nums.enumerated() {
if visited[i] {
continue
}
var newNumArr = numArr
newNumArr.append(n)
visited[i] = true
permutation(newNumArr, count: count+1, rCount: rCount)
visited[i] = false
}
}
return numSet.filter { isPrime($0) }.count
}
func isPrime(_ num: Int) -> Bool {
if num < 4 {
return (num <= 1) ? false : true
} else {
for i in 2...Int(sqrt(Double(num))) {
if num % i == 0 {
return false
}
}
}
return true
}
정리(Today I Learned)
1. 재귀가 진짜 헷갈리는 것 같다... 직접 하나하나 예시를 돌려보지 않으면 머리속에서 잘 그려지지가 않는다... 무조건 직접 손으로 재귀를 돌려보는 것이 좋은 것 같다.