코딩테스트/프로그래머스

[JS] 옹알이 (2)

joycie416 2024. 8. 9. 13:13
 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

문제 분석

1. 주어진 텍스트 포함해야 함.

2. 주어진 텍스트 중 동일한 텍스트가 연속되면 안됨.

 

문제 해결 과정

1.` split`을 통해 array로 바꾸자.

하지만 지금 아는 지식으로는 여러 단어를 기준으로 `split`해서 하나의 array로 만드는 것은 복잡한 과정을 거쳐야할 것 같았다.

 

 

2. `replace`를 통해 주어진 택스트 앞에 공백을 추가한 후 `split`하자.

공백을 추가해 `split`하면 단순하게 해결할 수 있겠다는 아이디어가 1번 과정 중 갑자기 떠올랐다. 이때 `replace` 매소드는 맨 처음 등장하는 경우에 한하여 바꿔주므로 `replaceAll`을 사용하였다. 또한 맨 앞에 기준 텍스트가 존재하면 빈문자열이 생기게 되어 `trim`을 통해 먼저 제거해주었다.

let tmp_word = babbling[i];
let isTrue = true;

for (let j = 0; j < 4; j++) {
  tmp_word = tmp_word.replaceAll(Babbles[j], ` ${Babbles[j]}`);
}
tmp_word = tmp_word.trim();

const tmp_split = tmp_word.split(' ');

여기서 `isTrue`는 올바른 단어인지 확인할 용도로 설정한 변수이다.

 

 

3. 각 부분에 불필요한 글자가 더 들어있으면 안됨.

예시를 보면 'uuu'와 'ayaayaa'는 발음할 수 있는 단어에 포함되지 않는다. 이를 봤을 때 기준 단어 포함해야 한다는 것을 알 수 있다.

 

 

4. 연속되면 안됨.

Javascript에서는 할당되지 않은 것을 불러올 때, `undefined`로 반환한다는 것을 고려하여 코드를 작성했다. 파이썬 등 배열(리스트)의 크기를 벗어나는 경우 에러를 발생하는 언어와 다르다.

const str = tmp_split[k];
if (str === tmp_split[k-1] || str == tmp_split[k+1]){
  // 연속되면 안됨

  isTrue = false;
  break;
}

자신보다 앞에 있거나 뒤에 있는 단어와 동일하면 `isTrue`를 false로 바꿔주고 해당 단어에 `tmp_split`에 관한 반복을 종료한다.

 

 

5. 한 단어로 이루어진 경우도 고려해야 함

위 과정을 거치고 테스트해봤는데, 'ayaa' 같은 한단어로 split된 경우에서 문제가 발생했다. 그래서 처음에는 `tmp_word`과 `babbling[i]`가 같으면 false가 되도록 했다. 그런데 이 경우 올바른 케이스도 false로 분류하는 문제가 발생한다.

 

 

6. 배열의 `every` 메소드를 사용하자.

`tmp_split`의 모든 원소가 기준 단어들이어야 한다. 따라서 `every`메소드를 사용하기에 적합하다. 이 메소드를 사용하면 3번도 만족하게 된다.

if (!tmp_split.every((str) => Babbles.includes(str))) {
  // Babbles에 속한 단어로만 이루어져야 함
  isTrue = false;
  continue;
}

`every` 메소드의 결과가 false이면 `isTrue`도 false로 바꿔주고 이후 과정을 실행하지 않도록 `continue`를 넣었다.

 

7. `isTrue` 확인

코드에서 반복문이 들어가야 할 곳은 두 군데 이다. input으로 주어질 `babbling`의 원소를 모두 순회하기 위한 반복문과 `tmp_split`으로 쪼개진 각 단어를 순회하기 위한 반복문이 필요하다.

두 번째 경우는 4번에 주어진 코드처럼 false로 변경되면 break하도록 설정해두었다. 첫번째 반복문의 마지막에서 `isTrue`가 true로 남아있는 경우 `answer`를 1늘려주면 된다.

 

 

전체 코드

const Babbles = ['ayas', 'ye', 'woo', 'ma'];

function solution (babbling) {
  let answer = 0;

  for (let i = 0, n = babbling.length; i < n; i++) {
    let tmp_word = babbling[i];
    let isTrue = true;

    for (let j = 0; j < 4; j++) {
      tmp_word = tmp_word.replaceAll(Babbles[j], ` ${Babbles[j]}`);
    }
    tmp_word = tmp_word.trim();
    console.log(tmp_word);

    const tmp_split = tmp_word.split(' ');

    if (!tmp_split.every((str) => Babbles.includes(str))) {
      // Babbles의 단어로만 이루어져야 함
      console.log('here 0');

      isTrue = false;
      continue;
    }

    for(let k in tmp_split) {
      const str = tmp_split[k];
      if (str === tmp_split[k-1] || str == tmp_split[k+1]){
        // 연속되면 안됨
        console.log('here 1');

        isTrue = false;
        break;
      }
    }

    if (isTrue) {
      // console.log(babbling[i]);
      answer++;
    }
  }

  return answer;
}

const ex = ["ayaye", "uuu", "yeye", "yemawoo", "ayaayaa"];
// const ex = ["aya", "yee", "u", "maa", 'ayaya'];

console.log(solution(ex));