성능 요약
메모리: 20.8 MB, 시간: 127.85 ms
구분
코딩테스트 연습 > 2021 Dev-Matching: 웹 백엔드 개발자(상반기)
문제 설명
- 민호는 다단계 조직을 이용하여 칫솔을 판매하고 있습니다. 판매원이 칫솔을 판매하면 그 이익이 피라미드 조직을 타고 조금씩 분배되는 형태의 판매망입니다.
어느정도 판매가 이루어진 후, 조직을 운영하던 민호는 조직 내 누가 얼마만큼의 이득을 가져갔는지가 궁금해졌습니다.
(중략)
- 각 판매원의 이름을 담은 배열 enroll, 각 판매원을 다단계 조직에 참여시킨 다른 판매원의 이름을 담은 배열 referral, 판매량 집계 데이터의 판매원 이름을 나열한 배열 seller, 판매량 집계 데이터의 판매 수량을 나열한 배열 amount가 매개변수로 주어질 때, 각 판매원이 득한 이익금을 나열한 배열을 return 하도록 solution 함수를 완성해주세요. 판매원에게 배분된 이익금의 총합을 계산하여(정수형으로), 입력으로 주어진 enroll에 이름이 포함된 순서에 따라 나열하면 됩니다.
인덱스 값(정수)을 가지고 핸들링 하는 문제가 아닌, '문자열'을 가지고 값들을 핸들링 해야 한다. → 문자열을 인덱스로 사용하기 위해 딕셔너리를 사용해야 한다.
칫솔 판매가 발생 시, 하위 노드에서 상위 노드로 부모를 타고 올라가는 형태이다. → 각 노드에 대해 부모 노드 정보를 가지고 있는 딕셔너리가 필요하다.
특정 seller가 판매를 하면, 해당 판매에 대해 부모 노드를 타고 올라가면서 각 노드에 결괏값을 할당할 함수를 작성한다.
(종료 조건은 cost >= 1일 때다. / 1 미만인 경우는 계산하지 않겠다고 했으므로)
# 빠른 입력을 위해 sys.stdin 사용
import sys
input = sys.stdin.readline
# 부모를 타고 올라가며 금액 계산
def calculate(parent, child,cost,res):
while (cost >= 1):
res[child] += cost - cost//10
child = parent[child]
if (child == '-'):
break
cost = cost//10
def solution(enroll, referral, seller, amount):
# 결과 할당 할 배열
answer = []
# 결과 할당 할 딕셔너리, 자식에 대해 부모들을 나타낼 딕셔너리
res = {}
parent = {}
# 딕셔너리로 parent {자식:부모}, res 구현 {셀러:수익}
for i in range(len(enroll)):
parent[enroll[i]] = referral[i]
res[enroll[i]] = 0
# seller 배열에서 값 하나씩 꺼내 calculate() 함수로 전달
for i in range(len(seller)):
calculate(parent,seller[i],amount[i]*100,res)
# enroll의 순서에 맞게 answer에 값 할당
answer = [res[name] for name in enroll]
# 결과 리턴
return answer
### 출력 테스트
# 각 판매원의 이름
enroll = ["john", "mary", "edward", "sam", "emily", "jaimie", "tod", "young"]
# 각 판매원을 다단계 조직에 참여시킨 다른 판매원의 이름
referral = ["-", "-", "mary", "edward", "mary", "mary", "jaimie", "edward"]
# 판매량 집계 데이터의 판매원의 이름
seller = ["young", "john", "tod", "emily", "mary"]
# 판매량 집계 데이터의 판매 수량
amount = [12, 4, 2, 5, 10]
result = solution(enroll, referral, seller, amount)
print(result)
import sys
input = sys.stdin.readline
def solution(enroll, referral, seller, amount):
graph = []
selling_list = {}
# 딕셔너리로 selling_list 구현 {셀러:수익}
for i in range(len(seller)):
selling_list[seller[i]] = amount[i]*100
for i in range(len(enroll)):
cost = selling_list.get(enroll[i])
if cost==None:
cost = 0
graph.append((enroll[i],referral[i],cost))
answer = [0]*((len(enroll))+1)
for i in range(len(graph)):
e,r,cost = graph[i]
rest = cost*0.1
graph[i][2] += int(cost - rest)
return answer
위의 코드를 통해 하고자 하였던 건, 아래와 같은 트리 구조를 작성하고자 했기 떄문이었다.
우선 '트리 문제이니, 인접 리스트 형태로 트리를 만들고나면 어떤 형태가 보이지 않을까?' 싶어서 인접 리스트를 구현했으나, 인덱스(정수)가 아니라 문자열을 사용하기 때문에 그 다음부터 부모를 타고 올라가는 부분이 보이지 않았다.
그래서 코드를 한 번 아예 싹 갈아 엎었다.
특정 노드에 대한 부모 노드를 저장 할 의도로 parent 딕셔너리를 새로 구현하였고, 이후 부모 노드를 타고 올라가면서 값들을 계산해주는 형태로 문제를 해결했다.
이번 기회에 딕셔너리와 더 친해질 수 있었다. 딕셔너리의 key error
에 대해 dictionary.get()
을 사용 해 해결할 수 있다는 것을 배웠고, answer = [res[name] for name in enroll]
와 같이 특정 배열 순서에 맞게 딕셔너리를 작성하는 코드적인 부분을 알 수 있게 되었다.
오늘 문제는 실전이었다면 사실 못 풀었을거다.
프로그래머스의 기업 기출 문제였던 점이 새로웠고, 확실히 '실제 기출 문제의 벽이 좀 있구나' 싶었다.
오늘 문제는 현실에 있는 특정 문제를 코드로 옮겼다는 감각이 느껴져서 좋았던 것 같다.
99클럽
TIL
개발자취업
코딩테스트준비
항해99