본문 바로가기

Algorithm/Practice

2021 Dev-Matching: 웹 백엔드 개발(상반기) #3

다단계 칫솔 판매


Level 3

 

 

코딩테스트 연습 - 다단계 칫솔 판매

민호는 다단계 조직을 이용하여 칫솔을 판매하고 있습니다. 판매원이 칫솔을 판매하면 그 이익이 피라미드 조직을 타고 조금씩 분배되는 형태의 판매망입니다. 어느정도 판매가 이루어진 후,

programmers.co.kr

 

문제 설명

 민호는 다단계 조직을 이용하여 칫솔을 판매하고 있습니다. 판매원이 칫솔을 판매하면 그 이익이 피라미드 조직을 타고 조금씩 분배되는 형태의 판매망입니다. 어느정도 판매가 이루어진 후, 조직을 운영하던 민호는 조직 내 누가 얼마만큼의 이득을 가져갔는지가 궁금해졌습니다. 예를 들어, 민호가 운영하고 있는 다단계 칫솔 판매 조직이 아래 그림과 같다고 합시다.

 민호는 center이며, 파란색 네모는 여덟 명의 판매원을 표시한 것입니다. 각각은 자신을 조직에 참여시킨 추천인에 연결되어 피라미드 식의 구조를 이루고 있습니다. 조직의 이익 분배 규칙은 간단합니다. 모든 판매원은 칫솔의 판매에 의하여 발생하는 이익에서 10% 를 계산하여 자신을 조직에 참여시킨 추천인에게 배분하고 나머지는 자신이 가집니다. 모든 판매원은 자신이 칫솔 판매에서 발생한 이익 뿐만 아니라, 자신이 조직에 추천하여 가입시킨 판매원에게서 발생하는 이익의 10% 까지 자신에 이익이 됩니다. 자신에게 발생하는 이익 또한 마찬가지의 규칙으로 자신의 추천인에게 분배됩니다. 단, 10% 를 계산할 때에는 원 단위에서 절사하며, 10%를 계산한 금액이 1 원 미만인 경우에는 이득을 분배하지 않고 자신이 모두 가집니다.

 예를 들어, 아래와 같은 판매 기록이 있다고 가정하겠습니다. 칫솔의 판매에서 발생하는 이익은 개당 100 원으로 정해져 있습니다.

 각 판매원의 이름을 담은 배열 enroll, 각 판매원을 다단계 조직에 참여시킨 다른 판매원의 이름을 담은 배열 referral, 판매량 집계 데이터의 판매원 이름을 나열한 배열 seller, 판매량 집계 데이터의 판매 수량을 나열한 배열 amount가 매개변수로 주어질 때, 각 판매원이 득한 이익금을 나열한 배열을 return 하도록 solution 함수를 완성해주세요. 판매원에게 배분된 이익금의 총합을 계산하여(정수형으로), 입력으로 주어진 enroll에 이름이 포함된 순서에 따라 나열하면 됩니다.

 

Logic

 판매실적이 있는 원소의 부모를 찾는 과정을 재귀로 구현하였다. 처음엔 .index()로 이름에 대한 인덱스를 찾고, round로 left 값을 반올림 했다. 그러나 round 가 아닌 // 연산자를 써야했으며, .index()는 데이터가 많아질 때(테스트케이스 15개) 커버가 안된다는 것을 알게 되었다. 그래서 딕셔너리로 인덱스를 저장했다. 파이썬은 유용하게도 리스트를 딕셔너리 형태로 만드는 코드가 검색하면 바로 나온다. ㅎㅎ 

 

Tip

- round 와 // 연산자 차이

round : 반올림

// : 나누기 연산 후 소수점 이하의 수를 버리고, 정수 부분의 수만 구함

 

- 리스트 to 딕셔너리

string_list = ['A','B','C']
dictionary = {string : 0 for string in string_list}
print(dictionary)
{'A': 0, 'B': 0, 'C': 0}

 

string_list = ['A','B','C']
dictionary = {string : i for i,string in enumerate(string_list)}
print(dictionary)
{'A': 0, 'B': 1, 'C': 2}

 

 

[python] List to Dict (리스트를 딕셔너리로 변환) 총 정리!!

검색어 : List to Dict List 에서 Dict으로 변환하는 방법에는 여러가지 방법이 있습니다...! string_list = ['A','B','C'] 위와 같은 리스트가 있을때, 딕셔너리로 변환시키는 여러가지 방법들 ..! 1. Dictionary..

security-nanglam.tistory.com

 

Code

def solution(enroll, referral, seller, amount):
    dict = {string : i for i,string in enumerate(enroll)}
    answer = [0] * len(enroll)
    for i in range(len(seller)):
        current_idx = dict[seller[i]]
        answer[current_idx] += amount[i] * 90 
        find_parent(dict, answer, enroll, referral, current_idx, amount[i] * 10)    
    return answer

def find_parent(dict, answer, enroll, referral, current_idx, left):
    parent = referral[current_idx]
    if parent != '-':
        if left// 10 < 1:
            answer[dict[parent]] += left
        else:
            answer[dict[parent]] += left - left//10
            find_parent(dict, answer, enroll, referral, dict[parent], left // 10)

 

런타임 에러 Code

def solution(enroll, referral, seller, amount):
    answer = [0] * len(enroll)
    for i in range(len(seller)):
        current_idx = enroll.index(seller[i])
        answer[current_idx] += amount[i] * 90 
        find_parent(answer, enroll, referral, current_idx, amount[i] * 10)    
    return answer

def find_parent(answer, enroll, referral, current_idx, left):
    parent = referral[current_idx]
    if parent != '-':
        if left// 10 < 1:
            answer[enroll.index(parent)] += left
        else:
            answer[enroll.index(parent)] += left - left//10
            find_parent(answer, enroll, referral, enroll.index(parent), left // 10)