JavaScript - 프로그래머스 레벨 : 1(18) - ORDER BY '정답률'

먹보·2023년 2월 8일
0

1. 신규아이디 추천

문제 설명 : 카카오에 입사한 신입 개발자 네오는 "카카오계정개발팀"에 배치되어, 카카오 서비스에 가입하는 유저들의 아이디를 생성하는 업무를 담당하게 되었습니다. "네오"에게 주어진 첫 업무는 새로 가입하는 유저들이 카카오 아이디 규칙에 맞지 않는 아이디를 입력했을 때, 입력된 아이디와 유사하면서 규칙에 맞는 아이디를 추천해주는 프로그램을 개발하는 것입니다.
다음은 카카오 아이디의 규칙입니다.

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

"네오"는 다음과 같이 7단계의 순차적인 처리 과정을 통해 신규 유저가 입력한 아이디가 카카오 아이디 규칙에 맞는 지 검사하고 규칙에 맞지 않은 경우 규칙에 맞는 새로운 아이디를 추천해 주려고 합니다.
신규 유저가 입력한 아이디가 new_id 라고 한다면,

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

function solution(new_id) {
    let answer = ''
    
    const firstStep = new_id.toLowerCase();

    const secAndThirdStep = firstStep.split('').filter((el) => el.match(/[0-9]|[a-z]|\-|\_|\./)).join('').replace(/\.+/g, '.')

    const fourthStep1 = secAndThirdStep.startsWith('.') ? secAndThirdStep.substring(1) : secAndThirdStep

    const fourthStep2 = fourthStep1.endsWith('.') ? fourthStep1.slice(0,-1) : fourthStep1

    const fifthStep1 = fourthStep2.replace(/\ /g, 'a');

    const fifthStep2 = fifthStep1.length == 0 ? 'a' : fifthStep1

    const sixthStep1 = fifthStep2.length >= 16 ? fifthStep2.slice(0,15) : fifthStep2;

    let seventhStep = sixthStep.endsWith('.') ? sixthStep.slice(0,-1) : sixthStep

    if(seventhStep.length <= 2){
        while(seventhStep.length < 3){
            seventhStep += seventhStep[seventhStep.length-1]
        }
        answer = seventhStep
    } else {
        answer = seventhStep
    }
    return answer
}
// 다른 사람의 답안 
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);
}

🗒️코멘트 : 음...뭔가 카카오톡에서 원했던 방식으로 푼 것 같지는 않다..

다른 모범 답안들을 보니 정규표현식을 제대로 이용해서 풀은 것 같던데..아직 정규표현식의 이해도가 부족한 것 같다.

그래서 직접 정규표현식을 다른 사람의 코드를 분석해 보았다.

  1. 알다시피 문자를 소문자로 바꿔주는 메서드
  2. .replace(/[^\w-_.]/g, '') [^x]는 'x는 제외한다'라는 뜻이고 \w는 알파벳+숫자를 뜻하니, 해석해보자면 알파벳과 숫자 그리고 [-,_,.] 3가지를 제외한 나머지를 전부 빈 문자열로 바꾼다는 뜻이다.
  3. .replace(/\.+/g, '.') 이건 나도 찾아서 써본 것인데 +싸인을 붙이면 앞에 온 표현이 1번 이상 반복된 곳을 뜻한다. 즉 여기서는 .이 1번 이상 반복된 모든 표현을 '.' 단 하나의 마침표로 교체한다는 뜻이다
  4. .replace(/^\.|\.$/g, '') 이게 조금 아쉬웠다. 시작과 ^로 시작을 표현하고 (헷갈리지 말아야 할 것은, 2번처럼 대괄호 안에 쓰였을 경우 제외라는 점이다), 표현 뒤 $로 끝을 표현할 수 있다는 사실을 간과했다..모르고 있었던 것은 아니었지만 응용력이 부족했던 것 같다.
  5. 여기서 $는 ^ 다음에 붙었으므로 빈 문자열을 a로 바꾼다는 뜻이다.
  6. 이런 식으로 다 변경하고 나서 문자열이 16 이상일 경우 앞까지 잘라주고 마지막이 마침표일 경우 제거해준다.
  7. len > 2 ? answer : answer + answer.charAt(len - 1).repeat(3 - len) Repeat..항상 생각난 문법 중 하나인데 이번에는 while을 써서 시도해봤다. 생각해보면 repeat이 더 성능이 좋았을 듯 싶다.

정규표현식 다음번에는 제대로 사용해보고 싶다.

2. 성격 유형 검사하기

문제 설명 : 나만의 카카오 성격 유형 검사지를 만들려고 합니다.
성격 유형 검사는 다음과 같은 4개 지표로 성격 유형을 구분합니다. 성격은 각 지표에서 두 유형 중 하나로 결정됩니다.

4개의 지표가 있으므로 성격 유형은 총 16(=2 x 2 x 2 x 2)가지가 나올 수 있습니다. 예를 들어, "RFMN"이나 "TCMA"와 같은 성격 유형이 있습니다.

검사지에는 총 n개의 질문이 있고, 각 질문에는 아래와 같은 7개의 선택지가 있습니다.

각 질문은 1가지 지표로 성격 유형 점수를 판단합니다.

예를 들어, 어떤 한 질문에서 4번 지표로 아래 표처럼 점수를 매길 수 있습니다.

이때 검사자가 질문에서 약간 동의 선택지를 선택할 경우 어피치형(A) 성격 유형 1점을 받게 됩니다. 만약 검사자가 매우 비동의 선택지를 선택할 경우 네오형(N) 성격 유형 3점을 받게 됩니다.

위 예시처럼 네오형이 비동의, 어피치형이 동의인 경우만 주어지지 않고, 질문에 따라 네오형이 동의, 어피치형이 비동의인 경우도 주어질 수 있습니다.
하지만 각 선택지는 고정적인 크기의 점수를 가지고 있습니다.

검사 결과는 모든 질문의 성격 유형 점수를 더하여 각 지표에서 더 높은 점수를 받은 성격 유형이 검사자의 성격 유형이라고 판단합니다. 단, 하나의 지표에서 각 성격 유형 점수가 같으면, 두 성격 유형 중 사전 순으로 빠른 성격 유형을 검사자의 성격 유형이라고 판단합니다.

질문마다 판단하는 지표를 담은 1차원 문자열 배열 survey와 검사자가 각 질문마다 선택한 선택지를 담은 1차원 정수 배열 choices가 매개변수로 주어집니다. 이때, 검사자의 성격 유형 검사 결과를 지표 번호 순서대로 return 하도록 solution 함수를 완성해주세요.

function solution(survey, choices) {
    let answer = '';
    const criteria = {
        R : 0,
        T : 0,
        C : 0,
        F : 0,
        J : 0,
        M : 0,
        A : 0,
        N : 0,
    }
    const scoreBasis = {
        1 : 3,
        2 : 2,
        3 : 1,
        4 : 0,
        5 : 1,
        6 : 2,
        7 : 3,
    }
    for(let i = 0 ; i < choices.length ; i++){
        if(choices[i] > 4){
            criteria[survey[i][1]] += scoreBasis[choices[i]]
        } else if (choices[i] < 4){
            criteria[survey[i][0]] += scoreBasis[choices[i]]
        }
    }
    answer += criteria['R'] >= criteria['T'] ? 'R' : 'T';
    answer += criteria['C'] >= criteria['F'] ? 'C' : 'F';
    answer += criteria['J'] >= criteria['M'] ? 'J' : 'M';
    answer += criteria['A'] >= criteria['N'] ? 'A' : 'N';
    return answer;
}

🗒️코멘트 : 문제는 쉬웠지만...굉장히 직관적으로 푼 문제라 그런지..씁쓸하다?

profile
🍖먹은 만큼 성장하는 개발자👩‍💻

0개의 댓글