from itertools import combinations
def solution(friends, gifts):
answer = 0
info_map = dict()
answer_map = dict()
for friend in friends:
info_map[friend] = dict()
info_map[friend]['TO'] = dict()
info_map[friend]['TO']['total'] = 0
info_map[friend]['FROM'] = dict()
info_map[friend]['FROM']['total'] = 0
answer_map[friend] = 0
for gift in gifts:
sender, reciever = map(str, gift.split())
if reciever in info_map[sender]['TO'].keys():
info_map[sender]['TO'][reciever] += 1
info_map[sender]['TO']['total'] += 1
else:
info_map[sender]['TO'][reciever] = 1
info_map[sender]['TO']['total'] += 1
if sender in info_map[reciever]['FROM'].keys():
info_map[reciever]['FROM'][sender] += 1
info_map[reciever]['FROM']['total'] += 1
else:
info_map[reciever]['FROM'][sender] = 1
info_map[reciever]['FROM']['total'] += 1
cases = list(combinations(friends, 2))
for case in cases:
f1, f2 = case
cnt_f1_send_f2 = 0
cnt_f2_send_f1 = 0
if f2 in info_map[f1]['TO'].keys():
cnt_f1_send_f2 = info_map[f1]['TO'][f2]
if f1 in info_map[f2]['TO'].keys():
cnt_f2_send_f1 = info_map[f2]['TO'][f1]
if cnt_f1_send_f2 > cnt_f2_send_f1:
answer_map[f1] += 1
elif cnt_f1_send_f2 < cnt_f2_send_f1:
answer_map[f2] += 1
elif ((cnt_f1_send_f2 == 0) and (cnt_f2_send_f1 == 0)
or (cnt_f2_send_f1 == cnt_f1_send_f2)):
f1_index = (info_map[f1]['TO']['total'] - info_map[f1]['FROM']['total'])
f2_index = (info_map[f2]['TO']['total'] - info_map[f2]['FROM']['total'])
if f1_index == f2_index:
continue
if f1_index > f2_index:
answer_map[f1] += 1
else:
answer_map[f2] += 1
answer_lst = []
for key, value in answer_map.items():
answer_lst.append((key, value))
# print(help(max))
answer = max(answer_lst, key = lambda x : x[1])
return answer[1]
이런 어려운 구현 문제의 특징은 조건이 많다는 점이다. 즉, 세부적으로 고려해야할 조건들이 복합적으로 엮여져 있는데, 이것을 단번에 고려하려는 순간 문제 푸는 것이 어려워진다.
따라서 다음과 같은 규칙을 따르는 것이 좋다.
위 문제 같은 경우에는, 양방향으로 사람들을 맵핑 시켜야 했다. 그래서 나는 딕셔너리를 통해 이를 표현하였고, 문제에서 제시한 조건들을 인라인으로 하나의 수식으로 계산하였다. 원래는 조건마다 함수를 만드는 것이 좋지만, 자료구조가 매우 적절하여, 굳이 함수를 만들 필요가 없었다.