코딩 테스트/프로그래머스(LV2)

[프로그래머스] 스킬트리 (LV2 - JavaScript)

dev-hpk 2024. 12. 10. 18:43
 

프로그래머스

SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프

programmers.co.kr

1. 문제

선행 스킬이란 어떤 스킬을 배우기 전에 먼저 배워야 하는 스킬을 뜻합니다.

 

예를 들어 선행 스킬 순서가 스파크 → 라이트닝 볼트 → 썬더일때, 썬더를 배우려면 먼저 라이트닝 볼트를 배워야 하고, 라이트닝 볼트를 배우려면 먼저 스파크를 배워야 합니다.

 

위 순서에 없는 다른 스킬(힐링 등)은 순서에 상관없이 배울 수 있습니다. 따라서 스파크 → 힐링 → 라이트닝 볼트 → 썬더와 같은 스킬트리는 가능하지만, 썬더 → 스파크라이트닝 볼트 → 스파크 → 힐링 → 썬더와 같은 스킬트리는 불가능합니다.

 

선행 스킬 순서 skill과 유저들이 만든 스킬트리1를 담은 배열 skill_trees가 매개변수로 주어질 때, 가능한 스킬트리 개수를 return 하는 solution 함수를 작성해주세요.

 

제한사항

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

입출력 예

skill skill_trees return
"CBD" ["BACDE", "CBADF", "AECB", "BDA"] 2

 

입출력 예 설명

입출력 예 #1

  • "BACDE": B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트립니다.
  • "CBADF": 가능한 스킬트리입니다.
  • "AECB": 가능한 스킬트리입니다.
  • "BDA": B 스킬을 배우기 전에 C 스킬을 먼저 배워야 합니다. 불가능한 스킬트리입니다.

2. 정답 풀이

풀이 전략

  • 정규식을 활용해 skill에 포함되는 문자 매칭한다.
  • skill_trees 배열의 각 요소들을 순회하며 배울 수 있는 스킬트리인지 확인한다.
  • 인덱싱을 통해 정규식에 해당하는 문자가 매칭되었을 때 skill[idx] 값과 현재 문자(s[i])가 일치하는지 확인한다.
  • 일치하면 인덱스를 증가시키고 순회를 진행한다.
  • 일치하지 않으면 배울 수 없는 스킬트리기 때문에 canLearn 플래그에 false를 할당하고 순회를 종료한다.
  • 순회를 마쳤을 때 canLearn 플래그의 값이 true면 배울 수 있는 스킬트리로 answer++를 진행한다.
function solution(skill, skill_trees) {
    let answer = 0;
    // skill에 포함되는 문자만 걸러낼 정규식
    const skillRegExp = new RegExp(`[${skill}]`);
    
    skill_trees.forEach(s => {
        let idx = 0; // skill 인덱스 
        let canLearn = true; // 스킬을 배울 수 있는지 확인하기 위한 플래그
        for (let i=0; i<s.length; i++) {
            // skill에 포함된 문자인 경우
            if (s[i].match(skillRegExp)) {
                // skill 순서와 어긋나면 플래그 false로 바꾸고 순회 종료
                if (skill[idx] !== s[i]) {
                    canLearn = false;
                    break;   
                } else {
                    // skill 순서와 같으면 인덱스 증가
                    idx++;
                }
            }
        }
        if (canLearn) answer++; // 배울 수 있는 스킬트리인 경우 answer++
    })
    return answer;
}

 

시간 복잡도도 짧고, 코드도 직관적인 것 같은데... 뭔가 코드가 길다😅😅

3. 다른 사람 풀이

function solution(skill, skill_trees) {
    var answer = 0;
    var regex = new RegExp(`[^${skill}]`, 'g');

    return skill_trees
        .map((x) => x.replace(regex, ''))
        .filter((x) => {
            return skill.indexOf(x) === 0 || x === "";
        })
        .length
}

 

skill에 포함되지 않은 문자를 replace 메서드를 통해 빈 문자열('')로 바꾸니까 너무 간단하다.

map을 통해 정규식으로 걸러낸 문자열을 skill의 접두사인지 확인하는 부분도 신기하네.. 전혀 생각도 못했다😱

 

 

[프로그래머스] 더 맵게 (LV2 - JavaScript)

프로그래머스SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프programmers.co.kr1. 문제 매운 것을 좋아하는 Leo는 모든 음식의 스코빌 지수를 K 이상으로

dev-hpk.tistory.com

 

 

[프로그래머스] 주식가격 (LV2 - JavaScript)

프로그래머스SW개발자를 위한 평가, 교육, 채용까지 Total Solution을 제공하는 개발자 성장을 위한 베이스캠프programmers.co.kr1. 문제 초 단위로 기록된 주식가격이 담긴 배열 prices가 매개변수로 주어

dev-hpk.tistory.com