본문 바로가기
알고리즘/Programmers

[TIL] 2023.04.23 Programmers_옹알이(1)

by heereal 2023. 4. 23.

Today I Learned

  • Programmers 문제 풀기

 


Programmers 문제 풀기

옹알이(1)

문제 설명

머쓱이는 태어난 지 6개월 된 조카를 돌보고 있습니다. 조카는 아직 "aya", "ye", "woo", "ma" 네 가지 발음을 최대 한 번씩 사용해 조합한(이어 붙인) 발음밖에 하지 못합니다. 문자열 배열 babbling이 매개변수로 주어질 때, 머쓱이의 조카가 발음할 수 있는 단어의 개수를 return 하도록 solution 함수를 완성해 주세요.

 

 

제한사항

  • 1 ≤ babbling의 길이 ≤ 100
  • 1 ≤ babbling[i]의 길이 ≤ 15
  • babbling의 각 문자열에서 "aya", "ye", "woo", "ma"는 각각 최대 한 번씩만 등장합니다.
    • 즉, 각 문자열의 가능한 모든 부분 문자열 중에서 "aya", "ye", "woo", "ma"가 한 번씩만 등장합니다.
  • 문자열은 알파벳 소문자로만 이루어져 있습니다.

 

입출력 예

babbling result
["aya", "yee", "u", "maa", "wyeoo"] 1
["ayaye", "uuuma", "ye", "yemawoo", "ayaa"] 3

입출력 예 #1

  • ["aya", "yee", "u", "maa", "wyeoo"]에서 발음할 수 있는 것은 "aya"뿐입니다. 따라서 1을 return 합니다.

입출력 예 #2

  • ["ayaye", "uuuma", "ye", "yemawoo", "ayaa"]에서 발음할 수 있는 것은 "aya" + "ye" = "ayaye", "ye", "ye" + "ma" + "woo" = "yemawoo"로 3개입니다. 따라서 3을 return 합니다.

 

 

나의 1차 풀이

function solution(babbling) {
    let array = ["aya", "ye", "woo", "ma"];
    let answer = 0;
    for (const babble of babbling) {
        let dd = babble;
        for (const say of array) {
            dd = dd.replaceAll(say, "")
        }
        if (dd === "") answer++;
    }
    return answer;
}

for문을 돌면서 replaceAll 메서드로 단어를 모든 부분을 옹알이로 대체해서 ""이 된다면 카운트하는 방법으로 풀었는데 이렇게 하면 발음할 수 있는 단어의 개수를 세는 데 문제가 발생한다.

 

주어진 문자열이 "wyeoo"라면 먼저 "ye"를 공백으로 대체해서 "woo"가 되고, 그 후에 "woo"를 다시 공백으로 대체해서 결과적으로 문자열이 공백이 된다. 문제의 제한사항에 따르면 발음할 수 없는 단어가 되어야 하는데 answer에 카운트가 되어서 답이 틀리게 됐다.

 

 

나의 최종 풀이

function solution(babbling) {
    let array = ["aya", "ye", "woo", "ma"];
    let answer = 0;
    for (const babble of babbling) {
        let word = babble;
        for (const say of array) {
            word = word.replaceAll(say, 1)
        }
        if (/^1*$/.test(word)) answer++;
    }
    return answer;
}
  1. 조카가 발음할 수 있는 문자열 배열 array를 생성한다.
  2. 파라미터로 받은 문자열 배열 babbling을 for문으로 반복한다.
  3. 문자열 배열 babbling의 각 요소에 조카가 발음할 수 있는 문자열 배열 array의 발음을 하나씩 replaceAll에 적용한다.
  4. 만약 for문의 요소가 조카가 발음할 수 있는 발음의 조합이라면 word는 숫자 1로만 구성된 변수가 된다.
  5. if문 조건에 정규표현식을 이용해서 word가 숫자 1로만 구성된 문자라면 answer +1을 한다.
  6. for문이 종료되면 최종적으로 answer를 return 한다.

 

정규표현식 풀이

/^1*$/
  • 이 정규표현식은 문자열의 시작부터 끝까지 1로만 이루어진 문자열을 나타냅니다.
  • 여기서 '^'는 문자열의 시작을 나타내고, '$'는 문자열의 끝을 나타냅니다. '*'는 앞의 문자 또는 패턴이 0번 이상 반복됨을 나타내는 메타 문자입니다.
  • 따라서 /^1*$/ 정규표현식은 문자열이 1로만 이루어져 있고, 그 길이는 0 이상인 문자열과 일치합니다.

 

다른 사람의 풀이 01

function solution(babbling) {
  var answer = 0;
  const regex = /^(aya|ye|woo|ma)+$/;

  babbling.forEach(word => {
    if (regex.test(word)) answer++;  
  })

  return answer;
}

  babbling에 forEach 메서드를 사용해서 정규표현식을 통과하는지에 따라 answer에 +1을 해주는 깔끔한 풀이.

 

 

다른 사람의 풀이 02

function solution(babbling) {
    let df = [ "aya", "ye", "woo", "ma"];
    let res = 0;
    for(let w of babbling) {
        if(df.some(f => w.includes(f+f))) continue;

        let rest = 
           df.reduce((a, f) => a.replaceAll(f, ""), w);

        if (rest.length > 0) continue;

        res++;
    }

    return res;
}

현재는 통과하지 못하는 풀이라고 하지만 some 메서드나 for문에 continue를 사용한 게 인상 깊어서 가져왔다. 

 

 Array.prototype.some() 

  • some() 메서드는 배열 안의 어떤 요소라도 주어진 판별 함수를 적어도 하나라도 통과하는지 테스트합니다. 만약 배열에서 주어진 함수가 true을 반환하면 true를 반환합니다. 그렇지 않으면 false를 반환합니다. 이 메서드는 배열을 변경하지 않습니다.

 

 반복_break/continue문 

  • break문: 이제 더 이상 반복하지 말고, 바로 for문이나 while문을 끝낸다.
  • continue문: continue문 아래에 있는 실행해야 하는 문장들을 건너뛰고, 다음 반복을 시작한다.

출처 http://rchemist.egloos.com/v/534921

 

 

댓글