[프로그래머스] 메뉴 리뉴얼 (Python 파이썬)
2021 KAKAO BLIND RECRUITMENT Level 2 메뉴 리뉴얼
문제 링크 : https://programmers.co.kr/learn/courses/30/lessons/72411
코딩테스트 연습 - 메뉴 리뉴얼
레스토랑을 운영하던 스카피는 코로나19로 인한 불경기를 극복하고자 메뉴를 새로 구성하려고 고민하고 있습니다. 기존에는 단품으로만 제공하던 메뉴를 조합해서 코스요리 형태로 재구성해서
programmers.co.kr
💡 아이디어
💡 문제를 어떤 방식으로 해결하려 했는지 그 과정을 적어주세요. 초기에 접근한 방법과 최종 접근이 차이가 없으면 한개만 적어도 됩니다.
초기 접근
이번에도 역시나~! 문제를 처음에 잘못 이해했었다. 큰 부분은 아니었지만...
그냥 두 번 이상 나혼 조합이면 다 사용하는 건줄 알았는데 max로 나온 것들을 사용하는 거였다는...!
그거 말고는 접근법에서 크게 달라진 건 없는 것 같다.
일단 들어온 orders에 대해 조합으로 모든 경우를 다 만들어줬다.
그리고 거기서 dictionary 사용해서 값 추가해주고...
각 course 크기? 개수?에 대해 가장 자주 나온 조합 값 구하고
그 값을 가지고 있는 key 값을 return해주는 식으로 만들었다.
크게 어렵진 않았는데 그냥 자잘한 파이썬 기술들이 조금 필요했다.
너무 오랜만에 다시 시작하는 거기도 하고... 해서 검색하느라 시간이 좀 걸렸다.
📋 사용 스펙
💡 어떤 알고리즘 또는 기법을 사용해 문제를 해결했는지 알려주세요
조합 (Python 내장함수 combinations 사용)
👨🏻💻 👩💻 코드
from itertools import combinations
from collections import defaultdict
def solution(orders, course):
answer = []
# course에 들어갈 수 있는 개수에 따라 for문 돌음
for c in course:
# 조합들을 저장할 dictionary의 value값들을 0으로 설정
allcomb = defaultdict(lambda:0)
# 모든 order들에 대해 조합을 진행해주었다.
for o in range(len(orders)):
combli = list(combinations(orders[o], c))
# 나온 조합에 대해 알파벳 순서대로 정렬
# 이미 나왔던 조합일 경우 +1 (사실 아니어도 +1임. defaultdict 이용해서.)
for comb in combli:
ch_comb = list(comb)
ch_comb.sort()
# list를 string 형태로 변환하려고 할 땐 .join 사용
ch_comb = ''.join(ch_comb)
allcomb[ch_comb] += 1
# 각 조합에서 가장 많이 나온 조합이 몇 번 나왔는지 알아내기 위함
maxlen = max(list(allcomb.values()), default=0)
# 최소 두 번 이상 나왔어야 하므로 주어진 조건에서
# max값과 같은 조합들을 최종 answer로 넣어준다.
if maxlen >= 2:
for c in allcomb.keys():
if allcomb[c] == maxlen:
answer.append(c)
answer.sort()
return answer
배운 점
💡 해당 문제를 통해 배운 내용 들을 적어주세요. 어떤 알고리즘, 코딩 기법,자료구조 등을 알게됐다. 문법적 요소도 좋습니다. 크게 없으면 생략해도 좋습니다.
- 조합 (combinations)
from itertools import combinations
combinations(n, r) # nCr 형태로 진행
내가 제일 좋아하는 툴.
전에 부캠 2차 코테 볼 때도 조합 관련한 문제가 나왔었는데, 이 내장함수로 진짜 3분만에 한 문제 풀어버림.
비슷한 예시로 순열은 permutations로 사용하면 된다. 같은 라이브러리 안에 있음. 나중에 한꺼번에 싹 정리해볼게용.
combinations를 사용해서 나온 조합들은 우선 itertools.combinations type을 띄게 된다.
나는 주로 여기에 list를 씌워주고, 그 안에서 요소를 하나씩 꺼내서 돈다.
조합의 결과가 만약 a, b일 경우 이 a, b는 tuple의 type으로 나온다.
tuple은 요소 수정을 못한다는 특징이 있으니, 이 점 유의해서 사용하길 바람!
- list를 string으로 바꿔줄 때 사용하는 join
string_val = ''.join(list_val)
보통의 형변환은 그냥 해당 값 앞에 형변환할 type을 적어주면 되는데, list에서 string으로는 한 번에 변경이 안 되더라.
그럴 때는 join을 사용하면 됨.
.join 앞에 있는 " " 안에 내가 어떤 것을 spliter...?로 사용할 것인지 적어주면 됨.
- defaultdict
from collections import defaultdict
dict_value = defaultdict(int)
dict_value = defaultdict(lambda:0)
보통 처음에 dictionary type을 사용하려면 초기화를 해줘야한다. 안 해주면 오류 뜸.
근데 이렇게 수를 세어주거나 하는 용도로 사용할 때는 처음부터 아예 무슨 값이 key 값으로 들어오든
다 value를 0으로 기본 설정하고 싶을텐데... 그럴 때 사용하는 함수다.
defaultdict의 인자로 내가 어떤 type의 값을 default로 사용할 것인지 넣어주거나,
아니면 특정 값으로 지정하고 싶을 땐 lambda:값 으로 넣어주면 되더라.
사실 난 아직도 람다함수 잘 쓸 줄 모름
오늘도 역시... 문제 좀 제대로 읽자!