위장
스파이들은 매일 다른 옷을 조합하여 입어 자신을 위장합니다.
예를 들어 스파이가 가진 옷이 아래와 같고 오늘 스파이가 동그란 안경, 긴 코트, 파란색 티셔츠를 입었다면 다음날은 청바지를 추가로 입거나 동그란 안경 대신 검정 선글라스를 착용하거나 해야 합니다.
스파이가 가진 의상들이 담긴 2차원 배열 clothes가 주어질 때 서로 다른 옷의 조합의 수를 return 하도록 solution 함수를 작성해주세요.
제한사항
- clothes의 각 행은 [의상의 이름, 의상의 종류]로 이루어져 있습니다.
- 스파이가 가진 의상의 수는 1개 이상 30개 이하입니다.
- 같은 이름을 가진 의상은 존재하지 않습니다.
- clothes의 모든 원소는 문자열로 이루어져 있습니다.
- 모든 문자열의 길이는 1 이상 20 이하인 자연수이고 알파벳 소문자 또는 '_' 로만 이루어져 있습니다.
- 스파이는 하루에 최소 한 개의 의상은 입습니다.
기본적인 경우의 수 순열 문제를 코드로 구현하는 문제이다.
하지만 순열문제임을 눈치채지 못하고 for문을 반복해서 쓰다가 많이 헤맸다..
+ list의 성분을 Count하는 부분을 잘 몰랐기 때문에 구글에서 검색해 collections의 Counter를 import해서 풀이함.
from collections import Counter
def solution(clothes):
answer = 0
temp = []
num = 1
for i in range(0, len(clothes)):
temp.append(clothes[i][1])
result = Counter(temp)
result = list(result.values())
for i in range(0, len(result)):
num = num * (list(result)[i] + 1)
answer = num - 1
return answer
내 코드는 뭔가 모르게 조잡하다.
다른사람의 풀이법
1.
def solution(clothes):
from collections import Counter
from functools import reduce
cnt = Counter([kind for name, kind in clothes])
answer = reduce(lambda x, y: x*(y+1), cnt.values(), 1) - 1
return answer
2.
def solution(clothes):
clothes_type = {}
for c, t in clothes:
if t not in clothes_type:
clothes_type[t] = 2
else:
clothes_type[t] += 1
cnt = 1
for num in clothes_type.values():
cnt *= num
return cnt - 1
3.
import collections
from functools import reduce
def solution(c):
return reduce(lambda x,y:x*y,[a+1 for a in collections.Counter([x[1] for x in c]).values()])-1
순열을 이용했다는 기본원리는 같다. Counter객체와 reduce에 대해서 공부할 필요가 있다.
collections 모듈 - Counter
https://excelsior-cjh.tistory.com/94
간단히 설명하면 컨테이너에 동일한 값의 자료가 몇개인지를 파악하는데 사용하는 객체이고, 그 출력값은 딕셔너리 형태이다.
여기서 말하는 컨테이너는 리스트, 딕셔너리, 스트링, 또는 (값=개수) 형태가 될 수 있다.
Counter의 사용가능 메소드는
1) Update() : Counter의 값 갱신
2) elements() : 입력된 값의 요소에 해당하는 값을 풀어서 반환
3) most_common(n) : 입력된 값의 요소들 중 빈도스가 높은 순으로 상위 ~개를 list안의 tuple형태로 반환해준다.
4) substract() : 말 그대로 요소를 뺴는 것을 의미한다 다만, 요소가 없는 경우에는 음수 값이 출력된다.
Counter의 연산
1) 덧셈(+) : 더한 요소만큼 카운트를 더해서 세어 줌
2) 뺄셈(-) : substarct와 다르게 음수값은 출력하지 않음
3) 교집합(&)과 합집합(|) : 말 그대로 요소간의 교집합, 합집합의 개수를 세어준다 출력은 딕셔너리 형태
functools 모듈 - reduce
reduce(function, iterable, initializer = None)
reduce는 첫 번째 파라미터로 함수(람다함수, 정의함수) 두 번째 파라미터로 계산 하고자하는 리스트가 들어 갈 수 있다.
from functools import reduce
result = reduce(lambda x, y: x+y, [1,2,3,4,5])
# (((1+2)+3)+4)+5)
#15
위와같이 리스트 안의 모든 값을 더 해줄 수도 있고 (for문이 필요없다)
from functools import reduce
func = lambda a, b: a if (a > b) else b
# a,b 비교해서 더 큰 것만 반환해주는 함수
result = reduce(func, [1, 100, 2, 55])
print(result)
# 100
위와 같이 최대값을 구할 수 도 있다!
'코딩테스트 공부 > 프로그래머스 문제' 카테고리의 다른 글
프로그래머스_해시_전화번호 목록 (0) | 2020.06.03 |
---|---|
프로그래머스 해시_완주하지 못한 선수 (0) | 2020.05.29 |
프로그래머스_스택_탑 (0) | 2020.05.26 |
프로그래머스_완전탐색_모의고사 (0) | 2020.05.04 |
2019 카카오 겨울 인턴쉽_크레인 인형뽑기 게임 (0) | 2020.05.04 |