Notice

[Python] 프로그래머스 위장

위장

해시를 사용하는 문제

 

 

 

풀이

def solution(clothes):
    hash = {}
    
    # hash를 초기화 => {"옷 종류" : 0}
    for n, t in clothes:
        hash[t] = 0
	
    # 옷 종류별로 가진 옷의 수를 해시에 넣음  
    for key in hash.keys():
        cnt = 0
        for n, t in clothes:
            if key == t:
                cnt += 1
        hash[key] = cnt

    value = list(hash.values())   # [2, 1]
    ans = 1
    # 경우의 수를 계산
    for i in value:
        ans *= (i + 1)      # ans = 6

    return ans - 1          # 옷을 모두 안 입을 경우를 제외

 

[예제1의 경우]

종류 의상
"headgear" 2
"eyewear" 1

 

1. headgear은 총 2개   =>  3가지의 경우의 수 존재

   1) 첫번째 옷을 입는다.

   2) 두번째 옷을 입는다.

   3) 입지 않는다.

 

2. eyewear은 총 1개   =>  2가지의 경우의 수 존재

  1) 첫번째 옷을 입는다.

  2) 입지 않는다.

 

그렇다면 총 3 x 2 가지의 경우의 수는 6가지이다. 여기서 두 종류의 옷을 모두 입지 않을 경우를 제외하면 5가지가 정답이다.

 

 

 

[다른 풀이 이해하기]

1. 해시를 이용한 풀이

def solution(clothes):
    # 1. 옷을 종류별로 구분하기
    hash_map = {}
    for clothe, type in clothes:
        hash_map[type] = hash_map.get(type, 0) + 1
        
    # 2. 입지 않는 경우를 추가하여 모든 조합 계산하기
    answer = 1
    for type in hash_map:   
        answer *= (hash_map[type] + 1)
    
    # 3. 아무종류의 옷도 입지 않는 경우 제외하기
    return answer - 1

 

- Hash_map.get(type, 0)

이 함수는 `key`에 해당하는 `value`가 있으면 가져오고, 아닐 경우 0을 default로 지정하여 사용하겠다는 의미

여기서는 옷 종류의 가짓 수를 의미

 

 

 

2. Counter를 사용한 풀이

from collections import Counter
from functools import reduce

def solution(clothes):
    # 1. 의상 종류별 Counter를 만든다.
    counter = Counter([type for clothe, type in clothes])

    # 2. 모든 종류의 count + 1을 누적하여 곱해준다
    answer = reduce(lambda acc, cur: acc*(cur+1), counter.values(), 1) - 1
    return answer

 


Counter 함수

 collections 모듈의 `Counter` 클래스

먼저 중복된 데이터가 저장된 배열을 인자로 넘기면 각 원소가 몇 번씩 나오는 지가 저장된 객체를 얻을 수 있다.

from collections import Counter

Counter(["hi", "hey", "hi", "hi", "hello", "hey"])
>> Counter({'hi': 3, 'hey': 2, 'hello': 1})

 

1. Counter를 사전처럼 사용하기

from collections import Counter

counter = Counter("hello world")
counter["o"], counter["l"]
>> (2, 3)

# Counter로 사전 프로그램 구현
def countLetters(word):
	counter = {}
    for letter in word:
    	if letter not in counter:
        	counter[letter] = 0
        counter[letter] += 1
   	
    return counter

countLetters('hello world'))
>> {'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1}

 

 

2. 가장 흔한 데이터 찾기

데이터의 개수가 많은 순으로 정렬된 배열을 리턴하는 ` most_common() ` 이라는 메서드 제공

from collections import Counter

Counter("hello world").most_common()
>> [('l', 3), ('o', 2), ('h', 1), ('e', 1), (' ', 1), ('w', 1), ('r', 1), ('d', 1)]

Counter("hello world").most_common(l)
>> [('l', 3)]

 

# 가장 많이 나온 데이터를 구하는 프로그램

from collections import Counter

def find_max(word):
	counter = Counter(word)
    max_count = -1
    
    for letter in counter:
    	if counter[letter] > max_count:
        	max_count = counter[letter]
            max_letter = letter
       	
        return max_letter, max_count

find_max("hello_world")
>> ('l', 3)

 

 

3. 산술 연산자 활용

Counter를 숫자처럼 산술 연산자로 사용할 수 있다.

from collection import Counter

counter1 = Counter(['A', 'A', 'B'])
counter2 = Counter(['A', 'B', 'B'])

counter1 + counter2
>> Counter({'A': 3, 'B': 3})

counter1 - counter2
>> Counter({'A': 1})

※ 뺄셈의 결과로 0이나 음수가 나온 경우 : 최종 카운터 객체에서 제외됨

 

 


Reduce 함수                      

iterable한 객체(문자열, 리스트, 딕셔너리, 세트)의 각 요소를 연산한 뒤 이전 연산 결과들과 누적해서 반환해 주는 함수

 

[예제]

리스트에서 1부터 20까지의 정수가 담겼을 때, 해당 리스트의 모든 요소의 합을 출력

1. `reduce`를 사용하지 않았을 때

def sum(x, y):
	return x + y
    
target = list(range(1, 21))
result = 0

for value in target:
	result - sum(result, value)
print(result)

 

2.  reduce를 사용했을 때

from functools import reduce

def sum(x, y):
	return x + y

target = list(range(1, 21))
print(reduce(sum, target))
>> 210

 

 

 

 

https://school.programmers.co.kr/learn/courses/30/lessons/42578

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

글쓰기 설정