- 문제설명
- 제한사항
- 예시 & 입출력 예
- 해결과정
- 문제가 단순하지 않아 구현해야 하는 기능이 뭔지 천천히 생각해봤다.
- 우선 첫번째로, 결국 출발점 S의 위치가 장애물을 만나는 상황이나 배열범위 밖으로 넘어가는 것을 체크하려면 먼저 기존 ["SOO", "OOO", "OOO"] 형식으로 주어져있는 1차원 park배열을 2차원배열로 만들어야 겠다는 생각을 했다.
이렇게 되면 추후 모든 상황을 비교할 때, 단순히 배열의 좌표값 끼리 비교하면 되므로 편리하다. - 다음으로 출발지점 S의 좌표값을 얻는 로직을 작성하자. (S는 오직 하나 --> [1,2] 처럼 1차원 배열로 생성)
- 다음으로 장애물 지점 X의 좌표값을 얻는 로직을 작성하자. 여기서 S와 동일한 논리로 구할 수 있지만, S는 무조건 하나인 반면, 장애물은 없을 수 도 있고 여러개가 있을 수 있기 때문에 우선 X의 개수를 구한 뒤 2차원 배열을 생성해 배열의 깊이를 장애물의 개수로 받도록 구성했다.
- 이후, [E 2]라는 명령을 받았을 때, 우선 한발자국을 움직일 수 있냐를 판단해 boolean을 반환하는 메소드를 작성한 후 주어진 이동횟수를 모두 움직여도 true를 반환한다면 이동시켜라. 라는 메소드를 구분지어서 만들려고 시도했다.
하지만 이렇게 구현하면 메인 메소드에서 for문을 여러번 사용해 결과값을 내보내야하므로, 최대한 메인 메소드를 간결하게 만들고자, [E 2] 라는 명령이 들어왔을 때 한발자국씩 움직일 수 있는지를 먼저 판단한 후, 매개변수를 이용해 움직인 값을 저장하고 이후 갱신된 좌표값에서 다시 남은 발자국 수를 끝까지 이동시겼을 때도 문제가 없다면 저장된 매개변수 값을 기존의 S 좌표값으로 넣어준 뒤 반환시키는 메소드를 작성했다. - 이렇게 되면 구현에 필요한 모든 기능 각각 독립적인 메소드로 작성 됐기 때문에, 메인 메소드에서 각 메소드를 불러오기만 하면 된다.
- 솔루션
import java.util.*;
class Solution {
// 1. park 2차원 배열로 만들기
public char[][] makePark2D (String[] park, String[] routes) {
char[][] park2D = new char[park.length][park[0].length()];
for(int i = 0; i < park.length; i++) {
for(int j = 0; j < park[0].length(); j++) {
park2D[i][j] = park[i].charAt(j);
}
}
return park2D;
}
// 2. 출발점 위치(S좌표) 찾기
public int[] search_S (char[][] park2D) {
for(int i = 0; i < park2D.length; i++) {
for(int j = 0; j < park2D[0].length; j++) {
if(park2D[i][j] == 'S') {
int[] s = {i,j};
return s;
}
}
}
return null;
}
// 3. 장애물 위치(X좌표들의 모음) 찾기
public int[][] search_X (char[][] park2D) {
int count = 0;
int[][] x_null = {{-1, -1}, {-2,-2}};
for(int i = 0; i < park2D.length; i++) {
for(int j = 0; j < park2D[0].length; j++) {
if(park2D[i][j] == 'X') {
count++;
}
}
}
if(count == 0) return x_null; //장애물이 없으면, 이동에 문제가 생김 --> 상관없는 초기값 설정
int [][] x_arr = new int[count][2];
int index = 0;
for(int i = 0; i < park2D.length; i++) {
for(int j = 0; j < park2D[0].length; j++) {
if(park2D[i][j] == 'X') {
int[] x = {i,j};
x_arr[index] = x;
index++;
}
}
}
return x_arr;
}
// 4. [E 2]처럼 이동 할 때 장애물에 안걸리고 끝에 안걸리면 이동시켜라
public int[] GoGo (char[][] park2D, int[][] x_arr, int[] s, String[] routes, int r_num) {
int tmpX = s[1];
int tmpY = s[0]; // 장애물 마주치는지, 배열을 나가버리는지 확인하는 변수
int [] s_result = new int[2];
for(int i = 0; i < x_arr.length; i++) {
tmpX = s[1];
tmpY = s[0]; //초기화 안해주면 numMoves가 x_arr.length만큼 곱해짐
int numMoves = Integer.parseInt(String.valueOf(routes[r_num].charAt(2))); //몇칸 움직여야돼? 의 변수
for(int j = 0; j < numMoves; j++){
switch (routes[r_num].charAt(0)) {
case 'E' :
if((tmpY == x_arr[i][0] && tmpX+1 == x_arr[i][1]) || tmpX+1 == park2D[0].length){
s_result = s;
return s_result; // 메인에서 결과를 다시 여기로 가져오기 위해 사용
}
else {
tmpX += 1;
}
break;
case 'W' :
if((tmpY == x_arr[i][0] && tmpX-1 == x_arr[i][1]) || tmpX-1 == -1){
s_result = s;
return s_result;
}
else {
tmpX -= 1;
}
break;
case 'S' :
if((tmpY+1 == x_arr[i][0] && tmpX == x_arr[i][1]) || tmpY+1 == park2D.length){
s_result = s;
return s_result;
}
else {
tmpY += 1;
}
break;
case 'N' :
if((tmpY-1 == x_arr[i][0] && tmpX == x_arr[i][1]) || tmpY-1 == -1){
s_result = s;
return s_result;
}
else {
tmpY -= 1;
}
break;
default : break;
}
}
}
s[0] = tmpY;
s[1] = tmpX;
return s;
}
// 메인 메소드
public int[] solution(String[] park, String[] routes) {
char[][] park2D = makePark2D(park, routes); // 기존 1차원 park --> 2차원 배열로 생성
int[] s = search_S(park2D); // 시작위치 찾기
int[][] x_arr = search_X(park2D); // 장애물 어디있는지 찾기, 여러개일 수 있으므로 2차원배열로 생성
int[] s_result = {}; // 결과 받을 배열 생성
for(int i = 0; i < routes.length; i++) {
s_result = GoGo(park2D, x_arr, s, routes, i); // 반복문을 통해 움직이라는 명령 수만큼 GoGo 메소드 실행
}
return s_result;
}
}
- 배운점
- 최근 자바의 객체지향성에 대해 공부를 해보며 코딩테스트를 준비할 때에도 객체지향성을 띈 코드를 작성하고자 했다.
- 물론 코딩테스트 안에서 .java 파일을 여러개 만들어가며 클래스를 선언하는 방식으로는 사용할 수 없었지만,
기존처럼 단순히 메인 메소드 안에 모든 내용을 담아 구현하는것이 아닌 각 기능의 역할을 맡는 메소드를 작성했다. - 하나의 메인메소드 안에 모든 내용을 담았다면 분명 각 기능들이 강하게 종속되어 많은 오류가 발생했을 것이다.
그러나, 각 메소드들을 독립적으로 실행시켜 메소드 간 논리 충돌을 방지하고 보다 가독성 있는 코드를 작성할 수 있었다.
'코딩테스트 > 프로그래머스' 카테고리의 다른 글
[Java] 프로그래머스 Level 2: 마법의 엘리베이터 (0) | 2023.05.31 |
---|---|
[Java] 프로그래머스 Level 2: 문자열 압축 (0) | 2023.05.30 |
[Java] 프로그래머스 Level 1: 둘만의 암호 (0) | 2023.05.29 |
[Java] 프로그래머스 Level 1: 달리기 경주 (0) | 2023.05.25 |
[Java] 프로그래머스 Level 1: 바탕화면 정리 (0) | 2023.05.23 |