Practice for coding test

프로그래머스 - Level 2. 튜플 / JavaScript (js)

Gray Park 2023. 2. 26. 11:30
728x90
반응형

문제설명

문제분석

이 문제는 입력값 s의 집합을 배열로 변환하고, 각 배열의 길이를 기준으로 오름차순 정렬한 다음, 리턴 배열(answer)에 포함되지 않은 요소를 추가하는 형태로 해결하면 됩니다.

  • 먼저 s의 집합을 배열로 변환한다.
  • 배열의 길이를 기준으로 오름차순 정렬한다.
  • 리턴 배열에 포함되지 않은 요소를 순차적으로 추가한다.

그럼 코드를 작성해보겠습니다.

이해하기 쉽게 코드작성하기

function solution(s) {
    const memo = {};
    let tmp = "";
    // 문자열 s를 순회하며 하나의 서브셋 내부에 있는 모든 요소를 tmp에 추가
    // 서브셋이 종료되면 tmp를 배열로 변환하고, 그 길이를 key로 객체에 배열을 저장
    for(let i = 1; i < s.length - 1; i++) {
        if(s[i] === "}") {
            const len = tmp.split(",").length
            memo[len] = memo[len] || JSON.parse(tmp + "]");
        } else if(s[i] === "{") {
            tmp = "[";
        } else {
            tmp += s[i];
        }
    }
    
    // 객체의 키를 오름차순으로 정렬
    const keys = Object.keys(memo).sort((a, b) => Number(a) - Number(b));
    const answer = [];
    
    // 배열로 된 서브셋을 순서대로 조회하며 answer에 없는 것만 추가
    for(const key of keys) {
        memo[key].forEach(x => {
            if(answer.includes(x) === false) {
                answer.push(x);
            }
        })
    }
    
    return answer;
}

위 코드를 조금 더 간결하게 개선할 순 없을까 고민을 하던 중, 문자열 처리해주는 부분과 정답 배열을 생성하는 부분을 구분짓기로 했습니다. 그리고 추상화를 통해 문자열 핸들링 함수로 대체하고, 정답 배열을 생성하는 부분을 reduce로 치환합니다. 그 결과는 다음과 같습니다.

function solution(s) {
    s = getArrayFromStrSet(s).sort((a, b) => a.length - b.length);
    return s.reduce((a, c) => {
        c.forEach(x => {
            if(a.includes(x) === false) {
                a.push(x);
            }
        });
        return a;
    }, []);
}

function getArrayFromStrSet(strSet) {
    return strSet
            .slice(2, strSet.length - 2)
            .split("},{")
            .map(x => JSON.parse(`[${x}]`));
}

변환된 코드를 살펴보면, 앞서 객체를 이용한 것과 달리 배열로 문자열을 핸들링합니다. 입력 문자열의 시작과 끝지점에 존재하는 "{{"와 "}}"를 제거한 문자열을 "},{"로 split 하면 배열로 변환할 수 있는, 숫자와 콤마로만 이루어진 문자열로 분리됩니다. 이 문자열의 좌우에 대괄호를 붙여 JSON.parse해주면 배열로 리턴하게 됩니다.

 

반응형

 

이렇게 생성된 배열을 길이에 따라 오름차순으로 정렬합니다. 이후 reduce를 통해 순차적으로 요소를 조회하며 빈 배열에 중복없이 요소를 추가하면 답을 찾을 수 있습니다.

 

조금 더 변경해서 코드를 깔끔하게 변경한다면 다음처럼도 가능합니다.

function solution(s) {
    s = getArrayFromStrSet(s).sort((a, b) => a.length - b.length);
    return s.reduce((a, c) => [...a, ...c.filter(x => a.includes(x) === false)], []);
}

function getArrayFromStrSet(strSet) {
    return strSet
            .slice(2, strSet.length - 2)
            .split("},{")
            .map(x => JSON.parse(`[${x}]`));
}

 

728x90
반응형