ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 20221007 TIL 코테 기출 문제 분석하기
    TIL 2022. 10. 7. 13:28

    기출문제는 반복된다.
    동일하게 나오지는 않더라도 유사한 개념이 사용된다.
    따라서 기출문제가 제일 중요하다.

    카카오 신입 공채 1차 코딩 테스트 난이도 하 문제들을 저번주와 이번주에 풀었다.
    (https://school.programmers.co.kr/learn/courses/30/lessons/17681?language=java,
    https://school.programmers.co.kr/learn/courses/30/lessons/17682?language=java)

    앞으로 코딩테스트 문제를 풀 때 기억하고 있어야 될 부분들을 살펴보자.

    1. 2진수

    컴퓨터는 2진수를 사용한다.
    따라서 프로그래밍을 하는 사람들은 2진수와 친하게 지내야 한다.
    그래서인지 2진수 관련된 문제가 코딩 테스트에서 많이 보인다.
    자주 나오는 것은 공식처럼 외워두는 것이 좋다.
    2진수 도출 코드는 외워두자.

        public String binary(int number) {
            String binary = "";
    
            while (number > 0) {
                binary = number % 2 + binary;
                number /= 2;
            }
    
            return binary;
        }

    Integer.toBinaryString 메소드를 사용할 수 있는 경우 사용해도 된다.

    2. 비트 연산

    비트 연산자를 사용하면 비트 연산이 진행된다.
    예를 들어 아래와 같은 문제에서는 비트 OR 연산으로 쉽게 9 | 30, 20 | 1, 28 | 21, 18 | 17, 11 | 28로 각 줄의 도출값을 10진수로 얻을 수 있다.
    즉, 비트 연산자를 사용하면 알아서 2진수에 해당하는 값의 각 비트에 대해 연산자 값에 따라 계산된다.

    3. 값 대체

    "10101"을 "# # #"와 같이 변환한다면, 1을 #로, 0을 " " (공백) 으로 대체하고 싶은 것이기 때문에
    replace("1", "#")와 replace("0", " ")를 사용하면 된다.

    4. 동일한 문자열 반복

    "111111" 와 같이 어떤 값 "1"을 특정 횟수 반복하고 싶다고 했을 때
    "1".repeat(횟수) 와 같이 사용할 수 있다.

    5. 정규식

    다트 게임 같은 문제는 정규식을 이용하면 각 기회에 해당하는 문자열을 받아오기 쉽다.
    각 기회에 대한 정규식을 표현해보면,
    점수에 대한 부분은 정수인데, 0에서 10 사이이므로 1자리에서 2자리의 digit에 해당한다.
    따라서 [0-9]{1,2}로 점수부분을 표현할 수 있고, (물론 더 정확히는 [0-9]0?로 표현할 수도 있다.)
    보너스는 S, D, T중 하나이므로 [SDT]로 보너스 부분을 표현할 수 있다.
    옵션은 *나 #이므로 [*#]로 나타낼 수 있고, 없을 수도 있으므로 ?를 붙여준다.
    따라서 정리하면 \d{1,2}[SDT][*#]? 로 표현할 수 있다.

    아래의 코드로 각각의 기회에 대한 문자열로 이뤄진 리스트를 뽑을 수 있다.

        public List<String> splitRound(String string) {
            List<String> rounds = new ArrayList<>();
    
            Pattern pattern = Pattern.compile("[0-9]{1,2}[SDT][*#]?");
    
            Matcher matcher = pattern.matcher(string);
    
            while(matcher.find()) {
                rounds.add(matcher.group());
            }
    
            return rounds;
        }


    split메소드가 받는 값 자체가 정규식이므로 split에서도 정규식을 이용할 수 있다.

    import java.util.ArrayList;
    import java.util.List;
    import java.util.Map;
    import java.util.Stack;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    import java.util.stream.Collectors;
    import java.util.stream.IntStream;
    
    class Solution {
        public int solution(String dartResult) {
            int answer = process(dartResult);
            return answer;
        }
    
        public List<String> splitRound(String string) {
            List<String> rounds = new ArrayList<>();
    
            Pattern pattern = Pattern.compile("[0-9]{1,2}[SDT][*#]?");
    
            Matcher matcher = pattern.matcher(string);
    
            while(matcher.find()) {
                rounds.add(matcher.group());
            }
    
            return rounds;
        }
    
        public int process(String string) {
            List<String> results = splitRound(string);
    
            List<Integer> values = new ArrayList<>();
    
            for (String result : results) {
                String[] words = result.split("[SDT]");
    
                int score = Integer.valueOf(words[0]);
    
                Pattern pattern = Pattern.compile("[SDT]");
    
                Matcher matcher = pattern.matcher(result);
    
                int bonus = 1;
    
                if (matcher.find()) {
                    if (matcher.group().equals("D")) {
                        bonus = 2;
                    }
    
                    if (matcher.group().equals("T")) {
                        bonus = 3;
                    }
                }
    
                values.add((int) Math.pow(score, bonus));
    
                if (words.length == 1) {
                    continue;
                }
    
                if (words[1].equals("*")) {
                    int lastIndex = values.size() - 1;
                    values.set(lastIndex, values.get(lastIndex) * 2);
    
                    if (lastIndex > 0) {
                        values.set(lastIndex - 1, values.get(lastIndex - 1) * 2);
                    }
                }
    
                if (words[1].equals("#")) {
                    int lastIndex = values.size() - 1;
                    values.set(lastIndex, -values.get(lastIndex));
                }
            }
    
            return values.stream().mapToInt(i -> i).sum();
        }
    }

    따라서 위와 같은 방식으로 다트 문제를 풀 수 있다.

    그리고 문자열이 같은지 비교할 때는 ==가 아닌 .equals()를 이용해야 된다는 점을 꼭 기억하자.

    코딩테스트 문제를 풀면서 기억해야 될 부분은 앞으로도 시간을 내서 꼭 정리하는 습관을 들이자!
    문제는 반복된다.

    댓글

Designed by Tistory.