Problem Solving

[프로그래머스] 위장 - 해시 (Swift/Python)

reujusong 2020. 8. 25. 17:49

1. 문제 설명

스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.

예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.

종류 이름

얼굴 동그란 안경, 검정 선글라스
상의 파란색 티셔츠
하의 청바지
겉옷 긴 코트

 

스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.

 


2. 제한사항

  • clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
  • 스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
  • 같은 이름을 가진 의상은 존재하지 않습니다.
  • clothes의 모든 원소는 문자열로 이루어져 있습니다.
  • 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
  • 스파이는 하루에 최소 한 개의 의상은 입습니다.

3. 입출력 예

clothes return
[[yellow_hat, headgear], [blue_sunglasses, eyewear], [green_turban, headgear]] 5
[[crow_mask, face], [blue_sunglasses, face], [smoky_makeup, face]] 3

 


4. 나의 풀이

정말 오랜만에 알고리즘 문제를 들고왔다. 부캠이 끝나고 예전에 풀었던 문제들을 스위프트로 다시 한번 풀어보려고 들어갔는데 은근 swift를 지원하지 않는 문제가 많았다. 그래서 가장 처음으로 보이는 문제를 풀어보았는데, 알고리즘 자체는 파이썬과 동일하다. clothes를 순회하며 같은 종류의 옷을 dictionary에 담아주고, 모든 경우의 수를 구하면 된다.

 

// Swift 풀이

import Foundation

func solution(_ clothes:[[String]]) -> Int {
    var dictionary: [String: [String]] = [:]
    var answer = 1
    
    for i in clothes {
        if dictionary.keys.contains(i[1]) {
            dictionary[i[1]]!.append(i[0])
        }
        else {
            dictionary[i[1]] = [i[0]]
        }
    }

    let keys = Array(dictionary.keys)
    for j in 0..<keys.count {
        answer *= dictionary[keys[j]]!.count + 1
    }
    
    return answer - 1
}

 

# Python 풀이

import collections
def solution(clothes):
    answer = 1
    kind = [i[1] for i in clothes]
    nums = list(collections.Counter(kind).values())
    
    for j in nums:
        answer *= j+1
    return answer - 1

 

아무리 단순한 문제이긴 해도, 파이썬으로 푼게 매~~~우 예전인데 너무 똑같이 풀었다...ㅋㅋㅋㅋ 그래도 파이썬 같은 경우는 list comprehension이나 collections 등 여러 모듈을 활용했지만, 스위프트는 기본 문법만 사용해서 코드 자체가 조금 더 길어졌다. 고차 함수를 활용할 방법이 있을텐데 문제를 푸는데 직관적으로 떠오르질 않아서 다 풀고 다른 사람의 풀이를 확인해보니

 

// Swift 다른 사람의 풀이

import Foundation

func solution(_ clothes:[[String]]) -> Int {
    let types = clothes.compactMap({ $0.last })
    let typeSet = Set(types)
    let categories = Array(typeSet)

    let counts = categories.map({ category in
        return clothes.filter({ $0.last == category }).count + 1
    })

    return counts.reduce(1,  { $0 * $1 }) - 1
}

 

compactMap이나, map, filter, reduce 모두를 활용한 것을 볼 수 있었다. 파이썬 만큼 간결한 스위프트의 문법,,, 많이 공부해야겠다.

 

 

 

문제 링크: https://programmers.co.kr/learn/courses/30/lessons/42578

 

코딩테스트 연습 - 위장

 

programmers.co.kr