프로그래밍/코딩테스트
[프로그래머스] 소수 찾기 (순열) / Swift
turu
2021. 5. 21. 00:07
https://programmers.co.kr/learn/courses/30/lessons/42839
코딩테스트 연습 - 소수 찾기
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다. 각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이
programmers.co.kr
[문제 보기]
더보기
한자리 숫자가 적힌 종이 조각이 흩어져있습니다. 흩어진 종이 조각을 붙여 소수를 몇 개 만들 수 있는지 알아내려 합니다.
각 종이 조각에 적힌 숫자가 적힌 문자열 numbers가 주어졌을 때, 종이 조각으로 만들 수 있는 소수가 몇 개인지 return 하도록 solution 함수를 완성해주세요.
제한사항
- numbers는 길이 1 이상 7 이하인 문자열입니다.
- numbers는 0~9까지 숫자만으로 이루어져 있습니다.
- "013"은 0, 1, 3 숫자가 적힌 종이 조각이 흩어져있다는 의미입니다.
입출력 예
numbers, return"17" | 3 |
"011" | 2 |
입출력 예 설명
예제 #1
[1, 7]으로는 소수 [7, 17, 71]를 만들 수 있습니다.
예제 #2
[0, 1, 1]으로는 소수 [11, 101]를 만들 수 있습니다.
- 11과 011은 같은 숫자로 취급합니다.
풀이 과정
소수 찾기 + 순열 문제였다.
입력받은 문자열을 각 숫자들의 배열로 분리하고 그 배열로 (1...분리된 배열의 길이)갯수를 뽑는 순열을 반복해서 구했다.
각 r개씩 뽑는 순열은 재귀 DFS 탐색으로 구했다.
// 내 풀이
import Foundation
var numberArr = [Int]()
var generatedNumber = Set<Int>()
var result = [Int]()
var checkList = [Bool]()
func convArrToNum(_ arr: [Int]) -> Int {
return arr.reduce(0) { $0 * 10 + $1 }
}
func isPrimeNumber(_ n: Int) -> Bool {
guard n > 1 else { return false }
let last = Int(sqrt(Double(n)))
var count = 0
var flag = true
for i in (1...last) {
if n % i == 0 {
count += 1
if count > 1 {
flag = false
break
}
}
}
return flag
}
func permuDFS(phase: Int, r: Int) {
if phase == r {
let num = convArrToNum(result)
generatedNumber.insert(num)
return
} else {
for i in (0..<numberArr.count) {
if checkList[i] == false {
result[phase] = numberArr[i]
checkList[i] = true
permuDFS(phase: phase + 1, r: r)
checkList[i] = false
}
}
}
}
func solution(_ numbers:String) -> Int {
numberArr = numbers.map { Int(String($0))! }
// generatedNumber Set을 완성시킨다
for i in (1...numberArr.count) {
result = [Int](repeating: 0, count: i)
checkList = [Bool](repeating: false, count: numberArr.count)
permuDFS(phase: 0, r: i)
}
// generatedNumber Set에서 소수의 갯수를 구한다
var count = 0
for element in generatedNumber {
if isPrimeNumber(element) {
count += 1
}
}
return count
}
// "17" -> [7, 17, 71] -> 3개
// "011" -> [11, 101] -> 2개
let numbers = "011" // 1, 17, 71 == 3
let sr = solution(numbers)
print(sr)
다른 사람 풀이
재귀 DFS를 swift 문법에 맞춰서 구한 것 같다. 그리고 solution 함수에서 Set<String>에서 각 String형 원소들을 Int형으로 변환할 때 나오는 옵셔널이 나오는 부분을 compactMap을 사용해서 해소한 부분이 눈에 띄었다(nil제거, 옵셔널 바인딩).
// 다른 사람 풀이
import Foundation
func combinations(_ array: [String]) -> Set<String> {
if array.count == 0 { return [] }
let answerArray = (0..<array.count).flatMap { i -> [String] in
var removedArray = array
let elem = removedArray.remove(at: i)
return [elem] + combinations(removedArray).map { elem + $0 }
}
return Set(answerArray)
}
func isPrime(_ number: Int) -> Bool {
guard number > 1 else {
return false
}
for i in 2..<number {
if number % i == 0 { return false }
}
return true
}
func solution(_ numbers: String) -> Int {
let array = Array(numbers).map{ String($0) }
let intSet = Set(combinations(array).compactMap { Int($0) })
return intSet.filter{ isPrime($0) }.count
}
반응형