프로그래머스 입문 120861 캐릭터의 좌표
문제
문자열 배열 key_input과 정수 배열 board가 매개변수로 주어진다.
캐릭터는 [0, 0]에서 시작하고 key_input의 방향에 따라 한 칸씩 이동한다.
left는 x좌표를 -1, right는 x좌표를 +1, up은 y좌표를 +1, down은 y좌표를 -1만큼 이동한다.
단, board 원소의 값은 홀수로만 주어지며, board가 정한 범위를 벗어나는 이동은 무시한다.
모든 입력을 처리한 뒤 최종 좌표를 반환하시오.
| key_input | board | result |
|---|---|---|
| [“left”, “right”, “up”, “right”, “right”] | [11, 11] | [2, 1] |
| [“down”, “down”, “down”, “down”, “down”] | [7, 9] | [0, -4] |
풀이
경계를 넘지 않을 때만 이동하기
#include <stdlib.h>
#include <string.h>
int* solution(const char* key_input[], size_t key_input_len, int board[], size_t board_len)
{
int* result = malloc(sizeof(int) * 2);
memset(result, 0, sizeof(int) * 2);
int limit_x = board[0] / 2;
int limit_y = board[1] / 2;
for (size_t i = 0; i < key_input_len; i++)
{
const char* direction = key_input[i];
if (strcmp(direction, "left") == 0 && result[0] > -limit_x)
{
result[0]--;
}
else if (strcmp(direction, "right") == 0 && result[0] < limit_x)
{
result[0]++;
}
else if (strcmp(direction, "up") == 0 && result[1] < limit_y)
{
result[1]++;
}
else if (strcmp(direction, "down") == 0 && result[1] > -limit_y)
{
result[1]--;
}
}
return result;
}
board[0]은 가로 칸 수이고, board[1]은 세로 칸 수이다.
두 값은 모두 홀수이므로 가운데 칸이 하나만 존재하고, 그 칸을 [0, 0]으로 볼 수 있다.
예를 들어 가로 크기가 11이면 가운데 1칸이 있고, 왼쪽에 5칸, 오른쪽에 5칸이 있다.
따라서 x 좌표는 -5 이상 5 이하로만 이동할 수 있고, 이 한계값은 board[0] / 2로 구할 수 있다.
세로 방향도 같은 방식으로 아래쪽 한계와 위쪽 한계를 board[1] / 2로 구한다.
이후 반복문에서 방향 문자열을 하나씩 확인하고, 해당 방향으로 이동해도 범위를 벗어나지 않을 때만 좌표를 갱신한다.
후보 좌표를 만든 뒤 유효성 검사하기
#include <stdlib.h>
#include <string.h>
int* solution(const char* key_input[], size_t key_input_len, int board[], size_t board_len)
{
int* result = malloc(sizeof(int) * 2);
memset(result, 0, sizeof(int) * 2);
int limit_x = board[0] / 2;
int limit_y = board[1] / 2;
for (size_t i = 0; i < key_input_len; i++)
{
int next_x = result[0];
int next_y = result[1];
if (strcmp(key_input[i], "left") == 0)
{
next_x--;
}
else if (strcmp(key_input[i], "right") == 0)
{
next_x++;
}
else if (strcmp(key_input[i], "up") == 0)
{
next_y++;
}
else if (strcmp(key_input[i], "down") == 0)
{
next_y--;
}
if (next_x < -limit_x || next_x > limit_x || next_y > limit_y || next_y < -limit_y)
{
continue;
}
result[0] = next_x;
result[1] = next_y;
}
return result;
}
이전 풀이에서는 이동하기 전에 범위를 벗어나지 않는지 확인한 뒤 좌표를 갱신했다.
이 풀이에서는 먼저 다음 좌표를 계산하고, 그 좌표가 유효한 범위 안에 있을 때만 갱신한다.