The Clockwise Spiral (5kyu)

Mark Lee·2021년 12월 10일
0

CodeWars

목록 보기
4/12

졸려서 잠시 짬 내서 간단히 풀어본 문제입니다.
https://www.codewars.com/kata/536a155256eb459b8700077e/

길이가 N인 정방 행렬 구조에서 시계 방향으로 진행하며 count를 하는 문제입니다. 비슷한 문제를 있었던 거 같기도 하네요.

Your objective is to complete a function createSpiral(N) that receives an integer N and returns an NxN two-dimensional array with numbers 1 through NxN represented as a clockwise spiral.

Return an empty array if N < 1 or N is not int / number

Examples:

N = 3 Output: [[1,2,3],[8,9,4],[7,6,5]]

1 2 3
8 9 4
7 6 5

풀이는 다음과 같습니다.

먼저, std::vector<int> flat 을 정의해서 이동하는 위치에 count된 숫자를 저장하도록 했습니다.
그리고 std::vector<bool> visit를 이용해서 한번 지나간 위치는 마킹해서 다시 지나가지 않도록 했습니다.
마지막으로 std::vector<std::pair<int, int>> dir을 정의해서 4개 진행 방향을 정의한 다음에 진행이 불가능한 상황이 되면, 다음 진행 방향으로 변경해서 위치를 갱신하도록 했습니다.

std::vector<std::vector<int>> create_spiral(int n)
{
    std::vector<std::vector<int>> ret;

    if (n < 1)
        return ret;

    std::vector<int> flat(n * n, 0);

    std::vector<bool> visit(n * n, false);
    std::vector<std::pair<int, int>> dir = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    int dirD = 4;
    int dirC = 0;

    int x = 0, y = 0;
    for (int i = 0; i < n * n; ++i)
    {
        int idx = y * n + x;
        flat[idx] = i + 1;
        visit[idx] = true;

        std::pair<int, int> next = dir[dirC % dirD];

        int nx = x + next.first;
        int ny = y + next.second;
        int nIdx = ny * n + nx;

        if (nx < 0 || nx > n - 1 || ny < 0 || ny > n - 1 || nIdx < 0 || nIdx > n * n - 1 || visit[nIdx])
        {
            dirC++;
            nx = x + dir[dirC % dirD].first;
            ny = y + dir[dirC % dirD].second;
        }

        x = nx;
        y = ny;
    }

    for (int i = 0; i < n; ++i)
    {
        std::vector<int> row(flat.begin() + i * n, flat.begin() + (i + 1) * n);
        ret.push_back(row);
    }

    return ret;
}
profile
C++/C#, Python을 주로 사용하는 개발자입니다. Engineering 알고리즘 개발을 주 업무로 하고 있습니다.

0개의 댓글