@sleepysoong
[프로그래머스][10번째로 푼 문제] 258712. 가장 많이 받은 선물 (240927) 본문
[프로그래머스][10번째로 푼 문제] 258712. 가장 많이 받은 선물 (240927)
sleepysoong 2024. 11. 26. 12:17구분
코딩테스트 연습 > 2024 KAKAO WINTER INTERNSHIP
채점결과
- 정확성: 100.0
- 합계: 100.0 / 100.0
제출 일자
2024년 09월 27일 09:52:51
문제 설명
선물을 직접 전하기 힘들 때 카카오톡 선물하기 기능을 이용해 축하 선물을 보낼 수 있습니다. 당신의 친구들이 이번 달까지 선물을 주고받은 기록을 바탕으로 다음 달에 누가 선물을 많이 받을지 예측하려고 합니다.
- 두 사람이 선물을 주고받은 기록이 있다면, 이번 달까지 두 사람 사이에 더 많은 선물을 준 사람이 다음 달에 선물을 하나 받습니다.
- 예를 들어
A
가B
에게 선물을 5번 줬고,B
가A
에게 선물을 3번 줬다면 다음 달엔A
가B
에게 선물을 하나 받습니다.
- 예를 들어
- 두 사람이 선물을 주고받은 기록이 하나도 없거나 주고받은 수가 같다면, 선물 지수가 더 큰 사람이 선물 지수가 더 작은 사람에게 선물을 하나 받습니다.
- 선물 지수는 이번 달까지 자신이 친구들에게 준 선물의 수에서 받은 선물의 수를 뺀 값입니다.
- 예를 들어
A
가 친구들에게 준 선물이 3개고 받은 선물이 10개라면A
의 선물 지수는 -7입니다.B
가 친구들에게 준 선물이 3개고 받은 선물이 2개라면B
의 선물 지수는 1입니다. 만약A
와B
가 선물을 주고받은 적이 없거나 정확히 같은 수로 선물을 주고받았다면, 다음 달엔B
가A
에게 선물을 하나 받습니다. - 만약 두 사람의 선물 지수도 같다면 다음 달에 선물을 주고받지 않습니다.
위에서 설명한 규칙대로 다음 달에 선물을 주고받을 때, 당신은 선물을 가장 많이 받을 친구가 받을 선물의 수를 알고 싶습니다.
예시
이름 | 준 선물 | 받은 선물 | 선물 지수 |
---|---|---|---|
joy | 0 | 1 | -1 |
brad | 0 | 1 | -1 |
alessandro | 4 | 1 | 3 |
conan | 0 | 1 | -1 |
david | 1 | 1 | 0 |
alessandro
가 선물을 더 많이 줬던 joy
, brad
, conan
에게서 선물을 3개 받습니다. 선물을 하나씩 주고받은 david
보다 선물 지수가 커 선물을 하나 받습니다.david
는 선물을 주고받지 않았던 joy
, brad
, conan
보다 선물 지수가 커 다음 달에 선물을 3개 받습니다.joy
, brad
, conan
은 선물을 받지 못합니다.
다음 달에 가장 선물을 많이 받는 사람은 alessandro
이고 4개의 선물을 받습니다. 따라서 4를 return 해야 합니다.
입출력 예 #3
a
와 b
, a
와 c
, b
와 c
사이에 서로 선물을 주고받은 수도 같고 세 사람의 선물 지수도 0으로 같아 다음 달엔 아무도 선물을 받지 못합니다. 따라서 0을 return 해야 합니다.
from itertools import combinations
def solution(friends, gifts):
temp = {}
point = {}
result = {}
for _ in gifts:
[sender, receiver] = _.split(" ")
if not sender in temp:
temp[sender] = {}
if not receiver in temp[sender]:
temp[sender][receiver] = 0
temp[sender][receiver] += 1
if not sender in point:
point[sender] = 0
if not receiver in point:
point[receiver] = 0
point[sender] += 1
point[receiver] -= 1
def who(a, b):
try:
count_a = temp[a][b]
except:
count_a = 0
try:
count_b = temp[b][a]
except:
count_b = 0
if count_a > count_b:
return a
if count_a < count_b:
return b
point_a = point[a] if a in point else 0
point_b = point[b] if b in point else 0
if point_a > point_b:
return a
if point_a < point_b:
return b
return None
for (a, b) in combinations(friends, 2):
_ = who(a, b)
if not _ == None:
if not _ in result:
result[_] = 0
result[_] += 1
return 0 if len(result) < 1 else sorted(result.values())[-1]
느낀 점
for i, friend1 in enumerate(friends):
for j in range(i+1, len(friends)):
friend2 = friends[j]
a = from_count[friend1].count(friend2)
b = from_count[friend2].count(friend1)
if a < b:
next_gift[friend2] += 1
elif a > b:
next_gift[friend1] += 1
elif a == b:
gi_a = gift_index[friend1]
gi_b = gift_index[friend2]
if gi_a > gi_b:
next_gift[friend1] += 1
elif gi_a < gi_b:
next_gift[friend2] += 1
answer = 0
for friend in friends:
answer = max(answer, next_gift[friend])
return answer
오매 Collections
에 defaultdict
라는 것이 있나? 난 Counter
말고는 써본 적이 없는걸 (...)
defaultdict
가 무엇인가요?
defaultdict
는 기본적으로 값이 존재하지 않는 키에 접근할 때 발생하는 KeyError
를 방지하기 위해 설계된 딕셔너리 자료구조입니다. defaultdict
는 첫 번째 인자로 제공된 함수나 클래스에 의해 초기화되는 기본 값을 제공합니다.
기본적으로 파이썬의 일반적인 dict
는 존재하지 않는 키에 접근하면 KeyError
가 발생하지만 defaultdict
는 그런 경우에도 기본값을 반환해주는 장점이 있습니다.
from collections import defaultdict
# 기본값으로 int(0)를 갖는 defaultdict
d = defaultdict(int)
# 기본값이 없을 경우 자동으로 0을 할당
d['a'] += 1 # d['a']가 존재하지 않으면 기본값 0에서 1 증가
print(d) # 출력: defaultdict(<class 'int'="">, {'a': 1})
defaultdict
를 사용하는 이유
- 기본값을 자동으로 설정: 값이 존재하지 않는 키에 접근할 때 기본값을 자동으로 설정해주는 기능은 딕셔너리의 값을 다룰 때 매우 유용합니다.
- KeyError를 방지: 일반 딕셔너리는 존재하지 않는 키에 접근하면
KeyError
가 발생하지만,defaultdict
는 미리 지정한 기본값을 반환합니다.
예시: 리스트를 기본값으로 설정
d = defaultdict(list)
# 존재하지 않는 키에 리스트 추가
d['a'].append(1)
print(d) # 출력: defaultdict(<class 'list'="">, {'a': [1]})
# 여러 값을 리스트에 계속 추가
d['a'].append(2)
print(d) # 출력: defaultdict(<class 'list'="">, {'a': [1, 2]})
예시: 사용자 정의 초기값 사용
# 초기값으로 5를 반환하는 함수
def default_value():
return 5
# 기본값으로 함수 결과를 사용하는 defaultdict
d = defaultdict(default_value)
# 존재하지 않는 키 'b'에 접근하면 5가 반환됨
print(d['b']) # 출력: 5
defaultdict
를 사용하면 좋은 경우
- 카운팅 작업: 리스트나 문자열에서 등장 횟수를 세는 경우. 이때
defaultdict(int)
를 사용하면 편리합니다. - 그룹화 작업: 데이터를 특정 조건에 따라 그룹화할 때,
defaultdict(list)
를 사용하면 그룹에 데이터를 쉽게 추가할 수 있습니다. - 기본값 설정이 필요한 경우: 딕셔너리에서 초기화 없이 바로 값을 다뤄야 할 때.
defaultdict
vs. 일반 dict
defaultdict
는 특정 상황에서 유리하지만, 기본적으로는 dict
를 사용하는 것이 더 좋습니다. defaultdict
는 무조건 기본값을 설정하므로, 원치 않는 키가 생성될 수 있기 때문입니다.
예를 들어, 실수로 존재하지 않는 키에 접근하면 기본값이 설정되어 예기치 않은 데이터가 생성될 수 있습니다.
예시: 사용자 정의 초기값 사용
# 초기값으로 5를 반환하는 함수
def default_value():
return 5
# 기본값으로 함수 결과를 사용하는 defaultdict
d = defaultdict(default_value)
# 존재하지 않는 키 'b'에 접근하면 5가 반환됨
print(d['b']) # 출력: 5
defaultdict
를 사용하면 좋은 경우
- 카운팅 작업: 리스트나 문자열에서 등장 횟수를 세는 경우. 이때
defaultdict(int)
를 사용하면 편리합니다. - 그룹화 작업: 데이터를 특정 조건에 따라 그룹화할 때,
defaultdict(list)
를 사용하면 그룹에 데이터를 쉽게 추가할 수 있습니다. - 기본값 설정이 필요한 경우: 딕셔너리에서 초기화 없이 바로 값을 다뤄야 할 때.
defaultdict
vs. 일반 dict
defaultdict
는 특정 상황에서 유리하지만, 기본적으로는 dict
를 사용하는 것이 더 좋습니다. defaultdict
는 무조건 기본값을 설정하므로, 원치 않는 키가 생성될 수 있기 때문입니다.
예를 들어, 실수로 존재하지 않는 키에 접근하면 기본값이 설정되어 예기치 않은 데이터가 생성될 수 있습니다.
'programming > 잘 하는 언어는 없지만 문제는 풀어보고 싶어!' 카테고리의 다른 글
[프로그래머스][12번째로 푼 문제] 120907. OX퀴즈 (241106; 자바로 푼 첫 문제) (0) | 2024.11.26 |
---|---|
[프로그래머스][11번째로 푼 문제] 142086. 가장 가까운 같은 글자 (241028) (1) | 2024.11.26 |
[프로그래머스][9번째로 푼 문제] 120853. 컨트롤 제트 (240828) (1) | 2024.11.12 |
[프로그래머스][8번째로 푼 문제] 12906. 같은 숫자는 싫어 (240809) (1) | 2024.11.12 |
[프로그래머스][7번째로 푼 문제] 120871. 저주의 숫자 3 (240809) (0) | 2024.11.12 |