프로그래머스 이모티콘 할인행사 JavaScript
2023년 1월 10일
문제 풀이
2023 KAKAO BLIND RECRUITMENT의 문제, 체감으로는 어제 풀었던 택배 배달과 수거하기 보다 훨씬 쉬운 문제였다.
내 풀이의 핵심 아이디어는 할인율이 10%, 20%, 30%, 40%로 4가지 중 하나로 정해진 것이다. 이 점을 이용해 emoticons 에 모든 경우를 브루트 포스로 탐색한다.
function createQuaternaryNumbers(range, baseLength)
:
- 0 부터
range
-1 까지의 숫자를baseLength
의 길이로 정규화 후 반환 - 모든 값을 탐색할 때 편하게 하기위해 '0'으로 길이 정규화를 한다.
정규화된 4 진수들의 배열 quaternaryNumbersArray
를 하나씩 조회하여 그 값에 따라 할인율을 얻는다.
예를 들어 값이 '0001'인 경우 객체 discount
에 '0001'의 문자 하나씩을 키값으로 값을 얻어 할인율 emoticonDiscountRate
= [10, 10, 10, 20]을 얻는다.
얻어진 할인율 emoticonDiscountRate
을 이용해 해당 할인율에 따른 가입자 수와 판매액을 계산한다.
function subscriberSalesCheck(users, emotions, emotionsCountRate)
:
- 이모티콘의 할인율이 유저의 비율(user[0])과 같을 때에 모두 구매
- 유저의 구매 비용이 유저의 가격(user[1]) 보다 클 경우 판매액을 없애주고 가입자 수를 늘려줌
- 작은 경우엔 구매 비용을 판매액에 더해줌
- [가입자 수, 판매액] 반환
해당 할인율에 따른 [가입자 수, 판매액]의 가입자 수가 subScriber
보다 클 경우 값을 갱신, 가입자 수가 같을 경우 판매액이 salePrice
보다 클 경우에만 값을 갱신해 준다.
solution.js
function solution(users, emoticons) {
const discount = {'0': 10, '1': 20, '2': 30, '3': 40};
const emoticonsLength = emoticons.length;
let RANGE = 4;
let subScriber = 0;
let salePrice = 0;
for (let i = 0; i < emoticonsLength-1; i++) {
RANGE *= 4;
}
const quaternaryNumbersArray = createQuaternaryNumbers(RANGE, emoticonsLength);
for (const quNumber of quaternaryNumbersArray) {
const emoticonDiscountRate = [];
for (let i = 0; i < emoticonsLength; i++) {
emoticonDiscountRate.push(discount[quNumber[i]]);
}
const currentRateResult = subscriberSalesCheck(users, emoticons, emoticonDiscountRate);
if (currentRateResult[0] > subScriber) {
subScriber = currentRateResult[0];
salePrice = currentRateResult[1];
}
else if (currentRateResult[0] == subScriber && currentRateResult[1] > salePrice) {
subScriber = currentRateResult[0];
salePrice = currentRateResult[1];
}
}
return [subScriber, salePrice];
}
// baseLength 로 정규화된 0부터 range-1 까지의 4 진수 문자 배열 반환
function createQuaternaryNumbers(range, baseLength) {
const quaternarys = [];
for (let i = 0; i < range; i++) {
const temp = i.toString(4);
let normalizationTemp = '';
if (temp.length < baseLength) {
for (let j = 0; j < baseLength-temp.length; j++) {
normalizationTemp +='0';
}
}
normalizationTemp += temp;
quaternarys.push(normalizationTemp);
}
return quaternarys;
}
// emoticonsCountRate에 따른 가입자, 판매액 반환
function subscriberSalesCheck(users, emotions, emoticonsCountRate) {
let subScriber = 0;
let salePrice = 0;
for (const user of users) {
let userCost = 0;
for (let i = 0; i < emotions.length; i++) {
if (user[0] <= emoticonsCountRate[i]) {
userCost += (emotions[i] - (emotions[i] * (emoticonsCountRate[i] / 100)));
}
}
(userCost >= user[1]) ? subScriber++ : salePrice += userCost;
}
return [subScriber, salePrice];
}