코딩테스트/카카오 기출

카카오 2021 메뉴 리뉴얼 파이썬 풀이, 코드 / 파이썬은 풀만한 문제

RyanKwon 2022. 1. 30. 12:33
728x90

깃허브에서 코드만 볼 분은 링크 눌러주세요~

 

문제 설명 ㄱㄱ (Lv 2)

 

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

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

programmers.co.kr

orders에 여러 알파벳의 조합이 들어오는데, course에 써있는 크기만한 부분집합들을 만들어야 한다. 이 때 그 부분집합들은 orders에서 최소 2회씩 중복되어야 한다. 그리고 만약 2개 크기의 부분집합을 만들 때 여러 부분집합이 나온다면 그 중 가장 여러번 중복된 것들을 result에 알파벳순으로 리턴하면 된다.

 

 

문제 해설

 

1. course에 있는 숫자를 사용해 order에서 부분집합 크기만큼 combinations를 만들어서 set에 넣는다.

2. orders의 모든 order에 대해 1번을 반복하고, 아직까지 한번만 나온 조합, 그리고 최소 2회 나온 조합을 따로 구성해서 중복된 경우와 그렇지 않은 경우의 조합을 나눈다. (이 때 set, 논리연산자를 사용한다)

3. course에서 '하나의 부분집합 크기'에 대해 최소 2회 나온 조합 리스트를, collections Counter의 most_common을 사용해서 가장 많이 나온 조합을 확인한다.

4. 같은 횟수만큼 나온 경우가 있을 수 있으므로 Counter에서 추가 부분 집합들을 사용한다.

5. 각 course에 대해 위를 반복한다.

 

 

주의할 점

 

사실 위에만 읽어봐도 다 풀 수 있어서 .. 이 부분은 사소한 구현이 어려운 경우에만 읽어보길 추천한다.

 

1. combinations를 만들면 이런 경우가 생긴다. combinations는 (0, 1)을 만들면 (1, 0)는 만들지 않기 때문에 ['XY']와 ['YX']가 있으면 길이 2짜리 부분집합을 만드는 경우에 ('X', 'Y'), ('Y', 'X')로 각각 나오게 되고 이는 set에서 같은 부분집합으로 취급을 안해준다 ㅠㅠ.. 이 부분은 permutations로 해결하면 되지 않을까 싶겠지만 그렇게 하면  ('X', 'Y'), ('Y', 'X') 둘 다를 답으로 인정해버리는 경우가 생긴다. 지금은 길이가 2짜리라 2배지만 길이가 3짜리, 4짜리 부분집합도 있다는걸 생각해보면 정말 그 조합 모두를 답으로 인정해버리게 됨. 그래서 permutations를 쓰면 안된다. 대신 간단하게, 맨 처음 시작하는 과정에서 orders를 sort해버리면 ['XY'] ['YX']는 ['XY']하나가 되니까 부분집합도 알파벳 순서로만 나오게 된다. 이렇게 하면 문제 해결.

 

2. Counter를 쓰면.. 솔직히 쉬워질 것 같은 느낌이 들겠지만 딱히 그렇지도 않다. Counter를 쓰면 이렇게 되는데....

        count = collections.Counter(tmp_answer).most_common() #중복 횟수가 저장된 dict
        if not count: #없으면 패스
            continue
        answer.append(''.join(count[0][0])) #맨 앞 값 넣고
        for i in range(1, len(count)):
            if count[0][1] == count[i][1]: #같은 횟수인 친구들도 answer에 넣기
                answer.append(''.join(count[i][0]))

물론 더 쉽게 짤 수도 있을 것 같지만.. count안에 인덱스 설정도 그렇고 은근 안 써본 사람이 쓰기는 생각보다 귀찮은게 most_common함수이다 .. 물론 어제 짤때는 뭔가 머리가 안굴러서 남의 풀이를 살짝 sneak했는데 most_common을 썻길래 나도 썻지만.. 지금 생각해보면 그냥 dict로 푸는게 더 간단할 것 같기도. 가령..

        bc = collections.Counter(tmp_answer) #Counter만 해주고
        if not bc:
            continue
        de = {}
        max_key = 0
        for key in bc: #갯수에 따라 정리하고 key와 value를 바꾸는 과정
            if bc[key] not in de:
                de[bc[key]] = []
            de[bc[key]].append(''.join(key))
            max_key = max(max_key, bc[key]) #가장 많은 수를 미리 저장 후
        answer.extend(de[max_key])  #answer에 해당 value 넣기

음.. 다시 보니까... 이게 더 어려운 것 같기도...ㅋㅋㅋㅋㅋ근데 나는 뭐랄까 굳이 다른 함수에 없는 모듈을 쓰는 경우는 꼭 다시 구현해봐야 직성이 풀려서 .. 아무튼 이렇게 풀면 된다.

 

 

 

728x90