출처: https://meyouus.tistory.com/64 [정보 공유 - For Me For You For Us]
본문으로 바로가기

조금 오랫동안 고민을 해야했던 문제이다:

def solution(skill, skill_trees):
    count = 0
    for i in range(len(skill_trees)):
        index_list = []
        index_list_check = []
        for j in range(len(skill)):
            if skill[j] in skill_trees[i]:
                index_list_check.append(skill_trees[i].index(skill[j]))
            for k in range(j):
                if not skill[k] in skill_trees[i]:
                    break
            else:
                if skill[j] in skill_trees[i]:
                    index_list.append(skill_trees[i].index(skill[j]))
        if index_list == index_list_check and index_list == sorted(index_list):
            count += 1
    return count

내가 짠 코드에서 고민을 해야했던 이유는 skill에 있는 문자열이 skill_tree[i]에 있다면 무조건 index_list에 추가해줄 것이 아니라, 이 문자열이 skill에 있던 앞의 문자열들이 존재한다면 추가를 해줘야 하고, 또 추가된 index_list에서 순서가 다 맞아야 count를 1을 더해줄 수 있다. 다음은 이 코드의 진행 방식이다

  1. count는 가능한 스킬 트리의 갯수를 의미한다.
  2. for문에서 j를 range(len(skill))로 정의해준다.
  3. 우선, skill의 문자열이 skill_trees[i]에 존재한다면, index_list_check에 추가해준다.
  4. for문에서 krange(j)로 정의해준다. 즉, j보다 낮은 숫자들로 정의해준다.
  5. skill[k]skill_tress[i]에 없다면, 즉 skill[j] 이전의 문자열이 skill_tress[i]에 없다면 그냥 break해준다.
  6. 만약 for문에서 break가 안 일어났다면, skill[j]skill_trees[i]에 존재하는지 확인해주고, 있다면 index_list에 추가해준다.
  7. 마지막으로, index_listindex_list_check가 같고, index_listsorted(index_list)가 같다면 count에 1을 더해준다.
    1. index_list == index_list_check의 뜻은 다음과 같다. 예를 들어 skill = 'CBD'이고 skill_tress = 'BDA'라면 index_list = [], index_list_check = [0, 1]이 될것이다. index_list_check는 만약 skill의 문자열이 안에 있으면 무조건 추가해주었고, index_list의 경우, 만약 이전의 문자열이 없으면 추가 안하는 방식으로 했으므로, 문자열 B, D 이전의 문자열인 C가 BDA에 없으므로 추가하지 않는다.
    2. index_list == sorted(index_list)의 뜻은 skill_trees의 스킬 순서가 알맞게 되어있는지 확인하는 과정이다. 예를들어 skill = 'CBD'이고 skill_trees = 'BDC'이라면 index_list == index_list_check가 되겠지만, 문제가 요구하는 조건에 따라 문자열 C가 문자열 B,D 이전에 있지 않으므로 알맞지 않게 된다. index_list = [2, 0, 1]이 되겠지만, 실제로는 보다 싶이 문자열 C가 가장 뒤에 있다는 것을 나타내므로, index_list == sorted(index_list)도 또한 확인해주어야 한다.
    3. 만약 이 조건들이 다 맞는다면 이제 count를 1을 더해주고 모든 skill_trees의 요소들을 확인 했다면 이를 출력해준다.

하지만 이렇게 푸는 것 보다 훨씬 간단한 방법이 있었으니, 한번 살펴보겠다.


다른 사람의 풀이

다음은 프로그래머스에서 가장 많은 좋아요를 받은 문제풀이이다:

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

매우 간단하게 풀었다.

  1. skill_tress의 각 요소들을 skills라고 정의하고, skill_listskill의 각 요소들을 확인하기 위해 이를 리스트로 만들어준다.
  2. 다음으로는 skills의 각 요소 s에 대하여, 만약 skills가 있다면, 만약 skill_list의 첫번째 문자열이 아니라면 break를 걸어준다. pop함수를 사용하기 때문에 만약 맞다면 그 첫번째 요소는 삭제해준다. skill_listskill_tress의 각 요소마다 정의해주므로 새롭게 클리어 된다.
  3. 만약 이 for문break없이 정상적으로 돌아갔다면, answer에 1을 더해준다. 이를 모두 완료한 후 answer를 돌려준다.

결국 순서대로 체크해주는 과정을 더 간단하게 표현한 것이다. 아직도 코딩을 더 효율적으로 하는 것은 갈 길이 먼듯하다.