여러가지 반례 찾기
이 문제의 제한조건은 1 ≤ babbling의 길이 ≤ 100
, 1 ≤ babbling[i]의 길이 ≤ 30
로서 아주 평범(?)하다. 그래서 극악으로 3중for문을 돌려도 가능할정도이다. 하지만 이 문제는 여러가지로 나를 힘들게 하였다. 아래와 같은 이유로 인해서 여러번 수정을 하게 되었다.
-
연속해서 같은 발음을 하는 것은 발음하지 못한다.
위 이유 때문에 따로 함수(
isSuccessiveP
)를 만들어서 체크해주도록 하였다. -
자르고 난 뒤에 남은 것을 붙였을 때, 발음할 수 있는 단어로 변경되는 경우가 생긴다. (사실은 발음할 수 없는 부분이다!)
자른 곳에 _을 넣어줌으로서 자르고 나서 같아지는 경우를 방지한다. 예를 들면
woayao → aya로 자름 → woo
, woo 가 되어 발음할 수 있는 단어가 되어버린다. 이렇게되면 발음할 수 있다고 체크되는데, 실제로는 발음 할 수 없는 것으로 체크되어야한다.
function solution(babbling) {
const arr = [];
const pronounceable = ['aya', 'ye', 'woo', 'ma'];
babbling.forEach((word) => {
let tmp = word;
for (const p of pronounceable) {
if (tmp.indexOf(p) > -1) {
const s = isSuccessiveP(word, p);
if (s) break;
tmp = tmp.split(p).join('_');
}
}
arr.push(tmp);
});
const parsed = arr.map((w) => w.split('_').join('')).filter(Boolean);
return babbling.length - parsed.length;
}
function isSuccessiveP(word, p) {
let _word = word;
let prevIdx = -1,
curIdx = 0;
while (curIdx > -1) {
curIdx = _word.indexOf(p, prevIdx + 1);
if (prevIdx + p.length === curIdx) return true;
else prevIdx = curIdx;
}
return false;
}
위의 몇가지 반례를 수정한 후 제출하였으나,, 어디선가 문제가 발생했는지, 80점을 맞게 되었다. 4개의 테스트 케이스가 안되는 상태!. 질문하기에서 추천해준 대부분의 반례(주로 나타나는 반례들)는 통과한 상태여서, 뭔가 새로운 마음가짐으로 다시 코드를 짜야할 것 이라는 생각이 들었다.
아래 코드는 replace / replaceAll 이라는 메소드를 잘 활용해보자는 마인드로 접근하였다. 먼저 replaceAll을 사용해서 풀었는데, 이 경우는 여러 단어를 한번에 바꾸게 되는데 연속되는 단어를 바꾸는 경우, 연속되는 단어인지 여부를 판가름 하기가 쉽지 않았다. 그래서 아래와 같이 replace를 사용하여 단어를 바꿀때마다 이것이 연속된 단어를 바꾸는지 여부를 판가름 해주었다.
function solution(babbling) {
const pro = ['aya', 'ye', 'woo', 'ma'];
const result = []; // 발음 못하는 단어들
babbling.forEach((w) => {
let target = w;
for (let p of pro) {
while (true) {
let index = target.indexOf(p);
if (index === -1) break;
else {
const nextIndex = target.indexOf(p, index + 1);
if (index + p.length === nextIndex) break; // 연속해서 발음하는 경우
else target = target.replace(p, ' '); // 교체하고 남은 부분을 직접적으로 조인(join)하지 않음
}
}
}
if (!!target.trim()) result.push(target);
});
return babbling.length - result.length;
}
드디어 성공!!
코드 자체는 매우 복잡하다. 추가적으로 리팩토링을 하자면, 어떻게 하면 루프 안에 루프들을 줄일 수 있을지 고민해봐야하겠다. 그래도 내가 생각한 바를 여러가지 방법을 통해서 구현할 수 있었다는 점에서 만족하고 넘어가자.(사실 많은 시간을 소비하긴해서... 😅)
추가로 코테 문제를 풀 때 자주 사용하지 않았던 replace/replaceAll
에 대한 활용을 해본 좋은 시간이였다.