[Swift][프로그래머스] 약수의 합

팔랑이·2024년 3월 29일

iOS/Swift

목록 보기
8/90

👉🏻 프로그래머스: 약수의 합 - 문제 링크


1️⃣ 첫 풀이

import Foundation

func solution(_ n:Int) -> Int {

    let num = n
    var a = 1
    var lst : [Int] = []

    while a <= Int(sqrt(Double(n))) {
        if n % a == 0 {
            lst.append(a)
            lst.append(n/a)
        }
        a += 1
    }

    let setlst = Set(lst)

    return setlst.reduce(0,+)
}

풀면서 공부한 부분

  • 리스트 선언 후 초기화 안익숙한데 저런식으로 써야 하는 것

  • python에서 제곱 곱하는 연산자 (**) 가 안먹어서 알아보니 foundation 라이브러리에 정의되어 있는 sqrt() 를 사용해야 함.
    - 제곱을 구하고 싶다면 pow(), 제곱근은 sqrt()
    - 둘 다 인자로 Double, Float를 받기 때문에 Int를 넣고 싶다면 자료형 변환이 필요함. 대소비교를 위해 다시 Int로 받고 싶다면 Int로 한번 더 감싸줘야 함.

  • Array 를 Set으로 바꾸기 위해서는 저런식으로 선언을 해 줘야 함. Set이 대문자임을 주의.

  • Swift 에는 list 대신 Array 가 있는데, 이것도 아직 익숙치가 않아서 변수명을 저런식으로 썼다... 앞으로 arr 라고 쓰는 습관을 들여야겠음.

2️⃣ 두 번째 풀이

다른 사람의 풀이를 확인해보니 너무 고수느낌이 나서, 일단 챗지피티한테 Swift가 권장하는 방식으로 효율적인 코드를 다시 짜 달라고 했더니 받은 코드.

import Foundation

func solution(_ n: Int) -> Int {
    // n이 1 이하인 경우, n 자체를 반환하고 함수 실행을 종료
    guard n > 1 else {
        return n
    }

    var divisors = Set<Int>()

    for divisor in 1...Int(sqrt(Double(n))) {
        if n % divisor == 0 {
            divisors.insert(divisor)
            divisors.insert(n / divisor)
        }
    }
    return divisors.reduce(0, +)
}

개선된 점

  • n 이 0인 경우, 0을 반환하도록 guard 문을 써줌. guard 문은 제시된 조건이 아니라면 else 후의 코드를 실행하도록 설계된 조건문이다.

  • 아예 약수 받는 리스트를 Set으로 선언함. Set은 사실 안 썼을때 정수 제곱근이 들어가는 것 같아서 추후에 추가한 코드였는데, 애초에 선언을 저렇게 하는게 당연히 더 좋겠군.

  • Set 에 값 집어넣기는 insert()

  • while문을 for_in 문으로 반복의 범위가 더욱 명시적으로 보인다. 지피티 말로는 while문보다 for in 문을 쓰는것이 오류가능성이 좋고 명시적이라 더 좋다고 하더라.

3️⃣ 다른 사람의 풀이 (짧은 코딩)

이제 이 풀이를 획기적으로 줄인 풀이.

func solution(_ n:Int) -> Int {   
    guard n != 0 else {
        return 0
    }
    return Array(1...n).filter{n % $0 == 0}.reduce(0, +)
}
  • n까지의 Array를 생성
  • 생성된 Array에 filter 함수 호출, filter 함수는 주어진 조건 (클로저)에 맞는 요소만 포함하는 새 Array를 반환
  • filter 안의 내용은 주어진 정수 n을 배열 안의 현재 요소($0)로 나누었을 때 0을 만족하는 것만 필터링
  • reduce() 메서드로 filter 통해 걸러진 값들의 합을 구함

python 에서도 리스트 컴프리헨션 공부하면서 익숙해질 때 짜릿함이 있었는데, 이것도 노력해 봐야겠다.

라는 생각을 했는데...?!

❓오잉❓

근데 쓰다보니까 위 코드는 그냥 코드 길이를 짧게 하기 위해서 저렇게 쓴거고, n을 제곱근까지만 나누는게 더 효율적인거 아냐? 하는 생각이 들어서 두 방법 다 직접 돌려봤다.

기존 풀이짧은 풀이

결과는 기존 풀이가 현저하게 좋다.

무조건 숏코딩 하려고 하지 말고, 어떤 코드가 효율적인지, 가독성이 좋은지 생각하면서 풀어야겠다는 생각을 했다.

profile
정체되지 않는 성장

0개의 댓글