성격 유형 검사하기

2020 KAKAO TECH INTERNSHIP

  ·  4 min read

문제 설명 #

문제 개요 #

나만의 카카오 성격 유형 검사지를 만들기 위한 문제이다.

성격 유형 검사는 다음과 같은 네 가지 지표를 기반으로 성격 유형을 구분한다:1

지표 번호성격 유형
1번 지표라이언형(R), 튜브형(T)
2번 지표콘형(C), 프로도형(F)
3번 지표제이지형(J), 무지형(M)
4번 지표어피치형(A), 네오형(N)

검사지는 총 n개의 질문으로 구성되며, 각 질문은 위 지표 중 하나의 성격 유형 점수를 결정한다. 질문에 대한 선택지는 7가지이며, 선택에 따라 점수가 부여된다.

  • 매우 비동의: 비동의 관련 성격 유형에 3점 부여
  • 비동의: 비동의 관련 성격 유형에 2점 부여
  • 약간 비동의: 비동의 관련 성격 유형에 1점 부여
  • 모르겠음: 점수 없음
  • 약간 동의: 동의 관련 성격 유형에 1점 부여
  • 동의: 동의 관련 성격 유형에 2점 부여
  • 매우 동의: 동의 관련 성격 유형에 3점 부여

결과는 모든 질문에서 계산된 점수를 더하여 각 지표에서 더 높은 점수를 가진 성격 유형으로 결정된다. 만약 점수가 같다면 사전 순으로 빠른 성격 유형이 선택된다.


입력과 출력 #

입력 #

  1. survey: 질문마다 성격 유형 지표를 나타내는 문자열 배열 (ex. [“AN”, “CF”, “MJ”, “RT”, “NA”])
  2. choices: 검사자가 각 질문에 대해 선택한 선택지 (1~7 사이의 정수로 표현)

출력 #

지표 번호 순서대로 검사자의 성격 유형을 반환하는 문자열 (ex. “TCMA”)


예제 분석 #

입출력 예 #1 #

Input:

  • survey = [“AN”, “CF”, “MJ”, “RT”, “NA”]
  • choices = [5, 3, 2, 7, 5]

점수 계산:

질문선택지비동의 성격 유형동의 성격 유형부여된 점수결과
AN5ANN +1N: 1
CF3CFC +1C: 1
MJ2MJM +2M: 2
RT7RTT +3T: 3
NA5NAA +1A: 1

최종 점수:

지표 번호성격 유형 점수최종 성격 유형
1번R: 0, T: 3T
2번C: 1, F: 0C
3번J: 0, M: 2M
4번A: 1, N: 1A (사전 순)

Output: “TCMA”


입출력 예 #2 #

Input:

  • survey = [“TR”, “RT”, “TR”]
  • choices = [7, 1, 3]

점수 계산:

질문선택지비동의 성격 유형동의 성격 유형부여된 점수결과
TR7TRR +3R: 3
RT1RTR +3R: 6
TR3TRT +1T: 1

최종 점수:

지표 번호성격 유형 점수최종 성격 유형
1번R: 6, T: 1R
2번C: 0, F: 0C (사전 순)
3번J: 0, M: 0J (사전 순)
4번A: 0, N: 0A (사전 순)

Output: “RCJA”

문제 나누기 #

성격 유형 검사하기의 경우 복잡한 문제가 아니므로 여러 함수를 만들지 않고 바로 main 함수에서 코드를 작성할 수 있었다. 크게 보면 choices를 순회하면서 각 성향 지표마다 점수를 계산한 뒤 4가지 지표에 포함되는 성격 유형 중 우세 성향을 선택하여 answer로 리턴하면 된다.

choices를 순회할 때 각 점수는 4점보다 작으면 4 - choice 점수를 해당 성격 유형에 더하고 4점보다 크면 choice 점수 - 4 만큼의 점수를 해당 성격 유형에 더해주면 된다.

성격 유형은 4가지 지표마다 2개씩 존재하는데 각각 (R, T), (C, F), (J, M), (A, N)이 있다. 이를 순서대로 char 배열에 정리하여 두어 앞의 유형의 점수가 크거나 같으면 앞의 유형을 우세 성향으로 정할 수 있다. 같은 경우는 사전순으로 앞에 오는 것을 선택하는데 위의 순서는 이미 사전순으로 정렬이 되어 있기 때문이다.

만약 정렬이 되어 있지 않아면 vector를 이용해서 정렬할 수 있을것이다.

문제 해결하기 #


char character_type[4][2] = {{'R','T'},{'C','F'},{'J','M'},{'A','N'}};

std::string getDominantCharacter(char first, char second, std::map<char, int> character){
    if(character[first] < character[second]){
        return std::string() + second;
    }else{
        return std::string() + first;
    } 
}

std::string solution(std::vector<std::string> survey, std::vector<int> choices){
    std::string answer = "";
    std::map<char, int> type_score;
    int index = 0;
    for(auto& choice : choices){
        auto temp_character = survey[index];
       	if(choice < 4){
            type_score[temp_character[0]] += (4-choice);
        }
        else if(choice > 4) {
            type_score[temp_character[1]] += (choice-4);
        }
        else {
           	;	 
        }
        index++;
    }
   
    for(const auto& item: character_type){
        answer += getDominantCharacter(item[0], item[1], type_score);
    }
    return answer;
}

문제 개선하기 #

  1. std::string()으로 char에서 string 변환 부분 수정

    std::string() + first의 코드 보다는 바로 std::string(1, first)를 통해 size()가 1인 string을 바로 만들 수 있다.

  2. enhanced loop과 index의 사용보다는 기존 for-loop을 사용하되 std::size_t로 사용할것

    for(std::size_t i = 0 ; i < choices.size() ; i++) {}

  3. char character_type[4][2]std::array<std::pair<char, char>, 4> character_type으로 변경

    for(const auto& [first, second] : character_type) {answer += getDo~~;) 로 코드 간결화 가능 pair의 경우 enhance loop 사용시 [first, second]와 같이 호출할 수 있다.

#include <string>
#include <vector>
#include <map>
#include <array>

std::string getDominantCharacter(char first, char second, const std::map<char, int>& character_scores) {
    if (character_scores.at(first) < character_scores.at(second)) {
        return std::string(1, second);
    }
    return std::string(1, first);
}

std::string solution(const std::vector<std::string>& survey, const std::vector<int>& choices) {
    std::string answer = "";
    
    // 성격 유형 초기화
    std::map<char, int> type_score = {
        {'R', 0}, {'T', 0},
        {'C', 0}, {'F', 0},
        {'J', 0}, {'M', 0},
        {'A', 0}, {'N', 0}
    };

    // 선택지 처리
    for (std::size_t i = 0; i < choices.size(); ++i) {
        char disagree = survey[i][0];
        char agree = survey[i][1];
        int choice = choices[i];
        
        if (choice < 4) {
            type_score[disagree] += (4 - choice);
        } else if (choice > 4) {
            type_score[agree] += (choice - 4);
        }
    }

    // 각 지표에서 우세 성향 선택
    const std::array<std::pair<char, char>, 4> character_type = {{
        {'R', 'T'}, {'C', 'F'}, {'J', 'M'}, {'A', 'N'}
    }};
    
    for (const auto& [first, second] : character_type) {
        answer += getDominantCharacter(first, second, type_score);
    }

    return answer;
}

  1. “코딩테스트 연습 - 성격 유형 검사하기,” 프로그래머스 스쿨. https://school.programmers.co.kr/learn/courses/30/lessons/118666 ↩︎