Python/Algorithm

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

언킴 2023. 9. 2. 15:34
반응형

이번 문제는 2023 KAKAO BLIND RECRUITMENT 에서 출제된 문제다. 프로그래머스 기준 난이도 Level 2에 해당하는 문제로, 완전탐색(Brute-Force Search, BFS) 문제로 접근할 수 있다. 

 

문제 설명

요약을 하자면, 카카오톡 이모티콘 플러스 서비스 가입자 수를 최대로 늘리는 것이 첫 번째 목적이고, 이모티콘 판매액을 최대한 늘리는 것이 두 번째 목적이다.  n명의 카카오톡 사용자에게 m개의 이모티콘을 할인해서 판매하는데, 이때 할인율은 10%, 20%, 30%, 40% 중 하나로 설정된다. 각 할인율에 따라 목적1, 목적2를 달성하는 값을 출력하는 문제다.

 

from itertools import product

def solution(users, emoticons):
    emg_len = len(emoticons)
    answer = [0, 0]
    
    for p in product(range(10, 41, 10), repeat=emg_len):
        counts, money = 0, 0
        
        for i in range(len(users)):
            user_discount = users[i][0]
            total = 0

코드를 해석하자면, 먼저 user_discount는 사용자가 몇 퍼센트 할인일 때 구매하는지에 대한 정보를 담고 있다. product로 된 부분은 이모티콘의 모든 할인율에 대한 조합을 나타낸다. 예를 들어, 이모티콘이 두 개인 경우 (10, 10) 씩 할인한 것부터 (40, 40)까지 할인한 모든 조합이 들어간 것이다. 

         
            for j in range(len(p)):
                if user_discount <= p[j]:
                    total += emoticons[j] * (100 - p[j]) * 0.01
            
            if total >= users[i][1]:
                counts += 1
            
            else:
                money += total

그런 다음, 유저 할인율보다 이모티콘의 할인율이 크면, 구매해서 total이라는 변수에 집어넣는다. 만약 사용자가 구매한 이모티콘의 총 구매 가격이 사용자가 생각한 가격보다 큰 경우 counts += 1 즉, 이모티콘 플러스를 구매하는 것이다. 만약 아니라면, else 구문으로 빠져서 그냥 돈으로 구매하는 형태로 진행된다. 

        if answer[0] > counts:
            continue
        
        if answer[0] == counts and answer[1] > money:
            continue
            
        answer = [counts, money]
    
    return answer

마지막 하단에 if 문으로 된 두 개의 부분은 목적 1, 목적 2에 대한 최댓값을 찾기 때문에 기존 값보다 작은 경우 continue하는 형태로 구문을 짤 수 있다. 

 

전체 코드는 다음과 같다. 

from itertools import product

def solution(users, emoticons):
    emg_len = len(emoticons)
    answer = [0, 0]
    
    for p in product(range(10, 41, 10), repeat=emg_len):
        counts, money = 0, 0
        for i in range(len(users)):
            user_discount = users[i][0]
            total = 0
            
            for j in range(len(p)):
                if user_discount <= p[j]:
                    total += emoticons[j] * (100 - p[j]) * 0.01
            
            if total >= users[i][1]:
                counts += 1
            
            else:
                money += total 
                
        if answer[0] > counts:
            continue
        
        if answer[0] == counts and answer[1] > money:
            continue
            
        answer = [counts, money]
    
    return answer