[JAVA | 2022 카카오 테크 인턴십] 성격 유형 검사하기

연어·2022년 11월 24일
0

algorithm

목록 보기
4/21

문제

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

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

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

  • 매우 비동의
  • 비동의
  • 약간 비동의
  • 모르겠음
  • 약간 동의
  • 동의
  • 매우 동의

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

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

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

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

  • 매우 동의나 매우 비동의 선택지를 선택하면 3점을 얻습니다.
  • 동의나 비동의 선택지를 선택하면 2점을 얻습니다.
  • 약간 동의나 약간 비동의 선택지를 선택하면 1점을 얻습니다.
  • 모르겠음 선택지를 선택하면 점수를 얻지 않습니다.

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

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

제한사항

  • 1 ≤ survey의 길이 ( = n) ≤ 1,000
    ✔ survey의 원소는 "RT", "TR", "FC", "CF", "MJ", "JM", "AN", "NA" 중 하나입니다.
    ✔ survey[i]의 첫 번째 캐릭터는 i+1번 질문의 비동의 관련 선택지를 선택하면 받는 성격 유형을 의미합니다.
    ✔ survey[i]의 두 번째 캐릭터는 i+1번 질문의 동의 관련 선택지를 선택하면 받는 성격 유형을 의미합니다.
    ✔ choices의 길이 = survey의 길이

  • choices[i]는 검사자가 선택한 i+1번째 질문의 선택지를 의미합니다.
    ✔ 1 ≤ choices의 원소 ≤ 7

choices
1매우 비동의
2비동의
3약간 비동의
4모르겠음
5약간 동의
6동의
7매우 동의

입출력 예

surveychoicesresult
["AN", "CF", "MJ", "RT", "NA"][5, 3, 2, 7, 5]"TCMA"
["TR", "RT", "TR"][7, 1, 3]"RCJA"

문제를 보고 먼저 느꼈던 것 -

  • 알파벳이 다 다르니 hashmap으로 가능할 것 같다
  • 선택지에 따라서 점수를 얻는 건 알겠다 ➡ '매우 비동의'도 3점이고, '매우 동의'도 3점인데 choices는 1 ~ 7이다 ➡ 당황
  • 점수가 같으면 사전 순으로 빠른 유형을 선택한다 ➡ '빠른 순', '느린 순' 이라는 표현만 보면 정렬을 해야 할 것만 같은 나는 파블로프의 개 스러웠다
  • return 타입이 String이니, String 타입으로 계속 붙이기보단 StringBuilder를 사용해보자

흐름
1. survey의 i 값에서 choices가 1~3이면 앞문자, 5~7이면 뒷문자를 계산한다.
2. hashmap으로 각 알파벳의 점수를 계산한다.
3. value가 높은 알파벳을 골라 지표 순으로 append한다.

결과

첫번째 코드(실패)

		String answer = "";
        StringBuilder sb = new StringBuilder(answer);
        Map<String, Integer> mbti = new HashMap<>();

        for (int i = 0; i < survey.length; i++) {
            int value = choices[i];
            if (1 <= value && value <= 3) {
                mbti.put(String.valueOf(survey[i].charAt(0)), mbti.getOrDefault(String.valueOf(survey[i].charAt(0)), 0) + choices[i] == 1 ? 3 : (choices[i] == 3 ? 1 : 2));
            } else if (5 <= value && value <= 7) {
                mbti.put(String.valueOf(survey[i].charAt(1)), mbti.getOrDefault(String.valueOf(survey[i].charAt(1)), 0)+choices[i] == 7 ? 3 : (choices[i] == 5 ? 1 : 2));
            }
        }

        sb.append(mbti.get("R") >= mbti.get("T") ? "R" : "T")
        .append(mbti.get("C") >= mbti.get("F") ? "C" : "F")
        .append(mbti.get("J") >= mbti.get("M") ? "J" : "M")
        .append(mbti.get("A") >= mbti.get("N") ? "A" : "N");

코드를 다 작성하고 보니 조금 웃겼다.
그냥 생각 나는 대로 짰더니 이렇게 작성해도 되는 게 맞는가..? 싶었다.
choices의 값을 가져다가 점수로 계산을 하려니 첫번째 시도는 이렇게 길고 복잡하게 짜이게 되었다.
뭔가 이건 아닌 것 같은데..
돌려봤을 때 결과는 잘 나오긴 하고..
의심하며 프로그래머스에서 제출 후 채점하니 테스트 실패가 떴다!
실패가 나올 만도 할 것 같다 라고 생각하면서 웃겼던 마음을 뒤로 하고 다시 짜보기 💨

두번째 코드 (통과!)

public class Main {
    static String solution(String[] survey, int[] choices) {
        String answer = "";
        StringBuilder sb = new StringBuilder(answer);
        Map<String, Integer> mbti = new HashMap<>();

        for (int i = 0; i < survey.length; i++) {
            int value = choices[i];
            if (1 <= value && value <= 3) {
                mbti.put(String.valueOf(survey[i].charAt(0)), mbti.getOrDefault(String.valueOf(survey[i].charAt(0)), 0) + 4 - value);
            } else if (5 <= value && value <= 7) {
                mbti.put(String.valueOf(survey[i].charAt(1)), mbti.getOrDefault(String.valueOf(survey[i].charAt(1)), 0) + value - 4);
            }
        }

        sb.append(mbti.getOrDefault("R", 0) >= mbti.getOrDefault("T", 0) ? "R" : "T")
        .append(mbti.getOrDefault("C", 0) >= mbti.getOrDefault("F", 0) ? "C" : "F")
        .append(mbti.getOrDefault("J", 0) >= mbti.getOrDefault("M", 0) ? "J" : "M")
        .append(mbti.getOrDefault("A", 0) >= mbti.getOrDefault("N", 0) ? "A" : "N");

        // System.out.println(sb.toString());
        answer = sb.toString();
        return answer;
    }

    public static void main(String[] args) {
        String[] survey = {"AN", "CF", "MJ", "RT", "NA"};
        int[] choices = {5, 3, 2, 7, 5};

//        String[] survey = {"TR", "RT", "TR"};
//        int[] choices = {7, 1, 3};
        solution(survey, choices);
    }
}
  • choices[i] == 1 ? 3 : (choices[i] == 3 ? 1 : 2)
    ➡ 4 - value
  • choices[i] == 7 ? 3 : (choices[i] == 5 ? 1 : 2)
    ➡ value - 4
  • .append(mbti.get("C") >= mbti.get("F") ? "C" : "F")
    ➡ .append(mbti.getOrDefault("C", 0) >= mbti.getOrDefault("F", 0) ? "C" : "F")

점수 계산은 삼항 연산에서 아무 점수가 더해지지 않는 4점을 기준으로 식을 변경했고,
.append부분은 hashmap에 계산되지 않은 알파벳이 있을 경우를 고려해서 변경했다.

재밌군 😆

출처 - https://school.programmers.co.kr/learn/courses/30/lessons/118666

profile
끄적이는 개발자

0개의 댓글