Programmers LEVEL1 ⎮ 신규 아이디 추천

NOWANDHERE·2021년 2월 11일

Algorithm

목록 보기
1/4
post-thumbnail

[Programmers LEVEL1] 신규 아이디 추천


📗 문제 내용


[문제 링크]

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

[문제]

신규 유저가 입력한 아이디를 나타내는 new_id가 매개변수로 주어질 때, 네오가 설계한 7단계의 처리 과정을 거친 후의 추천 아이디를 return 하도록 solution 함수를 완성해 주세요.

[제한 사항]

  • new_id는 길이 1 이상 1,000 이하인 문자열입니다.
  • new_id는 알파벳 대문자, 알파벳 소문자, 숫자, 특수문자로 구성되어 있습니다.
  • new_id에 나타날 수 있는 특수문자는 -_.~!@#$%^&*()=+[{]}:?,<>/ 로 한정됩니다.

🧑🏼‍💻 나의 풀이


풀이 과정을 단계별로 주석을 달아서 설명해두었다. 1 ~ 7단계까지 문제에 나와 있는대로 차근차근 구현하려고 했는데 다른 분들의 풀이를 보니까 정말 쉽게 푸신 분들도 있었다.

function solution(new_id) {
  let answer = '';
  // step 1 : 모두 소문자로 치환
  new_id = new_id.toLowerCase();

  // step 2 : 알파벳 소문자, 숫자, 빼기, 밑줄, 마침표 제외 모든 문자 제거
  // 아스키 코드를 이용하여 제거했다.
  for (let i = 0; i < new_id.length; i++) {
    const ascii = new_id.charCodeAt(i);
    if (
      (97 <= ascii && ascii <= 122) ||
      (48 <= ascii && ascii <= 57) ||
      new_id[i] === '-' ||
      new_id[i] === '_' ||
      new_id[i] === '.'
    ) {
      answer += new_id[i];
    } else continue;
  }

  // step 3 : 마침표가 2번 이상 연속되면 하나의 마침표로 치환
  // 가장 최근에 추가한 문자가 마침표이고 지금 넣으려고 하는 문자가 마침표라면 넣지 않는식으로 구현했다.
  new_id = answer;
  answer = new_id[0];
  let prev = answer[0];
  for (let i = 1; i < new_id.length; i++) {
    const current = new_id[i];
    if (prev === '.' && current === '.') continue;
    answer += current;
    prev = current;
  }

  // step 4 : 마침표가 처음이나 끝에 위치하면 제거
  if (answer[0] === '.') answer = answer.slice(1);
  if (answer[answer.length - 1] === '.') answer = answer.slice(0, -1);

  // step 5 : 빈 문자열이라면 'a' 대입
  if (!answer) answer = 'a';

  // step 6 : 길이가 16 이상이면, 첫 15개 문자 제외한 나머지 문자 제거
  if (answer.length >= 16) {
    answer = answer.slice(0, 15);
    // 만약 제거 후 마침표가 끝에 있으면 제거
    if (answer[answer.length - 1] === '.') {
      answer = answer.slice(0, -1);
    }
  }

  // step 7 : 길이가 2 이하이면, 마지막 문자를 길이가 3이 될 때까지 문자열의 끝에 추가
  if (answer.length <= 2) {
    while (answer.length < 3) {
      answer += answer[answer.length - 1];
    }
  }
  return answer;
}

## 예시 1 ~ 5번
console.log(solution('...!@BaT#*..y.abcdefghijklm')); // 'bat.y.abcdefghi'
console.log(solution('z-+.^.'));                      // 'z--'
console.log(solution('=.='));                         // 'aaa'
console.log(solution('123_.def'));                    // '123_.def'
console.log(solution('abcdefghijklmn.p'));            // 'abcdefghijklmn'

다른 사람의 풀이


정규식을 이용한 풀이

멋진 풀이인 것 같다.

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);
}

for loop 를 한 번만 사용한 풀이

다른 분들의 풀이를 보고 많이 배운다.

function solution(nid) {
  var ans = '';
  for (let i = 0; i < nid.length; i++) {
    let c = nid[i].toLowerCase();
    if ('0123456789abcdefghijklmnopqrstuvwxyz.-_'.indexOf(c) === -1) continue;
    if (c === '.' && ans[ans.length - 1] === '.' && nid[i - 1]) continue;
    ans += c;
  }
  if (ans[0] === '.') ans = ans.slice(1);
  ans = ans.slice(0, 15);
  if (ans[ans.length - 1] === '.') ans = ans.slice(0, ans.length - 1);
  if (!ans) ans = 'a';
  while (ans.length < 3) ans += ans[ans.length - 1];
  return ans;
}

Reference

0개의 댓글