2024년 4월 30일 화요일

2021 KAKAO BLIND RECRUITMENT 메뉴 리뉴얼 Lv. 2

문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/72411

파이썬 소스: https://bit.ly/3JGBTCG

 

이 문제를 풀이하는데 놓치기 쉬운 부분이 아래 문장입니다.

만약 가장 많이 함께 주문된 메뉴 구성이 여러 개라면, 모두 배열에 담아 return 하면 됩니다.

위의 문장의 의미를 잘 이해하려면, 입출력 예 #2번의 결과를 잘 살펴보아야 합니다.

AD가 세번, CD가 세번 주문 되었습니다. 그리고 AB도 두번 주문 되었습니다.

하지만, 함께 주문된 2개의 메뉴중에서, 가장 많이 주문된 횟수는 세번입니다. 따라서, AD, CD만 답에 포함되고, AB는 두번 주문 되었으므로, 답에 포함되지 않습니다.

위의 문제설명을 좀더 쉽게 바꿔 말하면, 함께 주문된 메뉴의 개수가 같은 것 중에서, 가장 많이 함께 주문된 메뉴만 답에 포함된다고 할 수 있습니다.

 

문제에서 주어지는 orders는 스트링을 가지는 리스트 변수입니다.

def solution(orders: List[str], course: List[int]):
    orders = [
list(order) for order in orders]
   
for order in orders:
        order.sort()

변수 order 값이 ABC라고 가정하고, course리스트에 2가 들어 있다면, A, B, C를 가지고 크기 2의 조합을 구해야 합니다. 따라서, 조합을 구하기 쉽도록, 미리 스트링을 리스트로 변환합니다. 조합의 순서도 알파벳순서를 따르기  위해서, sort()를 해주겠습니다.

 

for length in course:
    candidate_menus = defaultdict(
int)
    mx =
0

리스트 course에서 조합의 길이를 하나씩 꺼내면서 루프를 실행합니다.

딕셔너리 candidate_menus는 함께 주문된 메뉴를 키로 사용하고, 함께 주문된 메뉴가 몇번 주문되었는지를 값으로 가지는 딕셔너리입니다.

변수 mx는 함께 주문된 메뉴중에서 가장 많이 주문된 횟수를 저장합니다.

 

for order in orders:
   
if length <= len(order):
       
for menu in list(combinations(order, length)):
            candidate_menus[
tuple(menu)] += 1

       
mx = max(list(candidate_menus.values()))

조합의 길이 보다, order의 길이가 크거나 같으면, length의 길이를 가지는 조합을 리스트 order로부터 만들 수 있습니다. 조합을 만들어서, 조합의 각 아이템(menu)는 리스트입니다. 딕셔너리의 키로 사용하기 위해서, tuple로 변환하구요, 해당 함께 주문된 메뉴의 횟수에 +1을 합니다.

딕셔너리 candidate_menus에 들어있는 함께 주문된 메뉴들 중에서 가장 많이 주문된 값을 max()함수를 사용해서 찾고, mx에 저장합니다.

 

if mx <= 1:
   
continue

변수 mx 1보다 작거나 같다면, 함께 주문된 메뉴중에서 2번 이상 중복해서 주문된 메뉴가 없다는 뜻 이기 때문에, 답에 포함할 수 있는 함께 주문된 메뉴가 없습니다. continue하여 다음 조합의 길이로 이동합니다.

 

변수 mx의 값이 1보다 크다면,

for key in candidate_menus:
   
if candidate_menus[key] == mx:
        answer.append(
''.join(list(key)))

딕셔너리 candidate_menus에 포함된어 있는 모든 함께 주문된 메뉴들 중에서, 주문된 횟수가 mx와 같인 메뉴들을 답(리스트 answer)에 추가합니다.

 

answer.sort()
return answer

마지막으로, 함께 주문된 메뉴들이 알파벳 순서가 되도록 sort() 하고, 리스트 answer를 리턴합니다.

 

궁금한 문제, 내용은 댓글, 이메일(coding.data.pul@gmail.com)로 보내주세요.

코데풀 유튜브 구독 부탁드립니다.

https://www.youtube.com/@codapul

 

전체 코드는 아래에 있습니다.

from typing import List
from itertools import combinations
from collections import defaultdict


def solution(orders: List[str], course: List[int]):
    orders = [
list(order) for order in orders]
   
for order in orders:
        order.sort()

    answer = []

   
for length in course:
        candidate_menus = defaultdict(
int)
        mx =
0

       
for order in orders:
           
if length <= len(order):
               
for menu in list(combinations(order, length)):
                    candidate_menus[
tuple(menu)] += 1

               
mx = max(list(candidate_menus.values()))

       
if mx <= 1:
           
continue

        for
key in candidate_menus:
           
if candidate_menus[key] == mx:
                answer.append(
''.join(list(key)))

    answer.sort()
   
return answer

 

 

2024년 4월 28일 일요일

2021 KAKAO BLIND RECRUITMENT 신규 아이디 추천 Lv. 1

문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/72410

파이썬 소스: https://bit.ly/3JBPP0Q

 

문제에서 주어지는 7단계를 차근차근 구현하면 풀 수 있는 문제입니다.

1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.

id = new_id.lower()

스트링 new_id lower()메서드를 사용해서, 모두 소문자로 치환했습니다.

 

2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
id: List = list(id)
new_id = []
for c in id:
   
if c in '0123456789abcdefghijklmnopqrstuvwxyz-_.':
        new_id.append(c)
id =
''.join(new_id)

스트링 id에서 한글자씩 for 루프를 돌겠습니다.

알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) new_id 리스트에 저장됩니다.

리스트 new_id를 스트링 idjoin()메서드를 사용해서 변환합니다.

 

3단계 new_id에서 마침표(.) 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
id = re.sub(r'\.+', '.', id)

스트링 id에 있는 ‘.’중에서 1개 이상 연속된 ‘.’은 한 개의 ‘.’으로, 치환했습니다.

 

4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
if len(id) > 0 and id[0] == '.':
    id = id[
1:]

if len(id) > 0 and id[len(id) - 1] == '.':
    id = id[:-
1]

스트링 id의 길이가 0보다 클 때만, 맨 앞이나, 맨 뒤에 있는 ‘.’을 제거합니다.

 

5단계 new_id가 빈 문자열이라면, new_id "a"를 대입합니다.
if id == '':
    id =
'a'

스트링 id가 길이가 0인 스트링이면, ‘a’를 대입합니다.

 

6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다. 만약 제거 후 마침표(.) new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
if len(id) >= 16:
    id = id[:
15]

if id[len(id) - 1] == '.':
    id = id[:-
1]

스트링 id의 길아가 16이상이면, 15개의 문자로 잘라 줍니다.

마지막에 ‘.’이 있는 경우에도 마지막 ‘.’을 제거 해줍니다.

 

7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
while len(id) <=2:
    id += id[
len(id)-1]

길이가 2이하인 동안 while루프가 실행 되구요, 길이가 3이 되면 루프가 끝나게 됩니다.

 

여기까지 1단계부터 7단계까지 모두 구현을 해 보았습니다.

궁금한 문제, 내용은 댓글, 이메일(coding.data.pul@gmail.com)로 보내주세요.

코데풀 유튜브 구독 부탁드립니다.

https://www.youtube.com/@codapul

 

전체 코드는 아래에 있습니다.

import re
from typing import List


def solution(new_id: str):
   
# 1단계
   
id = new_id.lower()

   
# 2단계
   
new_id = []
   
for c in id:
       
if c in '0123456789abcdefghijklmnopqrstuvwxyz-_.':
            new_id.append(c)
    id =
''.join(new_id)

   
# 3단계
   
id = re.sub(r'\.+', '.', id)

   
# 4단계
   
if len(id) > 0 and id[0] == '.':
        id = id[
1:]

   
if len(id) > 0 and id[len(id) - 1] == '.':
        id = id[:-
1]

   
# 5단계
   
if id == '':
        id =
'a'

   
# 6단계
   
if len(id) >= 16:
        id = id[:
15]

   
if id[len(id) - 1] == '.':
        id = id[:-
1]
       
   
# 7단계
   
while len(id) <=2:
        id += id[
len(id)-1]

   
return id