728x90
문제 링크
https://school.programmers.co.kr/learn/courses/30/lessons/172928
문제 설명
문제는 길기 때문에 링크를 통해서 보는 것을 추천한다.
요약하자면 로봇 강아지를 이동하라는 만큼 이동한 후에 최종 지점을 출력하면 된다.
단, 이동하는데 공원을 벗어나거나 장애물이 있으면 해당 명령은 무시하면 된다.
해설
해당 문제는 따로 해설이 필요하지 않고, 문제 설명대로 코드를 작성하면 된다.
문제 풀이
우선 무작정 설명에 나와있는 거 그대로 코드를 작성한 방식과 해당 방식을 리펙토링 해서 풀어낸 방식 두 가지가 있다.
이번 문제에서 가장 핵심은 리펙토링 하는 부분에서 이동 방향을 동{0, 1}, 서{0, -1}, 남{1, 0}, 북{-1, 0}으로 직접 만든 게 핵심이다.
방향이 들어가는 문제들은 아래와 같이 좌표를 미리 만들어 두고 하는 게 좋다.
// 순서대로 동, 서, 남, 북
int dx = {0, 0, 1, -1};
int dy = {1, -1, 0, 0};
안 그러면 코드가 복잡해지고 그러다 보면 쉬운 문제도 실수가 많아져 시간만 잡아먹고 문제도 틀릴 수 있다.
아래가 복잡해지는 코드의 예시일 수 있겠다.
1. 리펙토링 전
엄청 복잡하다.. 문제를 풀고 나서도 런타임 에러가 발생하는데.. 왜 발생하는지 찾는데만 많은 시간을 소비했다.
근데 찾고 보면 정말 간단한 부분을 실수하는 경우가 많다.
이렇게 복잡한 코드를 방향을 미리 지정해서 코드를 짜면 간단해진다.
class Solution {
public int[] solution(String[] park, String[] routes) {
int[] start = getStartPosition(park);
int H = park.length;
int W = park[0].length();
for (String route: routes) {
char direction = route.charAt(0);
int num = route.charAt(2) - '0';
if (direction == 'E') {
if (start[1] + num > W - 1) {
continue;
}
start[1] += num;
for (int j = start[1] - num + 1; j <= start[1]; j++) {
if (park[start[0]].charAt(j) == 'X') {
start[1] -= num;
break;
};
}
} else if (direction == 'W') {
if (start[1] - num < 0) {
continue;
}
start[1] -= num;
for (int j = start[1]; j <= start[1] + num; j++) {
if (park[start[0]].charAt(j) == 'X') {
start[1] += num;
break;
};
}
} else if (direction == 'S') {
if (start[0] + num > H - 1) {
continue;
}
start[0] += num;
for (int j = start[0] - num; j <= start[0]; j++) {
if (park[j].charAt(start[1]) == 'X') {
start[0] -= num;
break;
};
}
} else {
if (start[0] - num < 0) {
continue;
}
start[0] -= num;
for (int j = start[0]; j <= start[0] + num; j++) {
if (park[j].charAt(start[1]) == 'X') {
start[0] += num;
break;
};
}
}
}
return start;
}
private int[] getStartPosition(String[] park) {
for (int i = 0; i < park.length; i++) {
for (int j = 0; j < park[i].length(); j++) {
char c = park[i].charAt(j);
if ('S' == c) {
return new int[]{i, j};
}
}
}
return new int[]{0, 0};
}
}
2. 리펙토링 후
물론 이것도 짧진 않지만 if문 안에 if문 그 안에 for문 그 안에 if문 이런 식으로 복잡한 코드보다는 깔끔해진다.
import java.util.*;
class Solution {
public int[] solution(String[] park, String[] routes) {
int[] start = getStartPosition(park);
Map<Character, int[]> map = new HashMap<>();
map.put('E', new int[]{0, 1});
map.put('W', new int[]{0, -1});
map.put('S', new int[]{1, 0});
map.put('N', new int[]{-1, 0});
for (String route: routes) {
char direction = route.charAt(0);
int moveCount = route.charAt(2) - '0';
int[] dxdy = map.get(direction);
int dx = dxdy[0];
int dy = dxdy[1];
int curX = start[0];
int curY = start[1];
boolean isOk = true;
for (int i = 0; i < moveCount; i++) {
curX += dx;
curY += dy;
if (curX < 0 || curY < 0 || curX > park.length - 1 || curY > park[0].length() - 1) {
isOk = false;
break;
}
if (park[curX].charAt(curY) == 'X') {
isOk = false;
break;
}
}
if (isOk) {
start[0] = curX;
start[1] = curY;
}
}
return start;
}
private int[] getStartPosition(String[] park) {
for (int i = 0; i < park.length; i++) {
for (int j = 0; j < park[i].length(); j++) {
char c = park[i].charAt(j);
if ('S' == c) {
return new int[]{i, j};
}
}
}
return new int[]{0, 0};
}
}
728x90
'알고리즘 > 구현' 카테고리의 다른 글
[프로그래머스] 혼자서 하는 틱택토 Lv2 JAVA [구현][엄탱] (1) | 2023.07.13 |
---|---|
[프로그래머스] lv1 바탕화면 정리 java [구현][엄탱] (0) | 2023.07.04 |