문자열 code가 주어집니다.
code를 앞에서부터 읽으면서 만약 문자가 "1"이면 mode를 바꿉니다. mode에 따라 code를 읽어가면서 문자열 ret을 만들어냅니다.

mode는 0과 1이 있으며, idx를 0 부터 code의 길이 - 1 까지 1씩 키워나가면서 code[idx]의 값에 따라 다음과 같이 행동합니다.

  • mode가 0일 때
    - code[idx]가 "1"이 아니면 idx가 짝수일 때만 ret의 맨 뒤에 code[idx]를 추가합니다.
    - code[idx]가 "1"이면 mode를 0에서 1로 바꿉니다.
  • mode가 1일 때
    - code[idx]가 "1"이 아니면 idx가 홀수일 때만 ret의 맨 뒤에 code[idx]를 추가합니다.
    - code[idx]가 "1"이면 mode를 1에서 0으로 바꿉니다.

문자열 code를 통해 만들어진 문자열 ret를 return 하는 solution 함수를 완성해 주세요.

단, 시작할 때 mode는 0이며, return 하려는 ret가 만약 빈 문자열이라면 대신 "EMPTY"를 return 합니다.

제한사항

  • 1 ≤ code의 길이 ≤ 100,000
    • code는 알파벳 소문자 또는 "1"로 이루어진 문자열입니다.

나의 풀이

function solution(code) {
    let mode = 0;
    let ret = '';
    
    // 정리 - mode에 관계 없이 현재 요소가 1이면 무조건 mode를 변경함
    // mode에 관계 없이 현재 요소가 0이나 문자이면 mode에 따라 문자열 추가 (조건만 다름)
    
    // 1. code를 순회하며 code[idx] 값이 문자인지, 숫자인지 구분한다.
    // 2. 숫자일 경우 mode를 바꿀지 말지에 대한 판별을 한다. 
    // 3. 문자일 경우 mode를 확인한 후 mode에 따른 행동을 한다. 
    
    let result = [...code].reduce((acc, cur, i) => {
        if (!isNaN(cur) && cur === '1') {   // code[idx]가 1일 때 mode 변경 
            acc.mode === 0 ? acc.mode = 1 : acc.mode = 0;
        } else {    // 나머지 경우 (code[idx]가 0이거나 문자일 때)
            if (acc.mode === 0) {
                if (i % 2 === 0) acc.ret += cur;
            } else {
                if (i % 2 !== 0) acc.ret += cur;
            }
        }
        return acc;
    }, { mode, ret })
    
    return result.ret.length === 0 ? "EMPTY" : result.ret;
}

생각한 과정을 기록해두려고 주석을 살려놨다.

조건을 정리해보면 결국 현재 요소가 1이면 무조건 mode를 바꾼다. 그렇기 때문에 우선 1일 때와 아닐 때로 구분하였고, 그 다음은 조건에 알맞게 경우를 나눴다.

  1. 주어진 code를 배열로 나누어 reduce 함수를 통해 순회한다. 초기값은 객체로 주었다. { mode: 0, ret: '' }로 mode와 ret(연결할 문자)를 담고 있다. 누적값은 acc로, 현재 요소는 cur로, 현재 요소의 인덱스 번호는 i로 받았다.
  2. !isNaN(cur) && cur === '1' 조건을 통해 현재 요소가 1일 때를 구분했다. 현재 요소가 1이면서 누적값의 mode가 0이면 0을 1로 바꾸어주고, 그렇지 않으면 mode의 값을 1에서 0으로 바꿔준다.
  3. 첫 번째 else 문에는 현재 요소가 0이거나 문자일 때가 담긴다.
    • 누적값(현재)의 mode가 0일 때, 인덱스 번호가 짝수일 경우에만 누적값 ret 요소에 cur(현재요소)를 더해준다.
    • 누적값(현재)의 mode가 0이 아닐 때(1), 인덱스 번호가 홀수인 경우에만 누적값 ret 요소에 cur(현재요소)를 더해준다.
  4. 배열의 모든 요소를 순회한 후 누적된 결과(acc)를 반환한다.
  5. result의 ret값의 길이가 0일 경우 "EMPTY"를 반환하고, 아닐경우 ret을 반환한다.

다른 풀이 1

function solution(code) {
    let answer = '';
    let mode = 0;

    for (let i = 0; i < code.length; i += 1) {
      if (Number(code[i]) === 1) {
        mode = mode === 1 ? 0 : 1;
      }
      if (Number(code[i]) !== 1 && i % 2 === mode) {
        answer += code[i];
      }
    }
    return answer.length > 0 ? answer : 'EMPTY';
}
  1. 최종적으로 반환할 문자를 저장할 변수answer를 빈 문자열로 초기화한다.
  2. mode를 저장할 변수를 0으로 초기화한다.
  3. code 문자열의 각 문자를 순회하며 처리한다.
    • if (Number(code[i]) === 1) : 현재 문자가 숫자 1인지 확인한다. 만약 1이 맞다면 mode 변수의 값을 반대로 변경한다.
    • if (Number(code[i]) !== 1 && i % 2 === mode) : 현재 문자가 숫자 1이 아니고, 현재 인덱스가 mode와 일치하는 경우 현재 문자를 answer 변수에 추가한다.
  4. 최종적으로 answer 변수의 길이가 0보다 크면 answer를 반환하고, 그렇지 않으면 'EMPTY'를 반환한다.

다른 풀이 2

function solution(code) {
    let odd = false
    return Array.from(code).reduce((acc, v, i) => {
        if (v === '1') {
            odd = !odd
            return acc
        }
        return (i % 2 === (odd ? 1 : 0)) ? acc + v : acc
    }, '') || 'EMPTY'
}
  1. odd 변수는 홀수 인덱스 여부를 확인하기 위한 변수이다.
  2. Array.from(code): code 문자열을 문자 배열로 변환한다.
  3. 배열의 각 요소를 순회하면서 reduce() 메서드를 사용한다. (acc: 누적값, v: 현재 요소, i: 인덱스)
    • if (v === '1') : 현재 문자가 '1'인 경우 odd 변수의 값을 반대로 변경하고 acc 를 반환한다.
    • return (i % 2 === (odd ? 1 : 0)) ? acc + v : acc: 현재 인덱스가 odd 변수에 따라 홀수 인덱스인 경우에만 현재 문자를 acc에 추가한다.
    • || 'EMPTY' : 최종 결과가 빈 문자열이면 'EMPTY'를 반환한다.

다른 풀이 3

function solution(code) {
    var answer = code.replaceAll("1","").split("").filter((val, idx)=> idx%2 === 0).join("");
    return answer.length > 0 ? answer : "EMPTY";
}
  1. code.replaceAll("1",""): 입력 문자열 code에서 모든 '1'을 제거한다.
  2. split(""): 나머지 ㅁ누자열을 개별 문자로 분리하여 배열로 만든다.
  3. filter((val, idx)=> idx%2 === 0): 짝수 인덱스의 문자열만 남긴다
  4. join(""): 남은 문자들을 다시 문자열로 합친다
  5. 최종 결과가 빈 문자열이 아니면 answer을 반환하고 빈 문자열이라면 "EMPTY"를 반환한다.
profile
영차영차 😎

0개의 댓글

Powered by GraphCDN, the GraphQL CDN