[Study] 프로그래머스 lv.1 공원 산책 (정답률 37%)

ayboori·2023년 6월 23일
0

Java Study

목록 보기
6/34

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

풀이 로직

1) 공원의 시작 위치를 세팅한다
2) 이동 경로를 방향, 숫자로 나눈다
3) 루프를 돌리며 해당 방향, 숫자, 현재 위치를 매개변수로 하는 move()를 실행한다.

move()

  • 방향에 따라 이동 방향을 달리 한다 (E는 +x, S는 +y, W는 -x, N은 -y)
  • 이동 방향만큼 루프를 돌며 장애물이 있는지 체크한다
  • 최대 길이로 이동 시 범위를 벗어나지 않는지 체크한다
  • 위 조건에 해당하지 않을 경우 이동을 수행한다 (point의 위치를 변경)

풀이 과정

시작 위치 / 현재 위치 저장 객체

시작 위치, 현재 위치를 저장할 포인터 역할을 하는 것을 찾고 싶어서 chat GPT에게 물어보았다.

1) 두 개의 변수를 사용하여 저장

int[][] array = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
int rowIndex = 1;
int columnIndex = 2;

int element = array[rowIndex][columnIndex]; // 특정 인덱스의 값 꺼내오기

2) 포인트 객체를 사용하여 저장

class Point {
    int x;
    int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

두 번째 방법이 더 적합해보여서 채택했다.

테스트 케이스 오류

적합한 체크가 일어나지 않는 것 같아 확인했더니 루프문이 잘못되어 있었다.
for (int i = 0; i < number; i++) {

1칸을 이동한다면 이동할 칸 수만큼 전부 체크해야 하기 때문에, 아래로 수정하는 게 맞다

for (int i = 0; i <= number; i++) {

x, y 설정 실수

이렇게 그림을 그려두고 설정했는데, 출력을 찍어보니 x와 y가 뒤바뀌어 출력되었다.
출력 값을 반대로 세팅하는 것으로 해결했으나, 왜 반대인지 모르겠다..!!

충격 소식...
그냥 문제가 반대였음
공원의 가로 길이가 W, 세로 길이가 H라고 할 때, 공원의 좌측 상단의 좌표는 (0, 0), 우측 하단의 좌표는 (H - 1, W - 1) 입니다.

내가 작성한 코드

class Solution {
    public int[] solution(String[] park, String[] routes) {
        // 현재 위치를 저장할 Point 객체 생성
        Point point = new Point();
        
        // 시작점 찾기
        for (int i = 0; i<park.length; i++) {
            if (park[i].contains("S")) {
                point.setPoint(park[i].indexOf("S"),i);
                System.out.println(point.x + " "+ point.y);
                break;
            }
      }              
          
        for (String str : routes) {
            // 이동할 경로를 char / int로 분리하기
            String[] split = str.split(" ");
            char direction = split[0].charAt(0);
            int number = Integer.parseInt(split[1]);
            
            System.out.println(direction + " "+ number);
            
            move(park, direction, number, point); // 이동 수행            
        }      
        
        int[] answer = {point.y,point.x};
        return answer;
    }
    
public void move(String[] park, char direction, int number, Point point) {
    switch (direction) {
        case 'E': // 동쪽 ( + x)
            for (int i = 0; i <= number; i++) {
                if (park[point.y].charAt(point.x + i) == 'X' || point.x + number >= park[point.y].length()) {
                    return;
                }
            }
            point.x += number;
            break;

        case 'S': // 남쪽 ( + y)
            for (int i = 0; i <= number; i++) {
                if (park[point.y + i].charAt(point.x) == 'X' || point.y + number >= park.length) {
                    return;
                }
            }
            point.y += number;
            break;

        case 'W': // 서쪽 ( - x)
            for (int i = 0; i <= number; i++) {
                if (park[point.y].charAt(point.x - i) == 'X' || point.x - number < 0) {
                    return;
                }
            }
            point.x -= number;
            break;

        case 'N': // 북쪽 (- y)
            for (int i = 0; i <= number; i++) {
                if (park[point.y - i].charAt(point.x) == 'X' || point.y - number < 0) {
                    return;
                }
            }
            point.y -= number;
            break;

        default:
            // 예외 던지기
            throw new IllegalArgumentException("wrong input");
    }
}


class Point { // 현재 위치 저장할 객체
    int x;
    int y;
    
    public void setPoint(int x, int y) {
        this.x = x;
        this.y = y;
    }
}
}

    
테스트 1 〉	통과 (19.52ms, 67.7MB)
테스트 2 〉	통과 (12.99ms, 88.3MB)
테스트 3 〉	통과 (11.79ms, 76.7MB)
테스트 4 〉	통과 (15.76ms, 69.2MB)
테스트 5 〉	통과 (21.07ms, 71.2MB)
테스트 6 〉	통과 (34.62ms, 70.6MB)
테스트 7 〉	통과 (24.25ms, 70.3MB)
테스트 8 〉	통과 (16.23ms, 70.7MB)
테스트 9 〉	통과 (13.91ms, 72MB)
테스트 10 〉	통과 (14.74ms, 70.6MB)
테스트 11 〉	통과 (12.08ms, 76.4MB)
테스트 12 〉	통과 (13.82ms, 80.7MB)
테스트 13 〉	통과 (13.49ms, 78.2MB)
테스트 14 〉	통과 (13.20ms, 80MB)
테스트 15 〉	통과 (13.33ms, 81.1MB)
테스트 16 〉	통과 (10.87ms, 70.8MB)
테스트 17 〉	통과 (27.06ms, 74.6MB)
테스트 18 〉	통과 (15.55ms, 75.9MB)
테스트 19 〉	통과 (12.67ms, 71.9MB)
테스트 20 〉	통과 (14.32ms, 78.1MB)

11ms ~ 34ms... 너무 길다

수정점

단위 거리 설정

대각선으로 이동하는 등의 업그레이드가 있을 경우 수행 시간을 줄일 수 있다

실행 시간 단축

1) if문 분리

전의 코드

        case 'E': // 동쪽 ( + x)
            for (int i = 0; i <= number; i++) {
                if (park[point.y].charAt(point.x + i) == 'X' || point.x + number >= park[point.y].length()) {
                    return;
                }
            }
            point.x += number;
            break;

후의 코드

            if(point.x - number < 0){
                return;
            }
            for (int i = 0; i <= number; i++) {
                if (park[point.y].charAt(point.x - i) == 'X') {
                    return;
                }
            }
            point.x -= number;
            break;

10ms ~ 16ms

System.out.println 삭제

놀라운 사실...!! 수행 시간이 1/100으로 줄었다
Sout이 생각보다 시간을 많이 잡아먹는구나.. 디버깅 연습을 해서 앞으론 출력 찍지 않고 코딩하기! 노력해봐야겠다

테스트 1 〉	통과 (0.34ms, 73.9MB)
테스트 2 〉	통과 (0.38ms, 70.8MB)
테스트 3 〉	통과 (0.41ms, 66.6MB)
테스트 4 〉	통과 (0.37ms, 66.3MB)
테스트 5 〉	통과 (0.82ms, 73.5MB)
테스트 6 〉	통과 (0.45ms, 79.1MB)
테스트 7 〉	통과 (0.69ms, 67.9MB)
테스트 8 〉	통과 (0.55ms, 77.6MB)
테스트 9 〉	통과 (1.28ms, 67.4MB)
테스트 10 〉	통과 (0.51ms, 73.6MB)
테스트 11 〉	통과 (1.07ms, 83.8MB)
테스트 12 〉	통과 (0.44ms, 72MB)
테스트 13 〉	통과 (0.67ms, 81MB)
테스트 14 〉	통과 (0.70ms, 82.3MB)
테스트 15 〉	통과 (1.00ms, 66.3MB)
테스트 16 〉	통과 (0.42ms, 74.9MB)
테스트 17 〉	통과 (0.59ms, 79.3MB)
테스트 18 〉	통과 (0.28ms, 69MB)
테스트 19 〉	통과 (0.41ms, 79MB)
테스트 20 〉	통과 (0.32ms, 72.8MB)

contains() / indexOf() 사용하지 않아보자

다른 팀원의 코드를 참고하여 수정해보았으나

        // 시작 지점 S 찾기
        for (int i = 0; i < park.length;i++) {
            for (int j = 0; j < park[i].length(); j++) {
                if (park[i].charAt(j) == 'S') {
                    answer[0] = i; // 세로 좌표
                    answer[1] = j; // 가로 좌표
                    break;
                }
            }
        }

오히려 어떤 테스트는 시간이 길어지기도 했다 (이중 for문을 사용하게 되어서 그런 듯?)

배운 것

char > int 편하게 바꾸기

int move = routes[i].charAt(2) - '0';

ASCII 코드 값을 적용했다.

배열 편하게 출력하기

Arrays.toString(배열)

profile
프로 개발자가 되기 위해 뚜벅뚜벅.. 뚜벅초

0개의 댓글