PS/Programmers

Programmers / Level 2 / 할인 행사 / JS

KimMinJun 2023. 1. 28. 18:57

< 문제 바로가기 >

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

/**
 * 원하는 제품명과 제품수량들이 담긴 각각의 리스트를 받아서  
 * key:제품명, value:제품수량을 가지는 Map으로 초기화 하는 함수
 * 
 * @param {string[]} want 원하는 제품명들이 담긴 리스트
 * @param {number[]} number 원하는 제품수량들이 담긴 리스트
 * @param {Map} wantCountMap 초기화할 Map
 */
function initWantCountObject(want, number, wantCountMap) {
  const WANT_LIST_LENGTH = want.length;

  let [wantProduct, wantCount] = ['', 0];
  for (let i = 0; i < WANT_LIST_LENGTH; i += 1) {
    [wantProduct, wantCount] = [want[i], number[i]];

    wantCountMap.set(wantProduct, wantCount);
  }
}

/**
 * start부터 end일까지 할인 품목을 Map의 key값으로 가지는 value를 마이너스 시키는 함수
 * 
 * @param {Map} wantCountMap key:제품명, value:제품수량을 가지는 Map
 * @param {string[]} discount 할인 품목 리스트
 * @param {number} start 회원 등록 일
 * @param {number} end 회원 자격이 끝나는 일
 */
function updateMinusCount(wantCountMap, discount, start, end) {
  let discountProduct = '';
  for (let i = start; i < end; i += 1) {
    discountProduct = discount[i];

    if (wantCountMap.has(discountProduct)) {
      wantCountMap.set(discountProduct, wantCountMap.get(discountProduct) - 1);
    }
  }
}

/**
 * 조건을 만족하는 회원 등록이 가능한 날인지 판단해서 boolean 값을 반환하는 함수
 * 
 * @param {Map} wantCountMap 제품 수량을 모두 업데이트
 * @returns {boolean} 회원 등록이 가능한 날이면 true 반환 
 */
function isPossibleDay(wantCountMap) {
  let result = 0;

  result = [...wantCountMap.values()].every((count) => count <= 0);

  return result;
}

function solution(want, number, discount) {
  const MEMBERSHIP_PERIOD = 10;
  const MAX_START_DAY = discount.length - MEMBERSHIP_PERIOD;
  let result = 0;
  let wantCountMap = new Map();

  let [start, end] = [0, 0];
  for (let i = 0; i <= MAX_START_DAY; i += 1) {
    [start, end] = [i, i + MEMBERSHIP_PERIOD];

    initWantCountObject(want, number, wantCountMap);
    updateMinusCount(wantCountMap, discount, start, end);

    if (isPossibleDay(wantCountMap)) {
      result += 1;
    }
  }

  return result;
}

 

크게 어렵지 않은 문제였다.

처음엔 Object를 이용하려다가, Map 자료구조를 이용했다.

 

원하는 제품명을 key로 가지고, 그 제품을 원하는 수량을 value로 가지는 Map을 만들었다.

그리고 회원 자격은 10일동안만 유지되기 때문에 회원 등록일을 하루씩 늘려가며 이 날에 회원 등록을 했을 때 모든 조건을 충족할 수 있는지 검사했다.

 

검사할때 every() 배열 메소드를 사용했는데, 배열의 모든 element가 조건을 모두 충족하면 true, 하나라도 충족하지 않는다면 false를 반환하기 때문에 이 문제에 적합했다.

여기서 조건엔 Map의 value가 0 이하인것을 판단하는 조건을 걸어주었는데, 이 조건을 걸어준 이유가 할인 품목 리스트를 순회하면서 Map에 있는 품목일 경우 그 value값을 1씩 빼주었기 때문이다.

따라서 value값이 0이하가 된다면 자기가 원하는 수량은 모두 살 수 있다는 뜻이므로 0이하를 판단하는 조건을 걸어주었다.

 

다른 사람들의 코드를 보면 간단히 한 코드도 많은데, 최대한 기능을 나누어서 함수를 작성해보았다.

나름 만족스러운 코드이다!