N Log

프로그래머스 입문 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;
}

이전 풀이에서는 이동하기 전에 범위를 벗어나지 않는지 확인한 뒤 좌표를 갱신했다.
이 풀이에서는 먼저 다음 좌표를 계산하고, 그 좌표가 유효한 범위 안에 있을 때만 갱신한다.