본문 바로가기

문돌이 존버/프로그래밍 스터디

(프로그래머스 연습 문제 풀이) 스킬트리

반응형
문제 설명
선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.
예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.
위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크나 라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.
선행 스킬 순서 skill과 유저들이 만든 스킬트리1를 담은 배열 skill_trees가 매개변수로 주어질 때, 가능한 스킬트리 개수를 return 하는 solution 함수를 작성해주세요.

제한 조건
1. 스킬은 알파벳 대문자로 표기하며, 모든 문자열은 알파벳 대문자로만 이루어져 있습니다.
2. 스킬 순서와 스킬트리는 문자열로 표기합니다.
- 예를 들어, C → B → D 라면 "CBD"로 표기합니다
3. 선행 스킬 순서 skill의 길이는 1 이상 26 이하이며, 스킬은 중복해 주어지지 않습니다.
4. skill_trees는 길이 1 이상 20 이하인 배열입니다.
5. skill_trees의 원소는 스킬을 나타내는 문자열입니다.
- skill_trees의 원소는 길이가 2 이상 26 이하인 문자열이며, 스킬이 중복해 주어지지 않습니다.

입출력 예
skill                   skill_trees                              return
"CBD"      ["BACDE", "CBADF", "AECB", "BDA"]         2

입출력 예 설명
"BACDE": B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트립니다.
"CBADF": 가능한 스킬트리입니다.
"AECB": 가능한 스킬트리입니다.
"BDA": B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트리입니다.
# 모범 참고 코드
from collections import deque

def solution(skill, skill_trees):
    answer = 0
    for skills in skill_trees:
        skill_list = deque(list(skill))
        
        for s in skills:
            if s in skill:
                if s != skill_list.popleft():
                    break
        else:
            answer += 1
    return answer

해당 문제는 하라는대로만 하면 쉽게(?) 풀 수 있는 문제다. skill에 나와있는 문자열 순서대로 적혀있는지만 보면 되는데, deque 를 활용해서 맨 왼쪽부터 빼내어 비교할 수 있다.

skill_trees 원소에는 skill에 없는 문자열이 포함될 수 있으므로 skill에 있는 문자열만 확인해서 비교하면 된다. 모범 코드에서 새롭게 본 문법은 for-else 구문이다. 이는 for문을 빠져나가는 break 가 걸리지 않으면 else 구문을 실행하는 것이다. 즉 skill_trees 원소에서 빼낸 문자열이 skill의 문자열과 순서가 다르다면 break 에 걸리면서 else 구문인 answer += 1가 실행되지 않는다.

정리하자면 순서대로 나열된 문자열만 answer += 1을 실행하는 것이다.

728x90
반응형