본문 바로가기

study/문제 풀이

프로그래머스 메뉴 리뉴얼 2021 카카오 문제 + 삽질과 유용한 라이브러리

 

 

코딩테스트 연습 - 메뉴 리뉴얼

레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다. 기존에는 단품으로만 제공하던 메뉴를 조합해서 코스요리 형태로 재구성해서

programmers.co.kr

문제: 단품 메뉴들로 코스요리를 만들 건데, 손님이 같이 주문하는 메뉴들로 조합을 해서 만든다.

코스 요리를 구성하는 메뉴의 개수는 정해져 있다. 예를 들어 단품 메뉴 3개로 구성된 코스 요리를 만든다면, 3개 이상 주문한 조합에서 가장 많이 주문된 조합을 코스 요리로 만든다. 주문 횟수가 같다면 둘 다 추가한다.(자세한 규칙, 설명은 사이트에서)

 

많이 어려운 문제는 아니었지만, 좋은 메소드, 라이브러리를 몰라 삽질을 했다.

 

문제 풀이 요약

1. 조합되야 하는 메뉴의 수에 따라서 조합을 찾는다.

2. 만약 2개의 메뉴로 조합한다면

3. 손님들이 주문한 메뉴들로 2개 조합을 만든다. -> 여기서 itertools의 combinations 메소드를 사용했다. 조합하려는 메뉴 수 이상을 주문한 손님의 주문에서만 만든다. 예를 들어 2개만 시킨 사람의 주문에서 3개짜리 조합은 찾지 않는다.

4. 가장 많이 주문된 조합을 찾는다.

5. 제시된 메뉴 수에 따라서 반복해서 찾는다.

 

 

 중요한 것은 조합을 만들 때, 오름차순이거나, 순서가 없어야 한다. 수학에서 조합은 당연히 순서가 없지만 itertools.Combinations를 이용하면 순서가 있는 튜플로 조합을 만든다.(a,b 와 b,a가 다른 것으로 세어진다) 그래서 나는 set() 함수를 이용하려 했지만 쉽지 않았다. 그래서 메뉴들을 오름차순으로 바꿨는데 적당한 함수를 몰라 여러줄로 코드를 짰다.

 하지만 sorted()라는 함수를 사용하면 문자열을 오름차순으로 정렬된 문자 리스트로 바꿀 수 있다. 이 함수를 진작에 알았으면 1시간은 절약됐다.

 그래서 조합을 만들기전 주문에 대해서 sorted 함수를 적용한다. 그러면 오름차순의 리스트가 되고 그것으로 조합을 만들면 진짜 조합처럼 세어진다.

 

 

그리고 나는 조합을 만든 뒤 딕셔너리를 이용해 조합들에 대한 주문된 횟수를 셌다. 그러나 이것도 Collection.Counter를 알면 더 짧은 코드로 셀 수 있었다.

 

마찬가지로 제일 많이 주문된 횟수를 셀 때도 직접 for문을 돌려 비교하며 많이 주문된 조합을 찾았지만 Counter 함수가 반환하는 값에 max() 함수를 씌우면 더 짧은 코드로 찾을 수 있었다.

 

상황에 맞는 라이브러리만 잘 사용하면 금방 풀 수 있다. 나는 itertools만 사용했다. Collection.Counter까지 알았다면 더 쉽게 풀 수 있다.

 

삽질 끝!

 

공부한 것 정리