Algorithms/프로그래머스

[프로그래머스] 메뉴 리뉴얼 (Python 파이썬)

떼닝 2022. 7. 1. 05:01

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:값 으로 넣어주면 되더라.

 

사실 난 아직도 람다함수 잘 쓸 줄 모름

 

오늘도 역시... 문제 좀 제대로 읽자!