2월 13일 TIL

이승원·2024년 2월 13일
0

TIL

목록 보기
21/75
post-thumbnail

프로그래머스 코딩테스트 [ 할인 행사 ]

Github 링크

  • 이번 문제는 총 3개의 배열이 주어졌다, 물품 목록, 물품 수량, 할인 행사하는 물품 목록. 할인행사를 하루에 하나의 물품 하나의 수량만 한다고 가정하고, 물품 목록과 수량을 전부 다 살수 있는 연속 10일을 찾는게 목적이다.
  • 우선 내가 처음 생각한 방법은, 물품 목록을 수량에 맞게 배열을 조정하는것이다. 예를 들어 "banana" 3개를 구입하면 ["banana","banana","banana"] 이런식으로 우선적으로 조정하고, 그리고 정렬을 한다음에, 할인 물품 목록은 0부터 count-10까지 순회하면서, 10사이즈의 subArray를 만들어서 정렬한다음에 비교를 할려고 했다. 근데 생각해보니 없는 물품이 포함되어 있을 수도 있어서, 결국은 하나하나 순회를 해야하는건데, 굳이 배열을 조정할 필요가 있을까 생각했다. 그래서 dictionary를 이용해서 각 물품을 key로, 수량을 value로 설정했다.
func solution(_ want:[String], _ number:[Int], _ discount:[String]) -> Int {
    var ans = 0 
    var dic : [String:Int] = [:]
    
    for index in 0..<want.count{
        let temp = want[index]
        dic[temp] = number[index]
    }
  • 그리고 이제 할인 물품 목록을 10개의 element로 구성되어 있는 sub Array로 만들고, 또 일일이 순회하면서 확인을 한다. 매번 확인해야 하니깐 만들어 놓은 딕셔너리를 복사본을 만들어서 value에서 -1씩 하면서 검사를 한다. 그리고 마지막에 dictionary에 있는 value들이 전부 0 이하면 ans+=1 을 해준다.
for index in 0...discount.count-10{
        let tempArr = Array(discount[index..<index+10])
        var tempDic = dic
        for element in tempArr{
             if let value = tempDic[element] {
                 tempDic.updateValue(value - 1, forKey: element)
             }
        }
        let satisfy = tempDic.values.allSatisfy{$0 <= 0}
        if satisfy {
            ans += 1
        }
  • allSatisfy 함수는 콜렉션의 모든 요소에 대해서 조건을 만족하는지 확인하는 함수다. 유용하게 쓸 수 있는 함수 인것 같다.
let allSatisfy = collection.allSatisfy { element in
    // 조건을 검사하는 코드
    // true 또는 false를 반환
}

프로그래머스 코딩테스트 [ 의상 ]

Github 링크

  • 이 문제는 다른 언어에서는 hashmap을 사용해야 하는거 같은데, swift에서는 그냥 dictionary만 사용해도 되는 문제 였다. 의상 종류는 총 4가지 있으며, 각각의 종류 별로 의상이 주어지고, 같은 종류의 옷은 동시에 착용이 불가능하고, 최소 한종류의 의상 종류를 선택해야하며, 중복되는 의상이 있어도, 새로운 의상이 추가되었다면 새로운 조합으로 간주한다.
  • 문제를 이해하는데 사실 오히려 더 오래 걸렸던것 같다.
  • 내가 사용한 방법은 주어진 인풋을 통해 총 각각의 의상종류의 총 몇가지의 의상이 있는 dictionary로 표현했다.
func solution(_ clothes:[[String]]) -> Int {
    var ans = 1
    var dic : [String:Int] = [:]
    
    for cloth in clothes {
        if let value = dic[cloth[1]] {
                 dic.updateValue(value + 1, forKey: cloth[1])
        }else{
            dic[cloth[1]] = 1
        }
    }
  • 그런 다음 value들로 계산으로 하는것이다.
for value in dic.values{
        ans = ans*(value+1)
}
    return ans - 1
  • 다 풀고 다른사람이 풀이를 봤는데, 전체적인 흐름은 똑같은데 compactMap 함수를 사용해서 참고하려고 적었다.
// 다른 사람의 더 깔끔한 풀이 

func solution(_ clothes:[[String]]) -> Int {
    let types = clothes.compactMap({ $0.last })
    let typeSet = Set(types)
    let categories = Array(typeSet)
    print(categories)
    
    let counts = categories.map({ category in
        return clothes.filter({ $0.last == category }).count + 1
    })
    
    return counts.reduce(1,  { $0 * $1 }) - 1
    
    return 0
}
  • compactMap은 map의 상위버전(?)이라고 생각하기로 했다. map은 고차함수로서, 주어진 콜렉션의 변형을 하여 새로운 콜렉션을 생성한다, 하지만 만약에 클로저 변환값에서 nil값이 반환되면 nil도 같은 콜렉션에 넣어서 반환하다, 그리고 Nil값이 나온다는것은? optional도 마찬가지로 붙어서 나온다는것이다. 반면 compactMap은 nil은 결과 콜렉션에 포함하지 않는다. 아래 코드가 예시이다
let numbers = ["1", "2", "3", "four", "5"]

let mappedNumbers = numbers.map { Int($0) }
let compactMappedNumbers = numbers.compactMap { Int($0) }

print(mappedNumbers) // [Optional(1), Optional(2), Optional(3), nil, Optional(5)]
print(compactMappedNumbers) // [1, 2, 3, 5]
  • 사실 이 문제에서는 굳이 compactMap안써도 되긴한데, 옵셔널 값을 처리하는게 원칙이니깐 compactMap을 사용하는것이 더욱 정확한 정답이긴하다.
  • 정리하자면, compactMap과 map의 차이는 compactMap은 nil값 무시, map은 Nil 포함. compactMap은 옵셔널 바인딩을 통해 옵셔널 값을 확인하고, 값이 있는 경우에만 추출하고, map은 그냥 optional 상태로 리턴.
profile
개발자 (진)

0개의 댓글