99클럽 코테 스터디 9일차 TIL <Programmers - [level 3] 다단계 칫솔 판매 - 77486>

@developer/takealittle.time·2024년 11월 5일
0

99Club

목록 보기
6/9
post-thumbnail


[문제 링크]

성능 요약

메모리: 20.8 MB, 시간: 127.85 ms

구분

코딩테스트 연습 > 2021 Dev-Matching: 웹 백엔드 개발자(상반기)

문제 설명

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

    (중략)

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

00. 발상

  • 인덱스 값(정수)을 가지고 핸들링 하는 문제가 아닌, '문자열'을 가지고 값들을 핸들링 해야 한다. → 문자열을 인덱스로 사용하기 위해 딕셔너리를 사용해야 한다.

  • 칫솔 판매가 발생 시, 하위 노드에서 상위 노드로 부모를 타고 올라가는 형태이다. → 각 노드에 대해 부모 노드 정보를 가지고 있는 딕셔너리가 필요하다.

  • 특정 seller가 판매를 하면, 해당 판매에 대해 부모 노드를 타고 올라가면서 각 노드에 결괏값을 할당할 함수를 작성한다.
    (종료 조건은 cost >= 1일 때다. / 1 미만인 경우는 계산하지 않겠다고 했으므로)

01. 작성 코드

# 빠른 입력을 위해 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)

02. 고민했던 부분 및 해결

  • 사실, 문제를 깔끔하게 해결하지 못했다.
    '딕셔너리를 사용해야겠다.' 라는 발상까진 떠올렸으나, 이후 삼천포로 빠졌다.
    처음에는 아래와 같은 코드를 작성했었다.
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] 와 같이 특정 배열 순서에 맞게 딕셔너리를 작성하는 코드적인 부분을 알 수 있게 되었다.

03. 회고 및 느낀 점

  • 오늘 문제는 실전이었다면 사실 못 풀었을거다.
    프로그래머스의 기업 기출 문제였던 점이 새로웠고, 확실히 '실제 기출 문제의 벽이 좀 있구나' 싶었다.

  • 오늘 문제는 현실에 있는 특정 문제를 코드로 옮겼다는 감각이 느껴져서 좋았던 것 같다.


99클럽 TIL 개발자취업 코딩테스트준비 항해99

profile
능동적으로 사고하고, 성장하기 위한. 🌱

0개의 댓글

관련 채용 정보