백준 로봇 청소기 - 14503 [JAVA] - 23년 1월 1일

Denia·2023년 1월 1일
0

코딩테스트 준비

목록 보기
126/201
post-custom-banner

스스로 문제를 너무 복잡하게 풀었다.

복잡하게 풀다보니 시간도 오래 걸림.

일단 구현부터 하고나서 리팩토링을 하는게 좋은 습관이다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

//로봇 청소기
//현재 위치 청소
//현재 방향을 기준으로 왼쪽방향부터 차례대로 탐색 진행
// 왼쪽이 더러우면 왼쪽회전 후 한칸 전진 -> 현재 위치 청소
// 왼쪽 방향 깨끗하면, 왼쪽 회전 후 다시 왼쪽방향부터 차례대로 탐색 진행
// 네방향이 모두 깨끗 or 벽 이면, 바라보는 방향 유지한 채로 한칸 후진 후 왼쪽 탐색
// 네방향이 모두 깨끗 or 벽 이면, 바라보는 방향 유지한 채로 한칸 후진이 불가능하면 작동 멈춤

// 로봇 청소기는 이미 청소된 칸 청소 X , 벽 통과 X

// 로봇 청소기가 있는 칸의 상태는 빈칸

// 로봇 청소기가 청소하는 칸의 개수를 출력

enum View {
    NORTH(0), EAST(1), SOUTH(2), WEST(3);
    final int value;

    View(int value) {
        this.value = value;
    }

    public static View valueOf(int value) {
        switch (value) {
            case 0:
                return View.NORTH;
            case 1:
                return View.EAST;
            case 2:
                return View.SOUTH;
            case 3:
                return View.WEST;
            default:
                return null;
        }
    }
}

enum Environment {
    EMPTY(0), WALL(1), CLEAN(2);

    final int value;

    Environment(int value) {
        this.value = value;
    }

    public static Environment valueOf(int value) {
        switch (value) {
            case 0:
                return EMPTY;
            case 1:
                return WALL;
            case 2:
                return CLEAN;
            default:
                return null;
        }
    }
}

public class Main {
    static public void main(String[] args) throws IOException {
        BjSolution sol = new BjSolution();

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String[] fl = br.readLine().split(" ");
        int rowNum = Integer.parseInt(fl[0]);
        int colNum = Integer.parseInt(fl[1]);

        String[] sl = br.readLine().split(" ");

        int[][] table = new int[rowNum][colNum];

        for (int r = 0; r < rowNum; r++) {
            String[] tl = br.readLine().split(" ");
            for (int c = 0; c < colNum; c++) {
                table[r][c] = Integer.parseInt(tl[c]);
            }
        }

        sol.solution(sl, table);
    }
}

class BjSolution {
    public void solution(String[] machineCoordi, int[][] table) {
        int row = Integer.parseInt(machineCoordi[0]);
        int col = Integer.parseInt(machineCoordi[1]);
        int view = Integer.parseInt(machineCoordi[2]);

        Machine machine = new Machine(row, col, View.valueOf(view), table);

        System.out.println(machine.simulation());
    }
}

class Coordi {
    int row, col;

    Coordi(int row, int col) {
        this.row = row;
        this.col = col;
    }
}

class Machine {
    int row, col;
    View view;
    Environment[][] table;
    int turnCount, cleanCount;

    public Machine(int row, int col, View view, int[][] table) {
        this.row = row;
        this.col = col;
        this.view = view;
        this.table = initIsCleaned(table);
    }

    public int simulation() {

        while (true) {
            clean();

            if (getTurnCount() == 4) {
                if (isAbleToBackUp()) {
                    backUp();
                    resetTurnCount();
                } else {
                    break;
                }
            } else {
                if (isAbleToCleanOnLeftSide()) {
                    changeView();
                    go();
                    resetTurnCount();
                } else {
                    changeView();
                    upTurnCount();
                }
            }
        }

        return cleanCount;
    }

    private Environment[][] initIsCleaned(int[][] table) {
        Environment[][] returnTable = new Environment[table.length][table[0].length];
        for (int r = 0; r < table.length; r++) {
            for (int c = 0; c < table[r].length; c++) {
                returnTable[r][c] = Environment.valueOf(table[r][c]);
            }
        }

        return returnTable;
    }

    public void clean() {
        if (this.table[this.row][this.col] != Environment.EMPTY)
            return;

        this.table[this.row][this.col] = Environment.CLEAN;
        cleanCount++;
    }

    public int getTurnCount() {
        return this.turnCount;
    }

    public void upTurnCount() {
        turnCount++;
    }

    public void resetTurnCount() {
        turnCount = 0;
    }

    public boolean isAbleToCleanOnLeftSide() {
        Coordi turnCoordi = getTurnCoordi(this.row, this.col);

        return this.table[turnCoordi.row][turnCoordi.col] == Environment.EMPTY;
    }

    public boolean isAbleToBackUp() {
        Coordi backUpCoordi = getBackCoordi(this.row, this.col);

        return this.table[backUpCoordi.row][backUpCoordi.col] != Environment.WALL;
    }

    public Coordi getBackCoordi(int curRow, int curCol) {
        if (this.view == View.NORTH) {
            curRow++;
        } else if (this.view == View.EAST) {
            curCol--;
        } else if (this.view == View.SOUTH) {
            curRow--;
        } else { //West
            curCol++;
        }

        return new Coordi(curRow, curCol);
    }

    public Coordi getTurnCoordi(int curRow, int curCol) {
        if (this.view == View.NORTH) {
            curCol--;
        } else if (this.view == View.EAST) {
            curRow--;
        } else if (this.view == View.SOUTH) {
            curCol++;
        } else { //West
            curRow++;
        }

        return new Coordi(curRow, curCol);
    }

    public void go() {
        if (this.view == View.NORTH) {
            this.row--;
        } else if (this.view == View.EAST) {
            this.col++;
        } else if (this.view == View.SOUTH) {
            this.row++;
        } else { //West
            this.col--;
        }
    }

    public void backUp() {
        if (this.view == View.NORTH) {
            this.row++;
        } else if (this.view == View.EAST) {
            this.col--;
        } else if (this.view == View.SOUTH) {
            this.row--;
        } else { //West
            this.col++;
        }
    }

    private void changeView() {
        int tempViewValue = this.view.value;

        tempViewValue += 3;
        tempViewValue %= 4;

        this.view = View.valueOf(tempViewValue);
    }
}

profile
HW -> FW -> Web
post-custom-banner

0개의 댓글