Supin Kim

Supin Kim

Developer

© 2021

Dark Mode

[코딩테스트 문제풀이] Programmers 방금 그곡

Programmers Lv.2 [3차]방금 그곡 #kakao#2018 KAKAO BLIND RECRUITMENT

[문제]

방금 그곡

[접근 방법]

일단 보자마자 든 생각은 #를 어떻게 구분해야 하지…라는 생각이 가장 먼저 들었는데, 풀고 다른 풀이를 찾아보니 String 메소드 중에 replace를 활용해 chaining으로 각 #이 있는 음표들을 해당 음표에서 사용하지 않는 숫자나 소문자로 변경해서 문자열을 비교하는 풀이가 많았던 것 같다.

그러나 정규식과 배열을 활용해도 풀 수 있다. String.match 메소드를 사용하면 각 정규식에 맞는 부분이 배열로 return된다. # 있는 정규식 조건을 먼저 써줘야 하는 이유는 ‘[A-G]{1}#’ 조건을 만족하지 않을 경우[A-G]{1}을 찾기 위해서 먼저 #를 써줘야지 반대의 순서로 작성하면 [A-G]{1}에서 이미 조건을 만족하기 때문에 #가 있는 부분을 걸러내지 못한다.

그리고 나서 시간은 전체 분으로 계산해서 악보의 길이와 네오가 들은 길이(m)을 비교해서 새로운 악보 배열을 생성해준다.

문제는 여기가 아니라 이제 m과 score를 비교하는 부분이었는데, 결론부터 말하자면 차라리 처음부터 아예 문제에서 사용하지 않는 단어로 string을 바꿔서 푸는 게 공수가 덜 들었을 것이라고 생각한다.

왜냐면 C / C#같은 string으로 하면 반드시 포함관계가 생겨버리는 친구들 때문에 조건에 만족하는지 아닌지 확인하는 조건이 더 까다로워졌기 때문이다.

처음에 시도했을 때 3가지 케이스에서 통과하지 못했는데, 그 이유는

if(mArr.every(x => scoreArr.includes(x)) 
   && scoreArr.join('/').includes(mArr.join('/')) 
   && scoreArr.length >= mArr.length)
   {
      ans.push({play:playTime, start: time1, name: name});
   }

이렇게 코드를 적어주면 예를 들어 m = “ABC” 이고, score=”ABC#DC”라면 문제의 조건과 틀리지만 내 체크코드에 의하면 m의 모든 원소들이 scoreArr = [“A”,”B”,”C#”,”D”,”C”]에 포함되고 join을 했을 때도 includes가 true가 된다.(“A/B/C”는 “A/B/C#/D/C”에 포함) 그래서 이런 예외 케이스를 잡아주지 못한다.

그러므로 이를 방지하기 위해서는 m의 가장 첫번째 원소의 위치를 score에서 찾아서 문자열 끝까지 만족하는 부분이 있는지 확인해줘야 한다.(앞부분만 찾아서는 안된다.) 이 점을 파악하는 데 애를 먹었고, 겨우 통과할 수 있었다. 풀고 보니 문제 자체는 그렇게 어렵지 않은데 조건을 체크하는 조건문을 꼼꼼하게 짜는지 못 짜는지가 문제를 시간 내에 풀 수 있는 관건이 되는 것 같다.

만약 다음에 이런 문자열 처리 문제를 만난다면, 간단하게 겹칠 수 있는 토큰은 해당 문제 조건에서 사용되지 않는 문자열로 변경하여 풀면 좀 더 쉽고 빠르게 풀어낼 것이다. 빠이팅 🔥

[해결 코드 1]

============================================================================================================

[추가 : 해결 코드2]

문자열 치환으로 풀 경우, 조건도 덜 까다롭고 코드 수도 줄고, 속도도 빠르다! 다음부터 문자열 중복을 피해야 하는 경우 문자열 치환으로 풀기!