Algorithms/프로그래머스

[프로그래머스] '캐릭터의 좌표' - Java

LEFT 2023. 5. 12. 20:23

<문제 제시>

<문제설명>
머쓱이는 RPG게임을 하고 있습니다. 
게임에는 up, down, left, right 방향키가 있으며 각 키를 누르면 
위, 아래, 왼쪽, 오른쪽으로 한 칸씩 이동합니다. 
예를 들어 [0,0]에서 up을 누른다면 캐릭터의 좌표는 [0, 1], down을 누른다면 [0, -1],
left를 누른다면 [-1, 0], right를 누른다면 [1, 0]입니다. 
머쓱이가 입력한 방향키의 배열 keyinput와 맵의 크기 board이 매개변수로 주어집니다. 
캐릭터는 항상 [0,0]에서 시작할 때 키 입력이 모두 끝난 뒤에
캐릭터의 좌표 [x, y]를 return하도록 solution 함수를 완성해주세요.

<예시 입출력>


<문제 해결 과정>

이동로직을 자바 코드단에서 좌표계로 표현하는 과정이었다.

Try 1)

int[] answer = {0, 0};
int width = board[0] / 2;
int height = board[1] / 2;

for(int i = 0; i < keyinput.length; i++) {
    if(keyinput[i].equals("left")) {
        answer[0] -= 1;
        if(Math.abs(answer[0]) > width) answer[0] += 1;
        System.out.println("왼쪽으로 이동 " + Arrays.toString(answer));
    }
    else if(keyinput[i].equals("right")) {
        answer[0] += 1;
        if(Math.abs(answer[0]) > width) answer[0] -= 1;
        System.out.println("오른쪽으로 이동 " + Arrays.toString(answer));
    }
    else if(keyinput[i].equals("down")) {
        answer[1] -= 1;
        if(Math.abs(answer[1]) > height) answer[1] += 1;
        System.out.println("아래쪽으로 이동 " + Arrays.toString(answer));
    }
    else if(keyinput[i].equals("up")) {
        answer[1] += 1;
        if(Math.abs(answer[1]) > height) answer[1] += 1;
        System.out.println("위쪽으로 이동 " + Arrays.toString(answer));
    }
}

return answer;

 

 

board의 반을 나누어 최대 이동가능한 거리를 제한하였다. 가로 이동 거리 (width), 세로 이동 거리 (height)

그 범위 내에서 keyinput값에 따라 다른 조건문 처리를 해주었다.

조건문에 일치하도록 하드코딩 해보았지만 테스트 3번에서 통과하지 못하였다. equals를 contains로 바꾸어봐도 동일한 결과였다.

Try 2)

int[] answer = {0, 0};
int width = board[0] / 2;
int height = board[1] / 2;

for(int i = 0; i < keyinput.length; i++) {
    if(keyinput[i].equals("left")) {
        if(Math.abs(answer[0]) < width) answer[0] -= 1;
    }
    else if(keyinput[i].equals("right")) {
        if(Math.abs(answer[0]) < width) answer[0] += 1;
    }
    else if(keyinput[i].equals("down")) {
        if(Math.abs(answer[1]) < height) answer[1] -= 1;
    }
    else if(keyinput[i].equals("up")) {
        if(Math.abs(answer[1]) < height) answer[1] += 1;
    }
}
return answer;

범위를 판단하는 순서를 우선순위로 두고 조건문도 간결화하였지만,예외사항이 있던 것 같다.

Solution 1)

int[] answer = {0, 0};
int width = board[0] / 2;
int height = board[1] / 2;

for(int i = 0; i < keyinput.length; i++) {
    if(keyinput[i].equals("left")) {
        if(answer[0] > -(width)) answer[0] -= 1;
    }
    else if(keyinput[i].equals("right")) {
        if(answer[0] < width) answer[0] += 1;
    }
    else if(keyinput[i].equals("down")) {
        if(answer[1] > -(height)) answer[1] -= 1;
    }
    else if(keyinput[i].equals("up")) {
        if(answer[1] < height) answer[1] += 1;
    }
}
return answer;

Try 2)의 코드를 수정하여 
Math.abs로 절대값 판단부분을 없애고 음수의 판단 시 음수처리를 하여 부등호의 방향을 바꿔보았다.

Solution 2)

int[] answer = {0, 0};
int width = board[0] / 2;
int height = board[1] / 2;

for(int i = 0; i < keyinput.length; i++) {
    if(keyinput[i].contains("left") || keyinput[i].contains("right")) {
        if(keyinput[i].equals("right")) {
            if(answer[0] < width) {
                answer[0] += 1;
            }
        }
        // left가 입력되었을때, -(width)로 음수처리 후 (=Math.abs), -1이동한다.
        else {
            if(answer[0] > -(width)) {
                answer[0] -= 1;
            }
        }
    }
    else {
        if(keyinput[i].equals("up")) {
            if(answer[1] < height) {
                answer[1] += 1;
            }
        }
        // down이 입력되었을때, -(height)로 음수처리 후 (=Math.abs), -1이동한다.
        else {
            if(answer[1] > -(height)) {
                answer[1] -= 1;
            }
        }
    }
}

return answer;

조금 더 조건문을 생략한 부분이다. 전체적으로 비슷하나 조건문 안에 조건문 (answer[0] < width)이 
처리되는 순서가 조금 달랐다. 범위를 판단하는 순서를 우선순위로 해도 될 것 같았다.


<전체코드>

package programmers.Lv0;

import java.util.Arrays;

public class coordinate_user {
	
	public static int[] solution(String[] keyinput, int[] board) {
		int[] answer = {0, 0};
        int width = board[0] / 2;
        int height = board[1] / 2;
        
        for(int i = 0; i < keyinput.length; i++) {
        	if(keyinput[i].equals("left")) {
        		if(answer[0] > -(width)) answer[0] -= 1;
        	}
        	else if(keyinput[i].equals("right")) {
        		if(answer[0] < width) answer[0] += 1;
        	}
        	else if(keyinput[i].equals("down")) {
        		if(answer[1] > -(height)) answer[1] -= 1;
        	}
        	else if(keyinput[i].equals("up")) {
        		if(answer[1] < height) answer[1] += 1;
        	}
        }
        return answer;
    }

	public static void main(String[] args) {
//		String[] keyinput = {"left", "right", "up", "right", "right"};
//		int[] board = {11, 11};
		
		String[] keyinput = {"down", "down", "down", "down", "down"};
		int[] board = {7, 9};
		
		System.out.println("최종 움직임 = " + Arrays.toString(solution(keyinput, board)));
	}

}

게임과 같은 이동로직을 자바에서 좌표계로 구해보는 과정에서 시행착오가 많았지만,

게임 이동 로직에 대해 조금이라도 더 이해할 수 있게되었다.


문제링크)
https://school.programmers.co.kr/learn/courses/30/lessons/120861

 

프로그래머스

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

programmers.co.kr