[JS] 프로그래머스 Lv1 - 공원 산책

찐새·2023년 5월 4일
0

코딩테스트

목록 보기
38/53
post-thumbnail

공원 산책

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

코드

function solution(park, routes) {
    const start = [0, 0];
    
    const board = park.map((v, i)=> {
        [...v].forEach((w, j)=> {
            if (w === "S") {
                [start[0], start[1]] = [i, j];
            }
        })
        return [...v]
    })
    
    routes.forEach((v)=>{
        const [op, n] = v.split(" ");
        let flag = false;
        if (op === "E") {
            if (start[1] + +n < board[0].length) {
                for (let i = 1; i <= +n; i++) {
                    if (board[start[0]][start[1] + i] === "X") {
                        flag = true;
                    }
                }
                start[1] += flag ? 0 : +n;
            }
        }
        if (op === "W") {
            if (start[1] - +n >= 0) {
                for (let i = +n; i >= 0 ; i--) {
                    if (board[start[0]][start[1] - i] === "X") {
                        flag = true;
                    }
                }
                start[1] -= flag ? 0 : +n;
            }
        }
        if (op === "N") {
            if (start[0] - +n >= 0) {
                for (let i = +n; i >= 0 ; i--) {
                    if (board[start[0]  - i][start[1]] === "X") {
                        flag = true;
                    }
                }
                start[0] -= flag ? 0 : +n;
            }
        }
        if (op === "S") {
            if (start[0] + +n < board.length) {
                for (let i = 1; i <= +n; i++) {
                    if (board[start[0] + i][start[1]] === "X") {
                        flag = true;
                    }
                }
                start[0] += flag ? 0 : +n;
            }
        }
    })
    
    return start;
}

풀이

park를 순회하며 시작점을 찾은 후, routes를 순회하면서 조건에 맞는 좌표를 찾았다. 조건문과 반복문을 범벅하며 다소 더럽게 하드 코딩했다.

제일 고민했던 부분은 방향과 거리 내에 있는 장애물을 어떻게 판단할 것인가였다. 그래서 생각해낸 것이 조건문 진입 전 flag를 세우고, 각 조건을 통과하면 n만큼 좌표를 순회해 X가 있다면 flag를 변경하는 것이었다. flag가 변경되면 장애물이 있으므로 좌표에 0을 더했다.

통과한 코드이긴 하지만, 너무 복잡하고 더러워서 다시 살펴보며 중복되는 부분을 제거하려고 시도했다.

수정한 코드

function solution(park, routes) {
    const start = [0, 0], direction = {"N":[-1, 0], "S":[1, 0], "W":[0, -1], "E":[0, 1]};
    
    park.forEach((v, i)=> {
        [...v].forEach((w, j)=> {
            if (w === "S") {
                [start[0], start[1]] = [i, j];
            }
        })
    })
    
    routes.forEach((v)=>{
        const [op, n] = v.split(" ");
        let nx = start[0], ny = start[1], cnt = 0;
        
        while (cnt < +n) {
            nx += direction[op][0];
            ny += direction[op][1];
            if (!park[nx] || !park[nx][ny] || park[nx][ny] === "X") break;
            cnt++;
        }
        
        if (cnt === +n) [start[0], start[1]] = [nx, ny];
    })
    return start;
}

풀이

조건문으로 하나씩 계산하는 대신 방향에 대한 hash map을 만들어 계산식을 줄였다. 쓰잘데기 없는 board 배열 변수도 제거했다.

routes를 순회하면서 nx, nydirection에 따른 좌표값을 계산했다. flag 대신 cnt를 변수로 놓고, while문을 돌려 n만큼 거리 내 장애물이 있는지 찾았다. while 안의 다른 조건은 인덱스가 배열 길이를 벗어났을 때 undefined를 반환하는 JS 성일을 이용해 범위를 벗어났는지 확인하는 것이다. nx < 0 && ny < 0 && ... 등으로 썼다가 다른 사람 풀이를 참고해 수정했다.

마지막으로 cntn과 같다면, 범위 안쪽이면서 장애물을 만나지 않은 것이므로, 좌표를 nx, ny로 수정했다.

배운점

  • 사용하는 언어의 성질을 잘 파악하고 있으면 코드가 더 간결해진다.
  • 작성한 코드가 무식하고 더럽더라도 먼저 풀어보고, 타인의 풀이를 참고하면 이해가 더 수월하다.
  • 특정 키워드에 따른 반복 계산이 가능할 때는 hash map이 유용하다. 익숙해지자.
profile
프론트엔드 개발자가 되고 싶다

0개의 댓글