새소식

Programmers

[Programmers] 메뉴 리뉴얼 문제 - (javascript)

  • -
728x90
문제 이름 :  메뉴 리뉴얼

 

<<< 문제 내용 >>>

 

function solution(orders, course) {
  let menu = {};

    // 메뉴들을 조합으로 가져오는 함수
  function combination(order, idx, len, prev) {
    if (prev.length === len) {
      let cur_key = prev.sort().join("");
      if (cur_key in menu) {
        menu[cur_key] += 1;
      } else menu[cur_key] = 1;
      return;
    }

    for (let i = idx; i < order.length; i++) {
      combination(order, i + 1, len, [...prev, order[i]]);
    }
  }

    //orders를 처음부터 끝까지 반복하면서
    //course도 처음부터 끝까지 반복된다.
    //그렇게 course 수에 맞는 조합들을 menu에 다 집어넣는다.
  orders.map((order) => {
    course.map((num) => combination(order, 0, num, []));
  });

    //result를 뽑아내기 위한 배열
  let answer = [];
    
    //course의 수에 맞춰 메뉴를 가져오면서    
  for (let i of course) {
      /* menu의 경우 dictionary지만 Object.entries를 사용하면서
       ["AB", 1] 와 같은 배열로 추려지게된다.
       이를 위해 course 길이인것만, 또 손님이 2번이상 시킨것만 골라서
       그 중 최대 값이 몇인지를 갱신해준다.(max는 최대값인 배열만 뽑기위해)
       그리고 마지막으로는 return으로 course와 "AB"와 같은 길이가 같은 것만
       filter로 걸러온다. */
    let max = 0;
    let temp = Object.entries(menu).filter(([k, v]) => {
      if (max < v && k.length === i && v > 1) max = v;
      return k.length === i;
    });

      /* 마지막으로 아까 구했던 max값을 이용해 filter로 값을 다 가져온다.
       현재 배열의 길이가 course만큼인 배열만 존재하고 그 중 max값은
       중복이 존재할 수 있기 때문에, filter로 가져오며 마지막엔 answer에
       push 해주면 된다. */
    temp = temp
      .filter(([k, v]) => {
        return v === max;
      })
      .map(([k, v]) => answer.push(k));
  }
    
    // 사전순 정렬이 문제 조건.
  return answer.sort();
}

* 재귀를 이용한 조합만 잘하면 나머지는 구현에 가까운 문제였다.

역시나 재귀에 약해서.. 머릿속에서 흐름을 생각하고 구현해도 안되었고,

손으로 그려가며 구현해도 안되어서 검색해보았고, 여러 방식중에 위의 방식이 내 입맛에 가장 맞았다.

 

이 문제의 코드는 생각보다 filter와 map 등의 깊이가 깊어서 주석으로 설명을 추가했다.

 

 

 

 

 

도움이 되셨다면 공감 부탁드립니다.

Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.