몸과 마음이 건전한 SW 개발자

프로그래머스 [Lv. 1] 신규 아이디 추천 {언어 : JavaScript} 본문

알고리즘

프로그래머스 [Lv. 1] 신규 아이디 추천 {언어 : JavaScript}

스위태니 2024. 2. 22. 01:39

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/72410

 

프로그래머스

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

programmers.co.kr

정답 코드

function solution(new_id) {
    // 문자열을 리스트로 만들기
    // const arr = Array.from(new_id)
    // const arr = [...new_id]
    const arr = new_id.split("")
    
    // 1 단계
    // e는 element : 요소
    const first_step = arr.map((e) => {
        // toUpperCase는 대문자로 바꿔주는 함수
        return e.toLowerCase()
    })
    
    // 2 단계
    const second_step_assist_arr = ["-", "_", "."]
    const second_step = first_step.reduce((acc, e) => {
        if (second_step_assist_arr.includes(e) || ("a" <= e && e <= "z") || ("0" <= e && e <= "9")) {
            acc.push(e)
        }
        return acc
    }, [])
    
    // 3 단계
    const third_step = second_step.reduce((acc, curr) => {
        // acc의 마지막 요소와 현재 요소가 모두 "."이면, 현재 요소를 추가하지 않습니다.
        const acc_lenght = acc.length
        if (!(acc_lenght > 0 && acc[acc_lenght - 1] === "." && curr === ".")) {
            acc.push(curr)
        }
        return acc
    }, [])

    // 4단계
    let fourth_step_assist_index = 0
    const fourth_step = third_step.reduce((acc, e, index) => {
        if (acc.length == 0) {
            if (e != ".") {
                acc.push(e)
            }
        } else {
            acc.push(e)
            if (e != ".") {
                fourth_step_assist_index = index
            }
        }
        return acc
    }, [])
    const fourth_step_final = fourth_step.slice(0, fourth_step_assist_index+1)

    // 5단계
    const fifth_step = fourth_step_final.length == 0 ? ["a"] : fourth_step_final
    
    // 6단계
    const sixth_step = fifth_step.length >= 16 ? fifth_step.slice(0, 15) : fifth_step
    const sixth_step_assist_index = sixth_step.length - sixth_step.slice().reverse().findIndex(element => element !== ".");
    const sixth_step_final = sixth_step.slice(0, sixth_step_assist_index);
    const sixth_step_final_length = sixth_step_final.length;
    
    // 7단계
    const seventh_step = sixth_step_final_length <= 2 ? [...sixth_step_final, ...Array(3 - sixth_step_final_length).fill(sixth_step_final[sixth_step_final_length - 1])]
    : sixth_step_final;

    // 출력
    const answer = seventh_step.join("")
    return answer
}

풀이 방법

  1. map, toLowerCase 사용
  2. reduce, includes, push 사용
  3. length 사용 => 괄호 없음 주의
  4. reduce의 index값, slice 사용
  5. 삼항 연산자 사용 => 조건 ? 참 값 : 거짓 값
  6. reverse, findIndex 사용 => 뒤에서부터 "."이 아닌 값을 찾아서 인덱스값 반환
  7. ES6 이상의 자바스크립트 버전 => 스프레드 연산자(...) 사용
  8. join("")을 이용해서 출력

다른 풀이

function solution(new_id) {
    let result = new_id
        .toLowerCase() // 1단계: 모든 대문자를 소문자로 변환
        .replace(/[^\w-_.]/g, '') // 2단계: 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거
        .replace(/\.{2,}/g, '.') // 3단계: 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환
        .replace(/^\.|\.$/g, '') // 4단계: 마침표(.)가 처음이나 끝에 위치한다면 제거
        .replace(/^$/, 'a') // 5단계: 빈 문자열이라면, "a"를 대입
        .slice(0, 15) // 6단계: 길이가 16자 이상이면, 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거
        .replace(/\.$/, ''); // 6단계의 후처리: 만약 제거 후 마침표(.)가 끝에 위치한다면 제거
    
    // 7단계: 길이가 2자 이하라면, 마지막 문자를 길이가 3이 될 때까지 반복해서 끝에 붙임
    result = result.padEnd(3, result[result.length - 1]);

    return result;
}

느낀점

  • 아직 가야할 길이 멀었다 ㅎㅎ
  • 정규표현식을 빨리 배워야 더 간결하고 가독성 높게 짤 수 있을 것 같다...