문제
https://school.programmers.co.kr/learn/courses/30/lessons/42578
코니는 매일 다른 옷을 조합하여 입는것을 좋아합니다.
예를 들어 코니가 가진 옷이 아래와 같고, 오늘 코니가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야합니다.
종류이름
종류 | 이름 |
얼굴 | 동그란안경, 검정선글라스 |
상의 | 파란색 티셔츠 |
하의 | 청바지 |
겉옷 | 긴 코트 |
- 코니는 각 종류별로 최대 1가지 의상만 착용할 수 있습니다. 예를 들어 위 예시의 경우 동그란 안경과 검정 선글라스를 동시에 착용할 수는 없습니다.
- 착용한 의상의 일부가 겹치더라도, 다른 의상이 겹치지 않거나, 혹은 의상을 추가로 더 착용한 경우에는 서로 다른 방법으로 옷을 착용한 것으로 계산합니다.
- 코니는 하루에 최소 한 개의 의상은 입습니다.
코니가 가진 의상들이 담긴 2차원 배열 clothes 가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.
제한사항
- clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
- 코니가 가진 의상의 수는 1개 이상 30개 이하입니다.
- 같은 이름을 가진 의상은 존재하지 않습니다.
- clothes의 모든 원소는 문자열로 이루어져 있습니다.
- 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
입출력 예
clothes | return |
[['yellow_hat', 'headgear'], ['blue_sunglassess','eyewear',['green_turban','headgear']] | 5 |
🤔 어떻게 접근해볼까?
일단 clothes의 각 행이 의상의 이름과, 의상의 종류로 따로 놀고있으니까. . 의상의 종류를 key 값으로 빼주고, 종류에 해당하는 의상의 이름을 value 로 빼줘야 한다는 것까지는 생각을 해보았다.
그렇다면 이제 여기서 접근하는 것이 문제였다. 어떻게 리스트에서 key 와 value 를 분리를 시킬 것인가!
첫번째 시도- 딕셔너리와 반복문
딕셔너리로 빼주자.
def solution(clothes):
answer = 1
closet = {}
for types, val in clothes:
if val in closet:
closet[val].append(types)
else:
closet[val] = [types]
for types in closet.values():
answer *= (len(types)+1)
return answer - 1
- 옷의 종류를 types, 옷의 이름을 val 로 두었다.
- closet= 딕셔너리 형태로 저장될 빈 딕셔너리
- 만약 현재 옷이 closet에 이미 존재한다면 (= 즉 중복이 된다면,)
- 그 옷은 종류가 될 것이다. 따라서 종류를 추가해준다.
- 만약 현재 옷이 closet에 존재하지 않는다면
- 해당 종류의 옷 리스트를 생성하고 현재 옷의 종류를 추가해주면 된다.
- 그리고.. 아무옷도 입지 않으면 안되니까 아무옷도 입지 않은 경우를 제외하기 위해 1을 반환해준다.
조금 더 설명
clothes = [("상의", "셔츠"), ("상의", "니트"), ("하의", "청바지"), ("하의", "치마"), ("액세서리", "모자")]
만약 이런 식으로 clothes 가 있다고 생각해보자.
우리는 빈 딕셔너리에 key, value 값으로 넣을 것이다.
- 빈 딕셔너리에 "상의", "셔츠" 가 없으므로 빈 딕셔너리에 그대로 저장이 된다.
- 두번째 "상의", "니트"를 빈 딕셔너리에 넣으려고 보니까.
- 어라리! "상의" 가 이미 있는 것을 확인할 수 있다.
- 따라서 이미 있는 key 값에 val (옷의 이름) 을 넣어주면 된다.
- 그리고 "하의","청바지" 를 넣으려고 보니까..
- closet={"상의": "셔츠","니트",} <- 여기에 하의 청바지가 없기 때문에 그대로 넣어주는 것이다.
두번째 시도 - defaultdict 활용하기
from collections import defaultdict
def solution(clothes):
answer = 1
closet = defaultdict(list)
for item, type in clothes:
closet[type].append(item)
for count in closet.values():
answer *= (len(count) + 1)
return answer - 1
defaultdict :
dictionary와 동일하게 [key : value] 형식으로 구성되고 모든 key에 대해 기본(default) 값을 설정해준다.
계속해서 초기값으로 설정을 해주면서 가능한 모든 조합을 복합연산자로 계산해주고, 마지막에 아무것도 선택하지 않는 경우를 빼주면 된다.
🤔*= 복합할당연산자는 또 뭐야?
- 복합 할당 연산자는 변수에 연산을 수행하고 그 결과를 다시 해당 변수에 할당하는 연산자
- *=의 경우 곱셈 연산을 수행하고 그 결과를 변수에 다시 할당한다.
# 예시!
answer = 2
answer *= 4 # answer = answer * 2
answer *= 6 # answer = answer * 3
오늘 정말..이해 하는데만 너무 오래걸렸다. 역시 알고리즘은 문제를 이해하는 게 제일 중요한 것 같다.
내일부터는 해시 맵을 활용하여 문제를 풀어보도록 하겠다.
'Algorithm' 카테고리의 다른 글
[Python] 프로그래머스 - 배열의 길이에 따라 다른 연산하기 (0) | 2024.07.15 |
---|---|
[Python] 프로그래머스 해시-베스트 앨범 (0) | 2024.07.13 |
[Python] 프로그래머스 해시- 전화번호 목록 (0) | 2024.07.11 |
[Python] 프로그래머스 알고리즘 해시- 완주하지 못한 선수 (0) | 2024.07.10 |
[Python] 프로그래머스 알고리즘 해시 - 폰켓몬 (0) | 2024.07.09 |