[프로그래머스 | Javascript] 2021 KAKAO BLIND RECRUITMENT - 신규 아이디 추천

박기영·2022년 9월 14일
0

프로그래머스

목록 보기
47/159
post-custom-banner

solution

function solution(new_id) {
    let stack = [];
    
    // 허용하는 특수문자
    let special = ["-", "_", "."];
    
    let idArr = new_id.split("");
    
    for(let i = 0; i < idArr.length; i++){        
        let idStr = idArr[i];
        
        let ASCII = idStr.charCodeAt();
        
        // 소문자거나 숫자면 stack에 넣는다
        if((ASCII >= 97 && ASCII <= 122) || (ASCII >= 48 && ASCII <= 57)){
            stack.push(String.fromCharCode(ASCII));
            
            continue;
        }
        
        // 1단계
        if(ASCII >= 65 && ASCII <= 90){
            // 만약 대문자가 있다면 소문자로 바꾼다.
            ASCII += 32;
            
            // 아스키 코드를 문자로 변환해서 stack에 넣는다.
            stack.push(String.fromCharCode(ASCII));
            
            // 하나의 문자에 대하여 연산이 끝났으므로 다음 문자로 넘어간다.
            continue;
        }
        
        // 2단계
        // 대문자에 대한 처리는 위에서 거쳐서 오기 때문에 신경 안 써도 되고,
        // 소문자나 숫자가 아니면서
        if(!(ASCII > 97 && ASCII < 122) && !(ASCII > 48 && ASCII < 57)){
            // 허용되는 특수문자라면 stack에 넣는다.
            if(special.includes(String.fromCharCode(ASCII))){
                stack.push(String.fromCharCode(ASCII));
                
                // 3단계
                // 만약 stack 가장 위에 있는 값이 "."이라면 연속인지 판단한다.
                if(stack[stack.length - 1] === "."){
                    // 만약 stack에서 "."이 연속으로 반복된다면 하나로 줄여준다.
                    if(stack[stack.length - 2] === stack[stack.length - 1]){
                        stack.pop();
                    }
                }
                
                continue;
            } else {
                // 허용되지 않은 특수문자라면 그냥 다음 문자로 넘어간다.
                continue;
            }
        }
    }
    
    // 4단계
    // 맨 앞이 "."이라면 지워준다
    if(stack[0] === "."){
        stack.shift();        
    }

    // 맨 뒤가 "."이라면 지워준다
    if(stack[stack.length - 1] === "."){
        stack.pop();
    }
    
    // 5단계
    // stack의 길이가 0이라면 "a" 넣어준다.
    if(stack.length === 0){
        stack.push("a");
    }
    
    // 6단계
    // 길이가 16이 넘는다면
    if(stack.length >= 16){
        // 0부터 14번 인덱스(즉, 길이가 15)까지만 남긴다.
        stack = stack.slice(0, 15);
    }
    
    // 제거 후에 다시 한번 맨 끝을 확인해준다.
    // "."이라면 제거해준다.
    if(stack[stack.length - 1] === "."){
        stack.pop();
    }
    
    // 7단계
    // 길이가 2 이하라면
    if(stack.length <= 2){
        let last = stack[stack.length - 1];
        
        // 길이가 3이 될 때까지 마지막 문자를 넣는다.
        while(stack.length !== 3){
            stack.push(last);
        }
    }
    
    return stack.join("");
}

정말 단순하게 풀었다.
문제 예시에서 주어진 단계별 풀이법을 그대로 코드로 표현했다.

특수 문자 처리의 편의성을 위해서 스택 구조를 활용했는데,
중간에 shift()를 사용하는 바람에 사실..큰 의미가 있나..싶은 풀이다.
사실상 데크 구조가 되어버렸다.

다른 분 풀이

const solution = (new_id) => {
    const id = new_id
        .toLowerCase()
        .replace(/[^\w\d-_.]/g, '')
        .replace(/\.{2,}/g, '.')
        .replace(/^\.|\.$/g, '')
        .padEnd(1, 'a')
        .slice(0, 15)
        .replace(/^\.|\.$/g, '')        
    
    return id.padEnd(3, id[id.length-1]);
}

1시간을 걸려 내 코드를 작성했는데 이 분은 정말 간단하게 푸셨다...정규식을 활용하셨다.
toLowerCase()로 대문자를 소문자로 전부 전환했고,
그 다음 단계부터는 정규식과 replace를 통해 조건에 맞는 것들을 전환해주었다.
padEnd()를 통해 new_id가 비어버렸을 경우 a를 넣어주었다.
padEnd()는 설정해놓은 길이보다 new_id의 길이가 크면 작동하지 않기 때문에 좋은 방법인 것 같다.
slice는 필자가 사용한 방법과 동일하다.
마지막에도 padEnd()를 사용해서 길이가 3보다 작을 경우,
길이를 3까지 맞추고, 가장 끝에 있는 문자를 반복해주었다.

profile
나를 믿는 사람들을, 실망시키지 않도록
post-custom-banner

0개의 댓글