ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Programmers] 혼자서 하는 틱택토 / ⭕
    Algorithm/Programmers 2024. 7. 11. 18:59
     

    프로그래머스

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

    programmers.co.kr

     

    1. 제출 코드 (1시간 23분 32초 / 구현)

    import java.util.*;
    
    class Solution {
        static ArrayList<Character>[] map;
        public int solution(String[] board) {
            int answer = 1;
            int p1 = 0;
            int p2 = 0;
            map = new ArrayList[3];
            
            for(int i = 0; i < 3; i++) {
                map[i] = new ArrayList<>();
                for(int j = 0; j < 3; j++) {
                    if(board[i].charAt(j) == 'O') {
                        p1++;
                    } else if(board[i].charAt(j) == 'X'){
                        p2++;
                    }
                    map[i].add(board[i].charAt(j));
                }
            }
            /* 
            1. 선공이 후공보다 2개 이상일 수 없음
            2. 선공보다 후공이 더 많을 수 없음
            */
            if(p1 - p2 >= 2 || p1 - p2 < 0) return 0;
    
            int[] rowCnt = rowCount();
            int[] colCnt = colCount();
            int[] crossCnt = crossCount();
            // 3. 각 행, 열, 대각선에서는 2개 이상의 승리 조건을 만들 수 없음
            if(rowCnt[0] >= 2 || rowCnt[1] >= 2 || colCnt[0] >= 2 || colCnt[1] >= 2 || crossCnt[0] >= 2 || crossCnt[1] >= 2) {
                return 0;
            }
    
            // 4. 선공이 이겼는데 후공이 계속 공격할 수 없음
            if(rowCnt[0] == 1 || colCnt[0] == 1 || crossCnt[0] == 1) {
                if(p1 == p2) return 0;
            }
            // 5. 후공이 이겼는데 선공이 계속 공격할 수 없음
            if(rowCnt[1] == 1 || colCnt[1] == 1 || crossCnt[1] == 1) {
                if(p1 > p2) return 0;
            }
            return answer;
        }
        
        static int[] rowCount() {
            int o_cnt = 0;
            int x_cnt = 0;
            for(int i = 0; i < 3; i++) {
                boolean isValid = true;
                char temp = map[i].get(0);
                if(temp == '.') continue;
                for(int j = 1; j < 3; j++) {
                    if(temp == 'O' && map[i].get(j) != 'O') {
                        isValid = false;
                        break;
                    } else if(temp == 'X' && map[i].get(j) != 'X'){
                        isValid = false;
                        break;
                    }
                }
                if(isValid) {
                    if(temp == 'O') o_cnt++;
                    else x_cnt++;
                }
            }
            return new int[] {o_cnt, x_cnt};
        }
        
        static int[] crossCount() {
            int o_cnt = 0;
            int x_cnt = 0;
            char leftTemp = map[0].get(0);
            if(leftTemp != '.'){
                boolean leftValid = true;
                for(int i = 1; i < 3; i++) {
                    if(leftTemp == 'O' && map[i].get(i) != 'O') {
                        leftValid = false;
                        break;
                    } else if(leftTemp == 'X' && map[i].get(i) != 'X'){
                        leftValid = false;
                        break;
                    }
                }
                if(leftValid) {
                    if(leftTemp == 'O') o_cnt++;
                    else x_cnt++;
                }
            }
            char rightTemp = map[0].get(2);
            if(rightTemp != '.') {
                boolean rightValid = true;
                for(int i = 1; i < 3; i++) {
                    if(rightTemp == 'O' && map[i].get(2 - i) != 'O') {
                        rightValid = false;
                        break;
                    } else if(rightTemp == 'X' && map[i].get(2 - i) != 'X'){
                        rightValid = false;
                        break;
                    }
                }
                if(rightValid) {
                    if(rightTemp == 'O') o_cnt++;
                    else x_cnt++;
                }
            }
            return new int[] {o_cnt, x_cnt};
        }
        
         static int[] colCount() {
            int o_cnt = 0;
            int x_cnt = 0;
            for(int i = 0; i < 3; i++) {
                boolean isValid = true;
                char temp = map[0].get(i);
                if(temp == '.') continue;
                for(int j = 1; j < 3; j++) {
                    if(temp == 'O' && map[j].get(i) != 'O') {
                        isValid = false;
                        break;
                    } else if(temp == 'X' && map[j].get(i) != 'X'){
                        isValid = false;
                        break;
                    }
                }
                if(isValid) {
                    if(temp == 'O') o_cnt++;
                    else x_cnt++;
                }
            }
            return new int[] {o_cnt, x_cnt};
        }
    }

     

     

    2. 구현 로직

    1. 게임판에서 선공과 후공의 개수를 Count
    2. 선공이 후공보다 2개 이상일 수 있는 경우와 선공보다 후공이 더 많을 수 없으니 return 0
    3. 각 행, 열, 대각선에서 틱택토 게임의 정답을 만족하는 조건을 Count
    4. 선공 또는 후공이 각 행, 열, 대각선에서 2개 이상의 정답이 존재할 수 없으니 return 0
    5. 선공이 이겼는데 후공이 계속 공격할 수 없으니 행, 열, 대각선에서 정답을 만족하는 조건이 있다면 선공 = 후공 일 때 return 0 (<는 위에서 필터됨)
    6. 후공이 이겼는데 선공이 게속 공격할 수 없으므로 선공 > 후공 일 때 return 0
    7. 이 외에 경우는 모두 진행 가능한 상황으로 정답 추출

     

    3. 유의할 점

    • 선공이 이겼는데 선공이 공격하는 경우를 생각 못 해서 테스트 케이스 일부를 틀려서 예외 상황을 잘 생각해야 할 거 같다.

    'Algorithm > Programmers' 카테고리의 다른 글

    [Programmers] 무인도 여행 / ⭕  (4) 2024.07.16
    [Programmers] 호텔 대실 / ⭕  (0) 2024.07.15
    [Programmers] 미로 탈출 / ⭕  (1) 2024.07.10
    [Programmers] 리코쳇 로봇 / ⭕  (0) 2024.07.09
    [Programmers] 광물 캐기 / ⭕  (0) 2024.07.08
Designed by Tistory.