CodingTest

프로그래머스 - 캐릭터의 좌표 (JAVA)

쩡선영 2023. 4. 5. 01:10

프로그래머스 0단계 캐릭터의 좌표 문제입니다

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

 

프로그래머스

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

programmers.co.kr

 

 

❓문제 설명

머쓱이는 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 함수를 완성해주세요.

⚠️제안사항 및 입출력 예

  • board은 [가로 크기, 세로 크기] 형태로 주어집니다.
  • board의 가로 크기와 세로 크기는 홀수입니다.
  • board의 크기를 벗어난 방향키 입력은 무시합니다.
  • 0 <= keyinput의 길이 <= 50
  • 1 <= board[0] <= 99
  • 1 <= board[1] <= 99
  • keyinput은 항상 up, down, left, right만 주어집니다.
keyinput board result
["left", "right", "up", "right", "right"] [11, 11] [2, 1]
["down", "down", "down", "down", "down"] [7, 9] [0, -4]

 


✏️내가 직접 짠 코드

class Solution {
    public int[] solution(String[] keyinput, int[] board) {
        int[] answer = {0,0};
        for(int i=0; i<keyinput.length; i++) {
			switch (keyinput[i]) {
			case "up" :
				if(answer[1]< ((board[1]/2))) answer[1]++;
				break;
			case "down" :
				if(answer[1] > (board[1]/2)*-1) answer[1]--;
				break;
			case "left" :
				if(answer[0] > (board[0]/2)*-1) answer[0]--;
				break;
			case "right" : 
				if(answer[0] < (board[0]/2)) answer[0]++;
				break;
			}
        }
        return answer;
    }
}

🗣️코드 설명

  • switch case 제어문을 사용하여 "up",  "down", "left", "right"가 나올 경우를 각각 다 나눴다.
  • up이 나올 경우 중 board[1]/2한 값이 answer[1]보다 작으면 answer[1]++
  • down이 나올 경우 answer[1] 이 board[1]/2*1 보다 크면 answer[1]--
  • left가 나올 경우 answer[0]이 board[1]/2*-1보다 크면 answer[0]--
  • right가 나올 경우 answer[0]이 board[0]/2보다 작으면 answer[0]++
  • 위와 같이 진행한 뒤 answer을 return 하였다.

😓반성할 점

이번 문제는 문법적으로는 기본적인 것들이지만, 알고리즘이 참 복잡한 문제였다. 그리하여 여태까지 풀어봤던 코딩테스트 문제들 중 가장 시간이 오래 걸렸다. (3일 정도)

 

문제를 해결하지 못했던 가장 큰 이유는 down과 left일 경우에

case "down" :
	if(Math.abs(answer[1]) < (board[1]/2)) answer[1]--;
		break;
 case "left" :
	if(Math.abs(answer[0]) < (board[0]/2)) answer[0]--;
		break;

위와 같이 Math.abs함수를 사용하여 절댓값을 구한 뒤 비교 하였다. 하지만 이 방식은 한 쪽 끝까지 (up or right) 갔을때 반대로 돌아오지 않았다. Math.abs함수 대신 처음부터 board값에 -1을 곱해서 음수로 변환해줬다면 이렇게까지 시간을 오래 끌지는 않았을 것이다.


👍다른사람의 코드

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

        return answer;
    }
}

이 분은 if문을 사용하여 문제를 해결했으며 변수에 직접 board의 길이를 넣어주었다. 이렇게 하니 더욱 가독성이 좋으며 깔끔한 코드가 나왔다. 나는 문제를 보자마자 switch - case문을 써야겠다는 생각밖에 들지 않았지만, 이분처럼 if-else if 제어문을 사용해도 가독성이 좋은 코드를 짤 수 있구나라고 깨닫게 되었다!

 

 

앞으로는 쉬운 문제 말고 이처럼 어려운 문제도 많이 도전해볼게요:)

발전하는 영깅이가 되겠습니다😎