코테: 신규 아이디 추천

Yeongjong Kim·2021년 12월 22일
0

본 문서는 프로그래머스(programmers.co.kr)에 기제된 카카오 2021년 블라인드 테스트를 기준으로 작성하였습니다.

신규 아이디 추천

문제

입력된 계정 id(string)이 조건에 맞지 않은 경우 주어진 프로세스에 따라 올바른 계정 id를 추천해주는 문제입니다.

계정 규칙

  • 길이는 3자 이상 15자 이하여야 합니다.
  • 아이디는 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.) 문자만 사용할 수 있습니다.
  • 단, 마침표(.)는 처음과 끝에 사용할 수 없으며 또한 연속으로 사용할 수 없습니다.

규칙에 맞지 않은 경우 추천 계정 생성 로직

  1. 1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
  2. 2단계 newid에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(), 마침표(.)를 제외한 모든 문자를 제거합니다.
  3. 3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
  4. 4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
  5. 5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
  6. 6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
    만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
  7. 7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.

문제 풀이 아이디어 생각해보기

  1. 조건문을 사용하여 유효한 아이디를 입력했는지 확인하는 함수 작성
  2. 유효하지 않은 아이디는 로직에 맞게 수정후 반환하기

풀이

  1. 유효 아이디 검증 함수는 정규표현식을 이용하기로 했다. 정규표현식중 test라는 메서드를 사용하면 string이 정규표현식과 매칭되는지 확인 후 boolean 형태로 값을 반환한다.

검증함수 코드

function isVaildId(id) {
  if (typeof id !== 'string'
      || !(id.length >= 3 && id.length <= 15)
      || /[^a-z\d-_.]/.test(id)
      || /^\.|\.$|[.]{2, }/.test(id)
     ) {
    return false;
  }

  return true;
}

추천아이디 코드

function getRecommendId(id) {
  let recommendId = id
    .toLowerCase()
    .replace(/[^a-z\d-_.]/g, '')
    .replace(/\.{2,}/g, '.')
    .replace(/^\.|\.$/g, '')
    .replace(/^$/, 'a')
    .slice(0, 15)
    .replace(/\.$/g, '');

  if (recommendId.length <= 2) {
    const lastChar = recommendId[recommendId.length - 1];
    
    while(recommendId.length <= 2) {
      recommendId = recommendId.concat(lastChar);
    }
  }
  
  return recommendId;
}

전체 코드

function solution(new_id) {
  function isVaildId(id) {
    if (typeof id !== 'string'
        || !(id.length >= 3 && id.length <= 15)
        || /[^a-z\d-_.]/.test(id)
        || /^\.|\.$|[.]{2, }/.test(id)
       ) {
      return false;
    }

    return true;
  }

  function getRecommendId(id) {
    let recommendId = id
      .toLowerCase()
      .replace(/[^a-z\d-_.]/g, '') // 소문자, 숫자, -, _, . 을 제외한 모든 string 제거
      .replace(/\.{2,}/g, '.') // .이 2번 이상 반복되는지 확인하여 .으로 바꾼다 이는 .+로 사용하여 1번이상 반복되었을 때로 치환 가능하다.
      .replace(/^\.|\.$/g, '') // .으로 시작하거나 끝나는 경우 제거
      .replace(/^$/, 'a') // 빈문자열인지 확인하는 방법으로 ^$를 사용할 수 있다.
      .slice(0, 15)
      .replace(/\.$/g, '');

    if (recommendId.length <= 2) {
      const lastChar = recommendId[recommendId.length - 1];
      
      while(recommendId.length <= 2) {
        recommendId = recommendId.concat(lastChar);
      }
    }
    
    return recommendId;
  }

  return isVaildId(new_id) 
    ? new_id
  	: getRecommendId(new_id)
}

다른 사람 풀이

function solution(new_id) {
    const answer = new_id
        .toLowerCase() // 1
        .replace(/[^\w-_.]/g, '') // 2
        .replace(/\.+/g, '.') // 3
        .replace(/^\.|\.$/g, '') // 4
        .replace(/^$/, 'a') // 5
        .slice(0, 15)
    	.replace(/\.$/, ''); // 6
  
    const len = answer.length;
  
    return len > 2 ? answer : answer + answer.charAt(len - 1).repeat(3 - len);
}

id가 유효한지 검증 코드하는 부분을 함수화 하여 사용한 것 외에는 전체적으로 코드 로직이 비슷하다.

이 코드를 보고 배운점은 answer의 길이를 미리 구하고 그에 따라 repeat 메서드를 사용해 마지막 문자값을 반복시키고 덧 붙였다는 점이다.

확실히 while보다는 가독성이 좋은 듯 하며, while을 사용했을 때 무한으로 반복될지도 모른다는 불안함을 해소시켜주는 것 같다.

profile
Front 💔 End

0개의 댓글