2024년 4월 17일 수요일

2023 KAKAO BLIND RECRUITMENT 이모티콘 할인행사

문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/150368

파이썬 소스: https://bit.ly/3TXgolX

 

이모티콘 플러스 서비스에 가입하는 것이 우선이고, 그 다음 조건이 이모티콘을 적게 할인을 해서, 최대한 비싸게 파는 것입니다. 각 사용자 별로 구매하는 할인율이 다르기 때문에, 모든 경우의 수를 다 계산해 보는 방법 밖에 없습니다.

이 문제의 답을 구하기 위해서는, 모든 users에게, 모든 이모티콘의 할인율의 가능성을 모두 적용해서 계산해 봐야 문제의 답을 구할 수 있습니다.

 문제에서는 이모티콘의 할인율을 아래와 같이 설명하고 있습니다.

이모티콘마다 할인율은 다를 수 있으며, 할인율은 10%, 20%, 30%, 40% 중 하나로 설정됩니다.

 

이모티콘의 할인율은 4가지입니다. 10% 20% 30% 40%

첫번째 이모티콘이 10% 할인율일 때, 두번째 이모티콘의 할인율도 10%일 수 있습니다. 위의 문제 설명을 보면, 조끔 헷갈려서, 이모티콘의 할인율이 모두 달라야 한다고 생각할 수 있지만, 아닙니다. 정확하게 다를 수 있으며라고 했기 때문에, 같을 수도 있는 것입니다.

 조금 다른 관점에서 보면, 이모티콘의 할인율이 모두 달라야 한다면, 이모티콘의 종류는 4개를 넘을 수 없습니다. 하지만 문제에서는 이모티콘의 종류가 7개 까지라고 설명하고 있기 때문에, 이모티콘의 할인율이 같을 수도, 다를 수도 있다고 보는 것이 문제를 올바르게 이해한 것입니다.

입출력 예 첫번재 처럼, 이모티콘의 개수가 2개라고 한다면 가능한 이모티콘의 할인율은 아래와 같습니다. 튜플의 인덱스 0번이 첫번째 이모티콘의 할인율이고, 인덱스 1번이 두번째 이모티콘의 할인율입니다. 16가지입니다.

(10, 10), (10, 20), (10, 30), (10, 40),

(20, 10), (20, 20), (20, 30), (20, 40),

(30, 10), (30, 20), (30, 30), (30, 40),

(40, 10), (40, 20), (40, 30), (40, 40)

 

위와 같은 경우를 중복순열이라고 하구요, 파이썬에서는 product()함수를 사용해서 중복순열을 구할 수 있습니다. 중복순열의 한 원소의 길이는 이모티콘의 종류의 수입니다.

def solution(users: List[List[int]], emoticons: List[List[int]]):
    discounts =
list(product([10, 20, 30, 40], repeat=len(emoticons)))

 

이제 모든 가능한 이모티콘의 할인율을 구했으니, 각 할인율 마다, user가 이모티콘 플러스 서비스에 가입하는지, 이모티콘을 할인된 가격에 구매하는지 계산해볼 차례입니다.

for discount in discounts:
    local_subscriber =
0
   
local_sell = 0

   
for user in users:
        local_user_subscriber =
False
       
local_user_sell = 0
       
user_dis, user_sell_limit = user

튜플 discount가 가리키는 각 이모티콘의 핳인율을 각 user에게

튜플 discount에 따른 이모티콘 플러스 서비스 가입자수 local_subscriber

튜플 discount에 따른 이모티콘 구입의 총함 local_sell

해당 user가 이모티콘 플러스 서비스에 가입하는지 여부 local_user_subscriber

해당 user가 구매한 이모티콘의 가격 local_user_sell

해당 user는 이 할인율 이하이면 이모티콘을 구입하는 할인윻 user_dis

해당 user가 구입가능한 최대 이모티콘 가격의 합 user_sell_limit

이제 각 user가 어떻게 행동하는지, 튜플 discount에서 제시된 할인율에 따라서, 알아볼 차례입니다.

for idx in range(len(emoticons)):
    emo_dis, emo_price = discount[idx], emoticons[idx]
   
if user_dis <= emo_dis:
        local_user_sell += (emo_price * (
100 - emo_dis) // 100)

   
if local_user_sell >= user_sell_limit:
        local_user_subscriber =
True
        break

이모티콘의 할인율이 원하는 할인율의 이하라면, 할인된 가격으로 이모티콘을 구매하고, 구매한 가격을 local_user_sell 에 저장합니다.

이모티콘을 구해한 가격의 합이 user_sell_limit의 이상이면, 해당 user는 이모티콘을 구매하지 않고, 이모토킨 플러스 서비스에 가입합니다. 이모티콘 플러스 서비스에 가입하면, 더 이상 이모티콘을 구매하지 않기 때문에, break로 루프를 나오게 됩니다.

if local_user_subscriber:
    local_subscriber +=
1
else:
    local_sell += local_user_sell

이모티콘 플러스 서비스에 가입했다면, local_subscriber 1증가시켜줍니다. 아니라면, 구매한 이모티콘의 가격의 합을 local_sell에 더해줍니다.

 

한번 discount에 대한 루프가 끝날 때 마다, 모든 유저들이 이모티콘 플러스 서비스에 가입하는지, 얼마나 이모티콘을 구매하는대 사용했는지 알 수 있습니다.

answer.append([local_subscriber, local_sell])
answer.sort(
reverse=True)
answer = [answer[
0]]

리스트 answer에 이모티콘 플러스 가입자 수와, 이모티콘 판매가격의 합을 appen()메서드로 넣어 줍니다. 첫 루프라면, answer 1개의 원소만 들어 있기 때문에, sort()하는 의미가 없지만, 두번재 루프 부터는 2가의 원소중에 sort(reverse=True)로 큰 값이 앞에 오게 됩니다.

따라서 answer[0]만 다시 answer에 넣어 주면, 문제에서 원하는 최대값이 answer[0]에 들어 있게 됩니다.

 

궁금한 내용은 댓글, 이메일(coding.data.pul@gmail.com)로 보내주세요.

코데풀 유튜브 구독 부탁드립니다.

https://www.youtube.com/@codapul

 

전체 코드는 아래에 있습니다.

from typing import List
from itertools import product


def solution(users: List[List[int]], emoticons: List[List[int]]):
    discounts =
list(product([10, 20, 30, 40], repeat=len(emoticons)))
    answer = []

   
for discount in discounts:
        local_subscriber =
0
       
local_sell = 0

       
for user in users:
            local_user_subscriber =
False
           
local_user_sell = 0
           
user_dis, user_sell_limit = user

           
for idx in range(len(emoticons)):
                emo_dis, emo_price = discount[idx], emoticons[idx]
               
if user_dis <= emo_dis:
                    local_user_sell += (emo_price * (
100 - emo_dis) // 100)

               
if local_user_sell >= user_sell_limit:
                    local_user_subscriber =
True
                    break

            if
local_user_subscriber:
                local_subscriber +=
1
           
else:
                local_sell += local_user_sell

        answer.append([local_subscriber, local_sell])
        answer.sort(
reverse=True)
        answer = [answer[
0]]

   
return answer[0]

 

 

댓글 없음:

댓글 쓰기