본문 바로가기
java/메모장

[코딩테스트] 공원 산책

by choi-dev 2024. 2. 18.

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

 

프로그래머스

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

programmers.co.kr

 

내 코드

package programmers;

import java.util.Arrays;
import java.util.Objects;

public class 공원산책 {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(solution(new String[]{"SOO","OOO","OOO"}, new String[]{"E 3", "S 2", "W 1"})));
    }

    public static int[] solution(String[] park, String[] routes) {
        /* 문제 의도
            park 배열에서 routes 배열 입력값으로 이동시킨 결과물 나타내기
            1. 장애물이 있으면 routes 배열의 명령 무시
            2. 이동하는 구간이 음수(공원 탈출)면 명령 무시

            park -> 2중 배열의 형태로 변환
            변환한 배열을 변수 arr에 초기화하고 S의 위치를 찾아서 xStart와 yStart에 초기화한다. (xStart, yStart)
            routes 배열에서 E를 만나면 yStart++, W를 만나면 yStart--, N을 만나면 xStart--, S를 만나면 xStart++
        */
        char[][] arr = new char[park.length][park[0].length()];
        int xStart = 0;
        int yStart = 0;
        for (int i = 0; i < park.length; i++) {
            arr[i] = park[i].toCharArray();

            if (park[i].contains("S")) {
                xStart = park[i].indexOf("S");
                yStart = i;
            }
        }

        for (String route: routes) {
            String way = route.split(" ")[0];
            int cnt = Integer.parseInt(route.split(" ")[1]);

            int mx = xStart;
            int my = yStart;

            for (int i = 0; i < cnt; i++) {
                if (Objects.equals(way, "E")) {
                    mx++;
                }
                if (Objects.equals(way, "W")) {
                    mx--;
                }
                if (Objects.equals(way, "S")) {
                    my++;
                }
                if (Objects.equals(way, "N")) {
                    my--;
                }

                if (mx >= 0 && my >= 0 && mx < arr[0].length && my < arr.length) {
                    if (arr[my][mx] == 'X') {
                        break;
                    }
                    if (i == cnt - 1) {
                        xStart = mx;
                        yStart = my;
                    }
                }
            }
        }
        return new int[]{yStart, xStart};
    }
}

해당 문제는 100% 내 생각으로 푼 것은 아니다. 중간에 탈출 로직을 구현하지 못해 남의 코드를 참고했었다. 선언부부터 천천히 확인해보면 다음과 같다. arr 2중 배열에는 park 배열을 2중 배열로 만든 것이다. 배열에 넣으면서 문자열 안에 S가 있으면 시작 지점의 인덱스를 가져올 수 있기 때문에 xStart, yStart 변수에 초기화했다.

 

routes 배열은 방향과 이동 횟수를 문자열로 담아둔 것이다. 횟수를 cnt, 방향을 way 라는 변수에 초기화했고 xStart, yStart 변수를 바로 사용하는 것이 아닌 다른 변수에 임시로 담아두고 방향대로 횟수만큼 움직여주고 방해물(X)를 만나지 않거나 기존 격자의 틀에서 탈출하지 않으면 xStart, yStart 변수에 움직인 값을 넣어주는 식으로 구현했다.

 

탈출 로직을 이해하지 못해 몇 시간을 헤맸는데 나와 같은 사람이 있다면 다음과 같이 이해하면 된다. 왜 i == cnt - 1이 탈출 로직인지 이해가 안갔는데 단순하게 생각하니 해결됐다. E 2의 문자열이라고 가정했을 때 E 방향으로 2번 움직여주면 되는데 i는 0부터 시작하기 때문에 횟수에서 1을 빼주지 않으면 OutOfRange가 발생한다. 즉, i가 0, 1이면 2번 움직인 꼴인데 cnt가 2이기 때문에 -1을 한 것이 탈출 로직이라 보면 된다.

'java > 메모장' 카테고리의 다른 글

JPA, querydsl는 네이티브 쿼리를 보완할 수 있을까?  (0) 2024.03.21
[코딩테스트] 바탕화면 정리  (0) 2024.02.18
[코딩테스트] 추억 점수  (0) 2024.02.18
[코딩테스트] 달리기 경주  (0) 2024.02.18
형 변환  (0) 2024.02.12