Devlog👩🏻‍💻/Algorithm

[Swift] 프로그래머스 Lv.1 : 고차함수 연습

yujjne 2024. 2. 15. 17:57

 

Swift 언어로 알고리즘 문제를 풀 때 고차함수를 이용하면 간단하게 풀이할 수 있다.

내가 푼 풀이에서 1줄짜리 코드가 되는 걸 보며 고차함수에 조금 더 익숙해지고 연습해야겠다는 생각이 절실히 들었다.

오늘 풀었던 알고리즘 문제들을 고차함수로도 연습해 본 코드를 정리해 봤다.

 


 

Lv.1 : 수박수박수박수박수박수?

🔗문제 링크

 

나의 풀이

func solution(_ n:Int) -> String {
    let su = "수"
    let bak = "박"
    var result = ""
    for i in 1...n {
        result += i % 2 == 0 ? bak : su
    }
    return result
}

 

for문으로 1부터 n까지의 범위를 반복하며 짝수, 홀수를 판별하여  "수"와 "박"을 이어 붙이도록 작성했다.

 

 

다른 사람의 풀이

func solution1(_ n:Int) -> String {
    return "\(String(repeating: "수박", count: n / 2))\(n % 2 == 0 ? "" : "수")"
}

func solution2(_ n:Int) -> String {
    return (0..<n).map{($0%2==0 ? "수" : "박")}.reduce("",+)
}

 

  • 1. String(repeating:count:) 메서드 사용

repeating : "수박" → "수박" 문자열 반복

count: n/2 → 반복 횟수 설정

 

주어진 숫자가 홀수일 때는 "수박" 패턴을 n/2번 반복하고, 짝수일 때는 "수박" 패턴을 n/2번 반복한 뒤에 "수"를 추가하는 방법이다. repeating을 사용하여 간단하게 반복하여 사용할 수 있다.

 

  • 2. 고차함수 map, reduce 사용

.map{($0%2==0 ? "수" : "박")} →  n회 반복하는 범위에서 각 요소가 짝수인지 홀수인지 판별하여 "수", "박"으로 매핑

.reduce("", +) → 생성된 배열의 모든 요소를 이어 붙여 하나의 문자열로 반환

 

 

Lv.1 : 내적

🔗문제 링크

 

나의 풀이

// a[0]*b[0] + a[1]*b[1] + ... + a[n-1]*b[n-1] n은 a,b 배열의 길이
func solution(_ a:[Int], _ b:[Int]) -> Int {
    let n = a.count
    var result = 0
    for i in 0..<n {
        result += a[i] * b[i]
    }
    return result
}

 

반복문으로 배열의 길이만큼 요소를 반복했고,

각 배열의 같은 위치에 있는 요소를 곱하여 합산했다.

 

 

다른 사람의 풀이💡

func solution1(_ a:[Int], _ b:[Int]) -> Int {
    return zip(a, b).map(*).reduce(0, +)
}

 

  • zip 함수 : 주어진 두 배열의 각 요소를 한 쌍으로 묶어주는 역할
  • map(*) : 각 시퀀스의 요소를 곱하는 역할 → (1,4)는 1*4
  • reduce(0, +) : 이전까지의 합산 값을 초기값으로 설정하고 각 요소를 더하여 새로운 값 반환

 

따라서 map으로 생성된 배열의 모든 요소를 합산하여 반환한다.

이렇게 단순하게 정확하게 작성할 수 있다니.. 🫢

 

 

Lv.1 : 약수의 합

 

🔗문제 링크

 

나의 풀이

func solution(_ n:Int) -> Int {
    var result = 0
    guard  n > 0 else { return result }
    for i in 1...n {
        if n % i == 0 {
            result += i
        }
    }
    return result
}

 

반복문을 사용하여 n의 약수를 찾고, 찾은 약수를 더하여 결과를 반환했다.

 

 

다른 사람의 풀이

func solution(_ n:Int) -> Int {
    return Array(1...n).filter{n % $0 == 0}.reduce(0, +)
}

 

 

  • Array(1...n) : 1부터 n까지의 배열을 생성
  • .filter { n % $0 == 0 } : 배열 중에서 나누었을 때 나머지가 0인 요소들 필터링하여 새로운 배열을 생성,$0은 배열의 각 요소이다.
  • .reduce(0, +) : 필터링된 배열의 요소들을 모두 합하여 결과를 반환

 

 

Lv.1 : 나머지가 1이 되는 수 찾기

🔗문제 링크

 

나의 풀이

func reminder(_ n:Int) -> Int {
    return Array(1...n).filter{n % $0 == 1}.first! // min()
}

 

조건에 맞는 요소를 모두 필터링했다는 점이 아쉽긴 하지만 고차함수를 이용해서 문제에 접근해 봤다.

1부터 n까지의 숫자 중에서 n을 나누었을 때 나머지가 1인 수 중에서 가장 작은 수를 찾아 반환한다.

 

 

 

Lv.1 : X만큼  간격이 있는 n개의 숫자

🔗문제 링크

 

나의 풀이

func solution(_ x:Int, _ n:Int) -> [Int64] {
    // x 부터 x만큼 증가 n개
    var numbers: [Int64] = []
    for i in 1...n {
        numbers.append(Int64(x*i))
    }
    return numbers
}

 

1부터 n까지의 수를 반복하면서 xi를 곱한 값을 numbers 배열에 추가하는 방법으로 풀었다.

이렇게 하면 x부터 시작하여 x만큼 증가하는 숫자가 n개 만들어진다.

 

 

다른 사람의 풀이💡

 

func solution(_ x:Int, _ n:Int) -> [Int64] {
    return Array(1...n).map { Int64($0 * x) }
}

 

1부터 n까지의 숫자 배열을 생성한 후,

배열의 각 요소에 x를 곱한 값을 Int64 타입으로 변환하여 새로운 배열을 반환한다.

 

 


 

 

지금 보니 제일 편하게 생각할 수 있는 문법인 for문을 자주 사용하게 된다.

고차함수를 이용해 더 간결하고 함수형적인 스타일로 문제를 풀어보려는 습관을 가져야겠다.