[프로그래머스] Lv2 - 이모티콘 할인행사

김멉덥·2023년 8월 30일
0

알고리즘 공부

목록 보기
100/171
post-thumbnail
post-custom-banner

문제

프로그래머스 2023 KAKAO BLIND RECRUITMENT


코드 구현

from itertools import product

def solution(users, emoticons):
    answer = [0, 0]

    # 할인율에 따라 각 유저의 구매 이모티콘, 금액, + 가입 여부 확인
    # 할인율은 10%, 20%, 30%, 40% 중 하나로 설정됨
    # 최대할인부터 내려가기

    sale = [0.4, 0.3, 0.2, 0.1]

    product_emo = list(product(emoticons, sale))    # (이모티콘, 할인율)의 모든 조합

    n = len(sale)   # 4
    split_product_emo = list(product_emo[i * n : (i + 1) * n] for i in range((len(product_emo) + n - 1) // n))      # 이모티콘 종류 별로 쪼개놓기

    new_product_emo = list(product(*split_product_emo))     # 쪼개놓은 것들 중 하나씩 뽑아서 각 (이모티콘, 할인율) 의 모든 조합을 담은 리스트

    # 해당 리스트를 하나씩 돌면서 판단
    for i in range(len(new_product_emo)):
        emoticon_plus = 0           # 이모티콘 플러스 가입자
        total_emoticon_value = 0    # 총 이모티콘 판매액
        for j in range(len(users)):         # 각 유저가 사게 될 이모티콘 금액을 구하기 (각 유저 구성요소 : [비율, 가격])
            user_spend = 0
            for e in range(len(emoticons)):
                sale_prise = new_product_emo[i][e][0] * (1 - new_product_emo[i][e][1])      # 유저가 사게되는 금액
                if(users[j][0] <= new_product_emo[i][e][1] * 100):      # 만약 '비율'% 이상의 할인이 있는 이모티콘이면 유저가 사게 됨
                    user_spend += sale_prise
            if(user_spend >= users[j][1]):      # 만약 '가격' 이상의 돈을 이모티콘 구매에 사용한다면 이모티콘 플러스 가입
                emoticon_plus += 1
            else:       # 이모티콘 플러스에 가입하지 않으면 총 이모티콘 가격 판매액만 업데이트
                total_emoticon_value += user_spend

        if(answer[0] < emoticon_plus):      # 이모티콘 플러스 가입자를 최대한 늘리는게 우선 목표이므로, 만약 더 많은 가입자를 얻은 답이 나오면 answer 변경
            answer = [emoticon_plus, total_emoticon_value]
        if (answer[0] == emoticon_plus):    # 그러나 같은 조건이라면, 다음 목표인 판매액 금액으로 비교
            if(answer[1] < total_emoticon_value):       # 이모티콘 플러스 가입자가 동일할 때, 판매액이 더 높다면 answer 변경
                answer = [emoticon_plus, total_emoticon_value]

    return answer

풀이

  • product()사용과 리스트를 일정한 크기별로 쪼개는걸 검색하여 풀었었다.
  • 리스트를 일정한 크기별로 쪼개어 각 요소를 리스트로 만드는 법
    n = 쪼갤 요소 개수
    result = list(리스트[i * n : (i + 1) * n] for i in range((len(리스트) + n - 1) // n))
  • 우선 각 이모티콘에 대한 (이모티콘 금액, 할인율) 의 모든 조합을 구한다.
  • for문으로 해당 조합 요소들을 다 돌면서 → 각 유저의 조건 별 이모티콘 소비 금액을 구하고 → 이모티콘 플러스 가입자와 총 판매액을 계속 업데이트 해준다.
  • 이모티콘 플러스 가입자를 최대로 하는게 우선 목표이므로 → 만약 이모티콘 플러스 가입자가 더 큰 값이 나온다면 answer 변경을 해준다.
    • 만약 이모티콘 플러스 가입자 현재 answer에 있는 가입자 값과 동일하다면 → 두번째 목표인 가격으로 비교하여 answer를 변경해준다.

What I learned

  • (이모티콘 금액, 할인율) 을 묶으려고 하다보니 복잡해졌다.
  • 할인율은 10%, 20%, 30%, 40%로 정해져있으니 (할인율, 할인율) 의 조합으로 구한 뒤, for문을 돌아서 이모티콘 금액으로 각 할인율을 적용하여 비교하면 되는데 괜히 복잡하게 길을 돌아왔다 !
    • 그리고 이렇게 짜면 좀 더 효율성 측면에서 돌리는 시간을 줄일 수 있게된다.
  • 깔끔한 정답 코드
    from itertools import product
    
    def solution(users, emoticons):
        E = len(emoticons)
        result = [0, 0]
        percents = (10, 20, 30, 40)
        prod = product(percents, repeat=E)
    
        for p in prod:
            prod_members, prod_price = 0, 0
            for buy_percent, max_price in users: 
                user_price = 0
                for item_price, item_percent in zip(emoticons, p):
                    if item_percent >= buy_percent:
                        user_price += item_price * (100-item_percent) * 0.01
    
                if user_price >= max_price:
                    prod_members += 1
                else:
                    prod_price += user_price
    
            result = max(result, [prod_members, prod_price])
    
        return result

▶️ 두개 이상의 리스트에서 모든 조합 구하기 list(product(*items))
참고 : https://ourcstory.tistory.com/414

from itertools import product

items = [['a', 'b', 'c,'], ['1', '2', '3', '4'], ['!', '@', '#']]
list(product(*items))

# [('a', '1', '!'), ('a', '1', '@'), ('a', '1', '#'), ('a', '2', '!'), ('a', '2', '@'), ('a', '2', '#'), ('a', '3', '!'), ('a', '3', '@'), ('a', '3', '#'), ('a', '4', '!'), ('a', '4', '@'), ('a', '4', '#'), ('b', '1', '!'), ('b', '1', '@'), ('b', '1', '#'), ('b', '2', '!'), ('b', '2', '@'), ('b', '2', '#'), ('b', '3', '!'), ('b', '3', '@'), ('b', '3', '#'), ('b', '4', '!'), ('b', '4', '@'), ('b', '4', '#'), ('c,', '1', '!'), ('c,', '1', '@'), ('c,', '1', '#'), ('c,', '2', '!'), ('c,', '2', '@'), ('c,', '2', '#'), ('c,', '3', '!'), ('c,', '3', '@'), ('c,', '3', '#'), ('c,', '4', '!'), ('c,', '4', '@'), ('c,', '4', '#')]
profile
데굴데굴 뚝딱뚝딱 개발기록
post-custom-banner

0개의 댓글