설계
약수 개수를 구할 수만 있다면, 스무스하게 풀릴거 같습니다.
소수 개수 판단법 확인했을 때, number의 제곱근만큼 확인했던 기억을 살려 활용해보자.
git : 기사단원의 무기
문제 : https://school.programmers.co.kr/learn/courses/30/lessons/136798
문제 풀이
numbers 를 순회하여 index + 1의 약수의 개수를 넣어주기
약수 개수 반환 알고리즘은 number의 제곱근만큼 반복하여 나눠줘서 나머지가 없는 경우 카운팅을 해주는데, 예를들어 16의 약수 개수를 카운팅한다고 했을때, 2 * 8 은 두 개로 카운팅되지만, 4 * 4는 하나로 카운팅해야하므로, 나눈 값과 몫을 확인해야한다!
약수 개수가 채워진 numbers를 limit 이하 만큼 필터해준 뒤, 그 합과 리밋이 넘어버린 기사의 수 * 제공되는 무기의 공격력으로 원하는 값을 반환 할 수 있다.
import Foundation
// 약수의 수가 공격력
// limit 제한
// power : 초과한 기사들의 무기 공격력
func solution(_ number:Int, _ limit:Int, _ power:Int) -> Int {
var numbers = Array.init(repeating: 0, count: number)
numbers.indices.forEach{ index in
numbers[index] = getCountOfDivisor(index + 1)
}
//print(numbers)
let numbersCount = numbers.count
let filteredNumbers = numbers.filter { item in
return item <= limit
}
let sum = filteredNumbers.reduce(0, +) + (( numbersCount - filteredNumbers.count ) * power )
return sum
}
func getCountOfDivisor(_ number: Int) -> Int {
var count = 0
let range = 1...Int(sqrt(Double(number)))
for index in range {
if(number % index == 0) {
if(index == number / index) {
count += 1
}
else {
count += 2
}
}
}
return count
}
다른 사람 풀이 분석
프로그래머스 - LEEHAKJIN-VV 님
import Foundation
func solution(_ number:Int, _ limit:Int, _ power:Int) -> Int {
var steelCount: Int = 0
(1...number).map{ knight in
let count = divisorCount(knight)
steelCount += (count > limit) ? power : count
}
return steelCount
}
func divisorCount(_ num: Int) -> Int {
var count: Int = 0
for n in 1...Int(sqrt(Double(num))) {
if num % n == 0 {
count += 2
if n * n == num {
count -= 1
}
}
}
return count
}
풀이의 메커니즘은 동일하지만, 배열을 만들어주지 않고 range와 map을 활용한 방법입니다.
정리
약수 개수를 구할 때 ! 몫과 나눈 값 같을 때 카운팅 유의!
'알고리즘 & 문제풀이' 카테고리의 다른 글
프로그래머스 - L2 피보나치 수 (0) | 2023.02.17 |
---|---|
프로그래머스 - L2 최댓값과 최솟값 (0) | 2023.02.15 |
프로그래머스 - L1 숫자 짝꿍 (0) | 2023.02.14 |
Queue- 자료구조 (0) | 2023.02.06 |
프로그래머스 - L1 소수 찾기 (0) | 2023.02.06 |