[코드 트리] 단 한 번의 2048 시도 (JAVA)

이형걸·2025년 1월 15일
0

Problem Solving

목록 보기
11/23

[코드 트리] 단 한 번의 2048 시도 (JAVA)

스크린샷 2025-01-15 오후 4 39 27

🗒️알고리즘 분류

#시뮬레이션 #simulation

✏️문제 설명

4x4 크기의 2차원 배열 안에 0을 포함한 2의 배수 들이 채워져 있다.

‘L’, ‘R’, ‘U’, ‘D’ 의 방향 중 한가지가 주어지고, 해당 방향에 따라 중력이 작용하여 배열 안의 값들이 전부 밀리게 된다.

이때 같은 값의 숫자들은 서로 합쳐진다. (ex: 2,2 → 4)

하지만, 같은 값의 숫자들이 합쳐지는 것은 딱 한번만 일어나기 때문에 연쇄적으로 숫자 합침이 일어나면 안된다. (ex: 2,2,4,2 → 4,4,2)

📌기억할 만한 포인트

난 여기서 무식하게 4 가지 방향으로 작용하는 중력과 숫자 합침을 4가지 경우에 따라서 전부 구현해줬다.(그래도 다행히 큰 무리 없이 깔끔하게 구현했다.)

하지만, 역시 좋은(?) 풀이는 아니었다.

해설에서는 이렇게 방향이 여러가지로 나오는 경우에는 구현하기 가장 쉬운 한가지 방향만 구현하고, 나머지는 90도 회전(rotate)으로 해결하는 것을 제안한다.

기억해두자!

📝처음 작성한 풀이 코드(JAVA)

import java.util.*;

public class Main {
    private static final int BLANK = 0;
    private static int N = 4;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = 4;  
        int[][] arr = new int[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                arr[i][j] = sc.nextInt();
            }
        }

        char direction = sc.next().charAt(0);

        sc.close();

        gravityByDirection(arr, direction);
        assembleNumber(arr, direction);
        gravityByDirection(arr, direction);
        
        print(arr);
        
        return;
    }

    private static void gravityByDirection(int[][] arr, char direction) {
        if (direction == 'L') {
            for (int i = 0; i < 4; ++i) {
                int[] temp = new int[4];
                int endOfTempArr = 0;
                for (int j = 0; j < 4; ++j) {
                    if (arr[i][j] != BLANK) {
                        temp[endOfTempArr++] = arr[i][j];
                    }
                }
                for (int j = 0; j < 4; ++j) {
                    arr[i][j] = temp[j];
                }
            }
        } else if (direction == 'R') {
            for (int i = 0; i < 4; ++i) {
                int[] temp = new int[4];
                int endOfTempArr = 3;
                for (int j = 3; j >= 0; --j) {
                    if (arr[i][j] != BLANK) {
                        temp[endOfTempArr--] = arr[i][j];
                    }
                }
                for (int j = 3; j >= 0; --j) {
                    arr[i][j] = temp[j];
                }
            }
        } else if (direction == 'U') {
            for (int j = 0; j < 4; ++j) {
                int[] temp = new int[4];
                int endOfTempArr = 0;
                for (int i = 0; i < 4; ++i) {
                    if (arr[i][j] != BLANK) {
                        temp[endOfTempArr++] = arr[i][j];
                    }
                }
                for (int i = 0; i < 4; ++i) {
                    arr[i][j] = temp[i];
                }
            }
        } else if (direction == 'D') {
            for (int j = 0; j < 4; ++j) {
                int[] temp = new int[4];
                int endOfTempArr = 3;
                for (int i = 3; i >= 0; --i) {
                    if (arr[i][j] != BLANK) {
                        temp[endOfTempArr--] = arr[i][j];
                    }
                }
                for (int i = 3; i >= 0; --i) {
                    arr[i][j] = temp[i];
                }
            }
        }
    }

    private static void assembleNumber(int[][] arr, char direction) {
        if (direction == 'L') {
            for (int i = 0; i < 4; ++i) {
                for (int j = 1; j < 4; ++j) {
                    if (arr[i][j-1] == arr[i][j]) {
                        arr[i][j-1] += arr[i][j];
                        arr[i][j] = BLANK;
                    }
                }
                
            }
        } else if (direction == 'R') {
            for (int i = 0; i < 4; ++i) {
                for (int j = 3; j > 0; --j) {
                    if (arr[i][j-1] == arr[i][j]) {
                        arr[i][j] += arr[i][j-1];
                        arr[i][j-1] = BLANK;
                    }
                }
            }
        } else if (direction == 'U') {
            for (int j = 0; j < 4; ++j) {
                for (int i = 1; i < 4; ++i) {
                    if (arr[i-1][j] == arr[i][j]) {
                        arr[i-1][j] += arr[i][j];
                        arr[i][j] = BLANK;
                    }
                }
            }
        } else if (direction == 'D') {
            for (int j = 0; j < 4; ++j) {
                for (int i = 3; i > 0; --i) {
                    if (arr[i-1][j] == arr[i][j]) {
                        arr[i][j] += arr[i-1][j];
                        arr[i-1][j] = BLANK;
                    }
                }
            }
        }
    }

    private static void print(int[][] arr) {
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 4; ++j) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println();
    }
}

📝rotate 메서드를 적용한 풀이 코드(JAVA)

import java.util.*;

public class Main {
    private static final int BLANK = 0;
    private static int N = 0;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = 4;  
        int[][] arr = new int[n][n];

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                arr[i][j] = sc.nextInt();
            }
        }

        char direction = sc.next().charAt(0);

        sc.close();

        N = n;

        tilt(arr, direction);
        
        print(arr);
        
        return;
    }

    private static void tilt(int[][] arr, char direction) {
        int moveCount = 0;

        if (direction == 'L') {
            moveCount = 3;
        } else if (direction == 'R') {
            moveCount = 1;
        } else if (direction == 'U') {
            moveCount = 2;
        } else if (direction == 'D') {
            moveCount = 0;
        }

        for (int i = 0; i < moveCount; ++i) {
            rotate(arr);
        }

        gravity(arr);
        assembleNumber(arr);
        gravity(arr);

        for (int i = 0; i < 4-moveCount; ++i) {
            rotate(arr);
        }
    }

    // grid를 시계방향으로 90' 회전시킵니다.
    private static void rotate(int[][] arr) {
        int[][] temp = new int[N][N];
        // nextGrid를 0으로 초기화합니다.
        for(int i = 0; i < N; i++)
            for(int j = 0; j < N; j++)
                temp[i][j] = 0;
        
        // 90' 회전합니다.
        for(int i = 0; i < N; i++)
            for(int j = 0; j < N; j++)
                temp[i][j] = arr[N -j- 1][i];
        
        // nextGrid를 grid에 옮겨줍니다.
         for(int i = 0; i < N; i++)
            for(int j = 0; j < N; j++)
                arr[i][j] = temp[i][j];
    }

    private static void gravity(int[][] arr) {
        for (int j = 0; j < N; ++j) {
            int[] temp = new int[N];
            int endOfTempArr = N-1;
            for (int i = N-1; i >= 0; --i) {
                if (arr[i][j] != BLANK) {
                    temp[endOfTempArr--] = arr[i][j];
                }
            }
            for (int i = N-1; i >= 0; --i) {
                arr[i][j] = temp[i];
            }
        }
    }

    private static void assembleNumber(int[][] arr) {
        for (int j = 0; j < N; ++j) {
            for (int i = N-1; i > 0; --i) {
                if (arr[i-1][j] == arr[i][j]) {
                    arr[i][j] += arr[i-1][j];
                    arr[i-1][j] = BLANK;
                }
            }
        }
    }

    private static void print(int[][] arr) {
        for (int i = 0; i < 4; ++i) {
            for (int j = 0; j < 4; ++j) {
                System.out.print(arr[i][j] + " ");
            }
            System.out.println();
        }
        System.out.println();
    }
}

⏰총 풀이시간

  • 55분
profile
현명하고 성실하게 살자

0개의 댓글