N Log

프로그래머스 입문 120844 배열 회전시키기

문제

출처

정수 배열 numbers, 배열의 길이 numbers_len, 회전 방향 direction("left" 또는 "right")이 주어진다.
배열의 원소를 direction 방향으로 한 칸씩 회전시키시오.

numbers direction result
[1, 2, 3] “left” [2, 3, 1]
[4, 5, 6] “right” [6, 4, 5]

풀이

[1, 2, 3]을 왼쪽으로 회전시키면 원소는 다음과 같이 이동한다.

1  2  3
  /  /
2  3  1

첫 번째 원소 1은 마지막 칸으로 이동하고, 나머지 원소는 한 칸씩 앞으로 이동한다.

[4, 5, 6]을 오른쪽으로 회전시키면 원소는 다음과 같이 이동한다.

4  5  6
 \  \
6  4  5

마지막 원소 6은 첫 번째 칸으로 이동하고, 나머지 원소는 한 칸씩 뒤로 이동한다.

직접 인덱스를 지정해 회전하기

#include <stdlib.h>
#include <string.h>

int* solution(int numbers[], size_t numbers_len, const char* direction)
{
    int* result = malloc(sizeof(int) * numbers_len);

    if (strcmp(direction, "left") == 0)
    {
        for (size_t i = 0; i < numbers_len - 1; i++)
        {
            result[i] = numbers[i + 1];
        }

        result[numbers_len - 1] = numbers[0];
    }
    else // direction == "right"
    {
        for (size_t i = 0; i < numbers_len - 1; i++)
        {
            result[i + 1] = numbers[i];
        }

        result[0] = numbers[numbers_len - 1];
    }

    return result;
}

위에서 설명한 인덱스 이동 규칙을 코드로 옮긴 구현이다.
그림에서 /와 \로 표시한 이동은 같은 규칙이 반복되므로 반복문에서 처리한다.
반복문은 배열 안에서 한 칸씩 이동하는 원소를 처리하고, 한쪽 끝에서 다른 쪽 끝으로 이동하는 원소는 따로 처리한다.
따라서 왼쪽 회전에서는 첫 번째 원소를 마지막 칸에, 오른쪽 회전에서는 마지막 원소를 첫 번째 칸에 저장한다.

나머지 연산을 이용해 회전하기

#include <stdlib.h>
#include <string.h>

int* solution(int numbers[], size_t numbers_len, const char* direction)
{
    int* result = malloc(sizeof(int) * numbers_len);

    if (strcmp(direction, "left") == 0)
    {
        for (size_t i = 0; i < numbers_len; i++)
        {
            result[i] = numbers[(i + 1) % numbers_len];
        }
    }
    else // direction == "right"
    {
        for (size_t i = 0; i < numbers_len; i++)
        {
            result[(i + 1) % numbers_len] = numbers[i];
        }
    }

    return result;
}

이전 방법은 대부분의 원소를 한 칸씩 옮긴 뒤, 범위를 벗어나는 값만 따로 처리했다.
그래서 왼쪽 회전에서는 첫 번째 원소를, 오른쪽 회전에서는 마지막 원소를 따로 처리하는 코드가 필요했다.
나머지 연산자를 사용하면 범위를 벗어나는 인덱스도 다시 유효한 인덱스로 바꿀 수 있다.

왼쪽 회전에서 i가 2이고 numbers_len이 3이면 (i + 1) % numbers_len은 (2 + 1) % 3, 즉 0이다.
따라서 numbers[0]의 원소가 result[2]에 저장된다.

오른쪽 회전에서 i가 2이고 numbers_len이 3이면 (i + 1) % numbers_len은 (2 + 1) % 3, 즉 0이다.
따라서 numbers[2]의 원소가 result[0]에 저장된다.