개발일기

프로그래머스 성격 유형 검사하기 본문

Algorithm/알고리즘

프로그래머스 성격 유형 검사하기

한둥둥 2024. 4. 4. 15:33

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

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

 

1. 문제풀이 가장 우선적으로 HashMap을 사용해서 풀어야겠다고 결정하였다. 여기서 이러한 결정을 하게 된 계기는 각각의 R, T, C, F를 정렬 단어별로 정렬해주어야 된다고 판단하였고 점수가 없다면 그러한 이유에서 HashMap을 선택하게 되었는데 그렇게까지는 할 필요가 없었음. 이것에 대한 자세한 이유는 아래에서 설명하겠다. 

 

2. survey에서 들어온 각각의 값들을 charAt을 통하여 firstChar , twoChar 첫 번째 문자, 두 번째 문자로 만들어주었다. 그 이외에 1~3 , 4 , 5~ 7 이런식으로 나누어서 판단하여 각각의 성격유형에 대해서 점수를 더해준다.  여기서 나같은 경우는 글을 이해못해서 순서를 바꿔서 더해주어 문제가 되었음.. 글 읽는게 너무어렵다.. 

 

3. 이렇게 해주었다면 성격 유형검사는 사실상 어려개의 성격들이 들어오는게 아닌 특정 단어만 확정적으로 들어오는 것이기 때문에 나는 삼항 연산자를 통해서 같다면 앞에 단어가 먼저 나오는게 append를 사용해서 만들어줌. 

 

import java.util.*;

class Solution {
    public String solution(String[] survey, int[] choices) {
        StringBuilder answer = new StringBuilder();
        
        int []scoreArr = {3, 2, 1, 0, 1, 2, 3};
        
        Map<Character,Integer> map = new HashMap<>();
        for(int i=0;i<survey.length; i++){
            char firstChar = survey[i].charAt(0);
            char twoChar = survey[i].charAt(1);
            if(choices[i] > 4) map.put(twoChar , map.getOrDefault(twoChar,0 ) + scoreArr[choices[i]-1]);
            else if(choices[i] > 0 && choices[i] < 4) map.put(firstChar, map.getOrDefault(firstChar, 0) + scoreArr[choices[i]-1]);
        }
    
        answer.append(map.getOrDefault('R',0)>=map.getOrDefault('T',0) ? "R" : "T");
        answer.append(map.getOrDefault('C',0)>=map.getOrDefault('F',0) ? "C" : "F");
        answer.append(map.getOrDefault('J',0)>=map.getOrDefault('M',0) ? "J" : "M");
        answer.append(map.getOrDefault('A',0)>=map.getOrDefault('N',0) ? "A" : "N");
        return answer.toString();
    }
}

 

 

최석현님의 굉장히 인상깊었던 풀이

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

class Solution {
    public String solution(String[] survey, int[] choices) {
        return new Survey(survey)
                .report(choices)
                .getReport();
    }

    public static class Report {
        private final String report;

        public Report(String report) {
            this.report = report;
        }

        public String getReport() {
            return report;
        }
    }

    public static class Survey {
        private final List<CharacterType> survey;

        public Survey(String[] survey) {
            this(Arrays.stream(survey)
                    .map(CharacterType::findType)
                    .collect(Collectors.toList()));
        }

        public Survey(List<CharacterType> survey) {
            this.survey = survey;
        }

        public Report report(int[] scores) {
            return IntStream.range(0, survey.size())
                    .mapToObj(i -> new Choice(survey.get(i), scores[i]))
                    .collect(Collectors.collectingAndThen(Collectors.toList(), this::report));
        }

        public Report report(List<Choice> choices) {
            Map<CharacterType, Integer> report = CharacterType.getAllTypes().stream()
                    .collect(Collectors.toMap(Function.identity(), __ -> 0));

            choices.forEach(choice -> report.put(choice.getCharacterType(), 
                    report.get(choice.getCharacterType()) + choice.score));

            return report.entrySet().stream()
                    .sorted(Comparator.comparing(entry -> entry.getKey().indicator))
                    .map(entry -> {
                        if (entry.getValue() > 0) {
                            return entry.getKey().getUpperElement();
                        }

                        return entry.getKey().getLowerElement();
                    })
                    .map(CharacterTypeElement::name)
                    .collect(Collectors.collectingAndThen(Collectors.joining(), Report::new));
        }
    }

    public static class Choice {
        private final CharacterType characterType;
        private final Integer score;

        public Choice(String characterType, Integer score) {
            this(CharacterType.findType(characterType), score);
        }

        public Choice(CharacterType characterType, Integer score) {
            if (characterType.isReversed()) {
                this.characterType = characterType.reverse();
                this.score = Math.abs(7 - score) + 1 - 4;
            } else {
                this.characterType = characterType;
                this.score = score - 4;
            }
        }

        public CharacterType getCharacterType() {
            return characterType;
        }

        public Integer getScore() {
            return score;
        }
    }

    public enum CharacterType {
        RT(1, false), TR(1, true),
        CF(2, false), FC(2, true),
        JM(3, false), MJ(3, true),
        AN(4, false), NA(4, true);

        private final Integer indicator;
        private final boolean isReversed;

        CharacterType(Integer indicator, boolean isReversed) {
            this.indicator = indicator;
            this.isReversed = isReversed;
        }

        public static CharacterTypeElement findDefaultElementByIndicator(int indicator) {
            return Arrays.stream(values())
                    .filter(type -> type.indicator.equals(indicator))
                    .findFirst()
                    .map(CharacterType::getLowerElement)
                    .orElseThrow();
        }

        public static CharacterType findType(String type) {
            return Arrays.stream(values())
                    .filter(characterType -> characterType.name().equals(type))
                    .findAny()
                    .orElseThrow();
        }

        public static List<CharacterType> getAllTypes() {
            return List.of(RT, CF, JM, AN);
        }

        public CharacterType reverse() {
            return findType(new StringBuilder(this.name()).reverse().toString());
        }

        public boolean isReversed() {
            return isReversed;
        }

        public CharacterTypeElement getLowerElement() {
            return CharacterTypeElement.findType(String.valueOf(this.name().charAt(0)));
        }

        public CharacterTypeElement getUpperElement() {
            return CharacterTypeElement.findType(String.valueOf(this.name().charAt(1)));
        }
    }

    public enum CharacterTypeElement {
        R, T, C, F, J, M, A, N;

        public static CharacterTypeElement findType(String element) {
            return Arrays.stream(values())
                    .filter(characterType -> characterType.name().equals(element))
                    .findAny()
                    .orElseThrow();
        }
    }
}

 

다른 코드들을 보면 아 쫌 뻔하네? 라는 생각이 들었는데 해당 코드를 보면서 든 생각은 전혀 뻔하지 않고 색다른 방식으로 접근했구나라는 생각을 가지게되었다.