https://school.programmers.co.kr/learn/courses/30/lessons/159994
프로그래머스 코딩테스트 1단계에 수록되어 있는 '카드 뭉치' 문제를 풀었습니다. 다른 사람의 풀이와 비교해보니 제가 조금 독특하게 풀었더라구요. 제 코드가 좀 지저분하긴 하지만 남들과 다른 아이디어로 푼 게 마음에 들어 sorted 문법 정리할 겸 풀이과정을 작성해보고자 합니다.
우선 제출한 답안은 다음과 같습니다.
def solution(cards1, cards2, goal):
cards1_sorted = sorted(enumerate(cards1),
key = lambda x: (goal.index(x[1]) if x[1] in goal else len(goal) + 1))
cards2_sorted = sorted(enumerate(cards2),
key = lambda x: (goal.index(x[1]) if x[1] in goal else len(goal) + 1))
index_1 = [index for index, value in cards1_sorted]
index_2 = [index for index, value in cards2_sorted]
if index_1 != sorted(index_1) or index_2 != sorted(index_2):
return "No"
else:
return "Yes"
하나씩 쪼개어 정리해 보겠습니다.
테스트케이스의 2번째 예시로 설명해 보겠습니다.
1. 먼저, cards1과 cards2에 enumerate() 함수를 이용해서 (인덱스, 카드)값이 되도록 만들어 줍니다. list()함수를 씌워 결과값을 눈으로 확인하면 다음과 같습니다.
cards1 = ["i", "water", "drink"]
cards2 = ["want", "to"]
goal = ["i", "want", "to", "drink", "water"]
list(enumerate(cards1))
# [(0, 'i'), (1, 'water'), (2, 'drink')]
list(enumerate(cards2))
# [(0, 'want'), (1, 'to')]
2. 저는 이렇게 추출한 이뉴머레이트 결과값을, sorted()를 이용해서 정렬을 해줄 거에요. 이 때 정렬을 해 주는 기준으로 goal을 넣어 주어서, goal에 있는 순서대로 정렬되도록 하겠습니다.
cards1_sorted = sorted(enumerate(cards1), key = lambda x: goal.index(x[1])
cards2_sorted = sorted(enumerate(cards2), key = lambda x: goal.index(x[1])
cards1_sorted
# [(0, 'i'), (2, 'drink'), (1, 'water')]
cards2_sorted
# [(0, 'want'), (1, 'to')]
key = lambda x: goal.index(x[1]) 와 같이 정렬 조건을 걸어줌으로써, cards1의 이뉴머레이트 결과값의 인덱스 1번 벨류가 goal에 어떤 순서대로 있느냐?를 기준으로 정렬한 값을 반환하도록 하였습니다. 결과값을 확인해보니 cards2는 그대로이지만 cards1은 drink가 앞으로 온 것을 확인할 수 있습니다. 그런데 이 문법에는 문제가 있습니다. 만약 cards1에 있는 단어가 goal에 없다면 어떻게 될까요?
2 - (1)
cards1 = ["i", "water", "drink", "apple"]
cards1_sorted = sorted(list(enumerate(cards1)), key = lambda x: goal.index(x[1]))
# ValueError: 'apple' is not in list
cards1에 'apple'을 추가해 보니, 벨류 에러가 발생합니다. 따라서 이렇게 없는 값이 있을 경우에는 cards1_sorted의 맨 뒤에다가 값을 추가해주도록 조건을 걸어주겠습니다.
cards1_sorted = sorted(list(enumerate(cards1)),
key = lambda x: (goal.index(x[1]) if x[1] in goal else len(goal) + 1))
cards2_sorted = sorted(list(enumerate(cards2)),
key = lambda x: (goal.index(x[1]) if x[1] in goal else len(goal) + 1))
만약 x[1]이 goal에 있다면 기존대로 정렬을 하고, 없다면 뒤에 추가하도록 if else 구문을 사용하여 조건을 걸어줬습니다. 이 부분은 챗지피티의 도움으로 완성할 수 있었습니다^_ㅠ 엄청 직관적인 문법이 아닌것 같긴 합니다만 그래도 자주 사용해서 자유자재로 구사할 수 있도록 하려고 합니다.
다시 apple이 없었던 원래의 예시문제로 돌아가서 계속해서 설명해보겠습니다.
3.
index_1 = [index for index, value in cards1_sorted]
index_2 = [index for index, value in cards2_sorted]
index_1
# [0, 2, 1]
index_2
# [0, 1]
이제 cards1_sorted와 cards_2sorted에서 인덱스만 뽑아서 깔끔한 리스트 index_1, index_2로 뽑아냅니다. 저는 이 index 리스트의 결과값이 0-2-1처럼 순서에 맞지 않을 경우 카드를 앞에서부터 차례로 사용하는 조건에 어긋난다는 점을 발견했습니다.
따라서 index_1, index_2가 오름차순으로 정렬되어 있다면 "Yes"를, 그렇지 않다면(순서가 뒤죽박죽이라면) "No"를 리턴하도록 함수를 작성했습니다.
def solution(cards1, cards2, goal):
cards1_sorted = sorted(enumerate(cards1), key = lambda x: (goal.index(x[1]) if x[1] in goal else len(goal) + 1))
cards2_sorted = sorted(enumerate(cards2), key = lambda x: (goal.index(x[1]) if x[1] in goal else len(goal) + 1))
index_1 = [index for index, value in cards1_sorted]
index_2 = [index for index, value in cards2_sorted]
if index_1 != sorted(index_1) or index_2 != sorted(index_2):
return "No"
else:
return "Yes"
최근에 sorted() 함수에 대해서 리뷰를 했으며 특히 key 뒤에 lambda 함수를 어떻게 활용할 수 있는 지 여러번 살펴보았기 때문에 위와 같은 아이디어로 문제를 풀 수 있었습니다. 다른 사람의 풀이를 확인해보니 이런 방식으로 풀이를 하신 분은 찾아보기 어려웠고 더 짧고 깔끔하고 반듯하게 푸신 분이 많아서 존경스러웠습니다! 아주 깔끔한 코드는 아니지만 그래도 재밌는 아이디어로 풀어낸 점을 스스로 높게 평가하고자 합니다 ^_^!
감사합니다.
'Code > problem solving' 카테고리의 다른 글
CPU, 병렬 처리, Ray, Multiprocessing (2) | 2024.09.20 |
---|---|
프로그래머스 코딩테스트 | 2단계 올바른 괄호 (Stack 알고리즘으로 풀이하기) (1) | 2024.04.23 |
프로그래머스 코딩테스트 | 2단계 피보나치 수 문제풀이 (재귀함수 + 메모화로 효율성 올리기) (0) | 2024.04.12 |
오류 해결 | 주피터, 코랩 future warning 제거하기 (pandas, seaborn) (0) | 2024.04.09 |
프로그래머스 코딩테스트 | 1단계 카카오 인턴십 키패드 누르기 문제 풀이 (파이썬) (1) | 2024.04.04 |