Spiral Array

문제는 다음과 같다:

6 6

  0   1   2   3   4   5
 19  20  21  22  23   6
 18  31  32  33  24   7
 17  30  35  34  25   8
 16  29  28  27  26   9
 15  14  13  12  11  10

위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

153개의 풀이가 있습니다. 1 / 16 Page

/*
프로그램 내용 : 문제는 다음과 같다:
6 6

  0   1   2   3   4   5
 19  20  21  22  23   6
 18  31  32  33  24   7
 17  30  35  34  25   8
 16  29  28  27  26   9
 15  14  13  12  11  10


위처럼 6 6이라는 입력을 주면 6 X 6 매트릭스에 나선형 회전을 한 값을 출력해야 한다.

작성한 날짜   : 2017년 6월 22일
*/
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x, y;
    int m_x, m_y;
    int **map;
    int height = 0, width = -1; 
    int cnt = 0, course = 1;    //출력숫자, 방향설정

    scanf_s("%d %d", &x, &y);

    m_x = x;
    m_y = y;

    map = (int**)malloc(sizeof(int)*y);
    for (int i = 0; i < y; i++)
    {
        *(map + i) = (int*)malloc(sizeof(int)*x);   //2차원 배열 생성
    }

    while (1)
    {
        for (int i = 0; i < m_x; i++)
        {
            width += course;    //가로 증가 또는 감소
            map[height][width] = cnt;
            cnt++;
        }

        for (int j = 0; j < m_y-1; j++)
        {
            height += course;   //높이 증가 또는 감소
            map[height][width] = cnt;
            cnt++;
        }

        m_x--;
        m_y--;
        course *= -1;   //방향결정

        if (m_x == 0 || m_y==0)
        {
            break;  //0이면 종료
        }
    }

    //출력
    for (int i = 0; i < y; i++)
    {
        for (int j = 0; j < x; j++)
        {
            printf("%4d", map[i][j]);   //나선형 회전을 한 값을 출력
        }
        printf("\n");
    }

    return 0;
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
public class SpiralArray {
    public static void main (String[] arg) {
        int matrixRange = 6;

        int arrays[][] = new int[matrixRange][matrixRange];
        int count=0, switchN=1, row=-1, col=0, routine=matrixRange;

        while (routine > 0) {
            for (int i=0; i<routine; i++) {
                row += switchN;
                arrays[col][row] = count;
                count++;
            }

            routine--;

            for (int j=0; j<routine; j++) {
                col += switchN;
                arrays[col][row] = count;
                count++;
            }

            switchN *= -1;

        }

        for (int i=0; i<arrays.length; i++) {
            for (int j=0; j<arrays[i].length; j++) {
                System.out.print(arrays[i][j]+"\t");
            }
            System.out.println();
        }

    }
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

javascript(ES6)

var initarray = function(rowsize = 6, colsize = 6) {
    return Array.from(Array(rowsize), (v, k) => Array.from(Array(colsize), () => -1));
};

Array.prototype.getRowCol = function() {
    return {row : this.length, col : this[0].length};
}

Array.prototype.printMatrix = function() {
    var {row, col} = this.getRowCol();
    var maxlength = ("" + (row * col)).length;

    var getspace = function(len, maxlen) {
        return new Array(maxlen - len + 2).join(" ");
    };

    var str = "";
    for (line of this) {
        for (value of line) {
            str += getspace(("" + value).length, maxlength) + value;
        }
        str += "\n";
    }
    console.log(str);
};

Array.prototype.makeSpiral = function() {
    var {row, col} = this.getRowCol();
    var [x, y, dx, dy] = [0, 0, 0, 1];

    for (let i = 0; i < row * col; i++) {
        this[x][y] = i;
        [x, y] = [x + dx, y + dy];

        if (!this[x] || !this[x][y] || this[x][y] !== -1 ) {
            [x, y] = [x - dx, y - dy];
            [dx, dy] = [dy, -dx];
            [x, y] = [x + dx, y + dy];
        }
    }
    return this;
};

initarray(6, 6).makeSpiral().printMatrix();
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

python 3.6, using numpy 2d arrays, def spiral(length) 는 spiral 로 들어가는 tuple(열, 행) 의 리스트를 넘깁니다.

import numpy as np


def spiral(m,n):
    pairs = []
    cnt = 0
    f, s = 0, -1 # fixed_num, start_num
    while True:
        right = [(f, i) for i in range(s+1, s+1+n-cnt)] # right, inc
        pairs += right
        cnt += 1
        if cnt == m:
            return pairs
        s, f = right[-1]

        down = [(i, f) for i in range(s+1, s+1+m-cnt)] # down, inc
        pairs += down
        if cnt == n:
            return pairs
        f, s = down[-1]

        left = [(f, i) for i in range(s-1, s-1-n+cnt, -1)] # left, dec
        pairs += left
        cnt += 1
        if cnt == m:
            return pairs
        s, f = left[-1]

        up = [(i, f) for i in range(s-1, s-1-m+cnt,-1)] # up, dec
        pairs += up
        if cnt == n:
            return pairs
        f, s = up[-1]


m, n = map(int, input("Matrix shape? ").split()) # get m number of m * n matrix
array = [i for i in range(m * n)] # make array, len(array) is m*n
matrix = np.zeros((m, n)).astype(int) # make m*n matrix based on zeros
spiral = spiral(m, n) # spiral list of (tuple)

for i in range(m * n):
    x, y = spiral[i]
    matrix[x][y] = array[i]

print(matrix)

>>>
Matrix shape?  6 6
[[ 0  1  2  3  4  5]
 [19 20 21 22 23  6]
 [18 31 32 33 24  7]
 [17 30 35 34 25  8]
 [16 29 28 27 26  9]
 [15 14 13 12 11 10]]
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

Swift



func nextIndexOfIndex(index: Int,
                      direction: inout Int,
                      counterInDirection: inout Int,
                      hCount: inout Int,
                      vCount: inout Int,
                      rows: Int,
                      columns: Int) -> Int {


    var nextIndex = -1

    // 기존 방향으로의 카운터가 0
    // 더 이상 입력하지 못 하니 다음 방향으로 전환
    if counterInDirection == 0 {

        direction = (direction + 1) % 4
        switch direction % 2 {
        case 0:
            // 수평 이동으로 변경하고 새로운 방향으로 입력할 숫자 갯수 초기화
            counterInDirection = hCount
            hCount = hCount - 1

        case 1:
            // 상하 이동으로 변경 새로운 방향으로 입력할 숫자 갯수 초기화
            counterInDirection = vCount
            vCount = vCount - 1

        default:
            return nextIndex
        }
    }

    switch direction {
    case 0:
        nextIndex = index + 1
    case 1:
        nextIndex = index + columns
    case 2:
        nextIndex = index - 1
    case 3:
        nextIndex = index - columns
    default:
        return -1
    }

    counterInDirection = counterInDirection - 1 // 다음 인덱스를 구했으니 진행 방향 카운터 차감
    return nextIndex

}

func printSpiralMatrix(rows: Int, columns: Int) {

    // 행렬 입력 갯수 초기값
    var hCount = columns - 1    // matrix[0] = 0 으로 초기화 하면서 1 소진
    var vCount = rows - 1       // 최초 수평 이동으로 행 카운트 1 소진하고 시작

    let total = rows * columns

    var matrix: Array<Int> = Array(repeating: -1, count: total)

    matrix[0] = 0

    // 입력방향 초기값 0 for right
    var d = 0 // 방향 초기화
    var counterInDirection = hCount

    var nextIndex = 0

    // 행렬 크기 만큼 한 번의 루프로 행렬 생성
    for i in 1..<total {

        nextIndex = nextIndexOfIndex(index: nextIndex,
                                     direction: &d,
                                     counterInDirection: &counterInDirection,
                                     hCount: &hCount,
                                     vCount: &vCount,
                                     rows: rows,
                                     columns: columns)
        if nextIndex < 1 || nextIndex >= total {
            break
        }

        matrix[nextIndex] = i
    }


    // 출력 루프

    for i in 0..<total {

        print(matrix[i], terminator:"")

        if (i%columns) == (columns - 1) {
            print("")
        } else {
            print("\t", terminator:"")
        }
    }
}

printSpiralMatrix(rows: 6, columns: 6)

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

c로 풀이. 많이 조잡.


#include <stdio.h>
int main(void)
{
    int a,b,c,num=0;
    int i,j,k;
    int s[20][20];
    scanf("%d%d",&a,&b);
    if (a>=b) c=a;
    else c=b;
    for(k=0;k<c/2;k++)
    {
        i=j=k;
        for(i=k;i<a-k-1;i++) {s[j][i]=num++; if (num==a*b) break;}
        if (num==a*b) break;
        for(j=k;j<b-k-1;j++) {s[j][i]=num++; if (num==a*b) break;}
        if (num==a*b) break;
        for(i=a-k-1;i>k;i--) {s[j][i]=num++; if (num==a*b) break;}
        if (num==a*b) break;
        for(j=b-k-1;j>k;j--) {s[j][i]=num++; if (num==a*b) break;}
        if (num==a*b) break;
    }
    for(i=0;i<b;i++)
    {
        for(j=0;j<a;j++) printf(" %3d",s[i][j]);
        printf("\n");
    }
    return 0;
}

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
a1 = int(input("a1 입력 : "))
a2 = int(input("a2 입력 : "))
b = [[0 for i in range(a1)] for j in range(a2)]
num = 0
a1count = 0
a2count = 1
turn = 0
for turn in range((a1+a2)):
    for i in range(a1 - a1count):
        if a1 >= a1count:
            b[turn][i+turn] = num
            num += 1
    a1count += 1
    for i in range(a2 - a2count):
        if a2 >= a2count:
            b[i+(turn + 1)][a1 - (turn + 1)] = num
            num += 1
    a2count += 1
    for i in range(a1 - a1count):
        if a1 >= a1count:
            b[a2 - (turn + 1)][a1 - (turn + 2) - i] = num
            num += 1
    a1count += 1
    for i in range(a2 - a2count):
        if a2 >= a2count:
            b[a2 - (turn + 2)-i][turn] = num
            num += 1
    a2count += 1
sqrts = len(str(num))
for i in range(a2):
    for j in range(a1):
        print(("%0" + str(len(str(num))) + "d ")  % b[i][j],end = '')
        if j == a1-1:
            print()

b[0][0]부터 시작해서 수동으로 그려보고, 규칙성을 찾아 일반화시켰습니다.

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
n=input()
n=int(n)

a = [[0 for col in range(n)] for row in range(n)]
row=0#행
col=0#열
num=0#행렬에 들어갈 숫자
if n%2==0:#n=짝수일때
    cur=n-1
    tmp=n
    while cur>0:
        while col<cur:# right move
            a[row][col]=num
            num+=1
            col+=1
        while row<cur:# down move
            a[row][col]=num
            num+=1
            row+=1
        while col>=tmp-cur:# left move
            a[row][col]=num
            num+=1
            col-=1
        while row>=tmp-cur:#up move
            a[row][col]=num
            num+=1
            row-=1
        row+=1
        col+=1
        cur-=1#4
else:
    cur=n-1
    tmp=n
    while cur>1:
        while col<cur:# right move
            a[row][col]=num
            num+=1
            col+=1
        while row<cur:# down move
            a[row][col]=num
            num+=1
            row+=1
        while col>=tmp-cur:# left move
            a[row][col]=num
            num+=1
            col-=1
        while row>=tmp-cur:#up move
            a[row][col]=num
            num+=1
            row-=1
        row+=1
        col+=1
        cur-=1

    row=(int)(tmp/2)
    col=row
    a[row][col]=num

for i in range(n):
    for j in range(n):
        print(a[i][j],end=" ")
    print("\n")

``````{.python}
n=input()
n=int(n)

a = [[0 for col in range(n)] for row in range(n)]
row=0#행
col=0#열
num=0#행렬에 들어갈 숫자
if n%2==0:#n=짝수일때
    cur=n-1
    tmp=n
    while cur>0:
        while col<cur:# right move
            a[row][col]=num
            num+=1
            col+=1
        while row<cur:# down move
            a[row][col]=num
            num+=1
            row+=1
        while col>=tmp-cur:# left move
            a[row][col]=num
            num+=1
            col-=1
        while row>=tmp-cur:#up move
            a[row][col]=num
            num+=1
            row-=1
        row+=1
        col+=1
        cur-=1#4
else:
    cur=n-1
    tmp=n
    while cur>1:
        while col<cur:# right move
            a[row][col]=num
            num+=1
            col+=1
        while row<cur:# down move
            a[row][col]=num
            num+=1
            row+=1
        while col>=tmp-cur:# left move
            a[row][col]=num
            num+=1
            col-=1
        while row>=tmp-cur:#up move
            a[row][col]=num
            num+=1
            row-=1
        row+=1
        col+=1
        cur-=1

    row=(int)(tmp/2)
    col=row
    a[row][col]=num

for i in range(n):
    for j in range(n):
        print(a[i][j],end=" ")
    print("\n")

print(row,col)
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

def fspiral(N, M):

scale = N*M
count = 0 # 짝수면 반복문 전부 홀수면 절반 실행
x = 0
R = 0 # 싸이클이 끝나고 의 현재의 값 R

# k의 범위 구하기
while(scale > 0):
    if N-2*x-1 == 0 or M-2*x-1 == 0 :
        scale -= (M-2*x-1 + N-2*x-1 +1)
        count += 1
    else:
        scale -= (M-2*x-1 + N-2*x-1) 
        count += 1
    if scale != 0 :
        scale -= (M-2*x-1 + N-2*x-1)
        count += 1
    x += 1


# 2차원 배열 만들기
matrix = [[0 for row in range(M)] for col in range(N)]


#나선형으로 진행하는 좌표 
for k in range(x):
    #처음만 y좌표를 0으로 놓음
    #1
    if M-2*k-1 != 0 :
        for i1 in range(k, M-(k+2)+1):
            if k ==0:
                matrix[0][i1] = i1-k
                R = i1-k

            else:
                matrix[k][i1] = u + R 
                R = u + R

    else :
        matrix[k][k] = 1 + R 
        R = 1 + R


    #2
    if N-2*k-1  != 0:
        for i2 in range(k, N-(k+2)+1):
            u = 0
            u += 1
            matrix[i2][M-k-1] = u + R 
            R = u + R

    elif M-2*k-1 == 0 and N-2*k-1 == 0 :
        pass
    else :
        matrix[k][M-k-1] = 1+R 
        R = 1 + R
        print("2 %s" %R)

    count -= 1
    print("count= %s" %count)
    if count != 0:
        #3
        for i3 in list(reversed(range(k+1, M-(k+1)+1))):
            u = 0
            u += 1
            matrix[N-k-1][i3] =  u+R
            R = u+ R

        #4
        for i4 in list(reversed(range(k+1, N-(k+1)+1))):
            u = 0
            u += 1
            matrix[i4][k] = u + R 
            R = u+ R


        count -= 1

    else:
        break



# matrix 프린트
for X in range(N):
    for Y in range(M):
        chr1 = matrix[X][Y]
        print("%3d" %chr1, end = "")
    print("\n")
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

import java.util.Scanner;

public class Algorithm {

public static void main(String[] args) {
    // TODO Auto-generated method stub
    int right =0;
    int down =1;
    int left =2;
    int up =3;
    int direction = right;  
    Scanner sc = new Scanner(System.in);
    int row = sc.nextInt();
    int col = sc.nextInt();
    int end = row*col;
    int[][] result = new int[row][col];
    boolean[][] data  = new boolean[row][col];

    int hori = -1;
    int verti = 0;

    for(int i=0; i<end; i++){
        if(direction == right){
            hori++;
            if(hori>=col || data[verti][hori]){
                hori--; verti++;
                result[verti][hori] = i;
                data[verti][hori] = true;
                direction = down;
            }else{
                result[verti][hori] = i;
                data[verti][hori] = true;
            }
        }else if(direction == down){
            verti++;
            if(verti>=row || data[verti][hori]){
                verti--; hori--;
                result[verti][hori] = i;
                data[verti][hori] = true;
                direction = left;
            }else{
                result[verti][hori] = i;
                data[verti][hori] = true;
            }
        }else if(direction == left){
            hori--;
            if(hori<0 || data[verti][hori]){
                hori++; verti--;
                result[verti][hori] = i;
                data[verti][hori] = true;
                direction = up;
            }else{
                result[verti][hori] = i;
                data[verti][hori] =true;
            }
        }           
        else if(direction == up){
            verti--;
            if(data[verti][hori]){
                verti++; hori++;
                result[verti][hori] = i;
                data[verti][hori] = true;
                direction = right;
            }else{
                result[verti][hori] = i;
                data[verti][hori] = true;
            }
        }

    }

    for(int i=0; i<row;i++){
        for(int j=0; j<col; j++){
            if(result[i][j] <10){
                System.out.print("   "+result[i][j]);
            }else{
            System.out.print("  "+result[i][j]);}
        }
        System.out.println("");
    }
}

}

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

풀이 작성

※ 풀이작성 안내
  • 본문에 코드를 삽입할 경우 에디터 우측 상단의 "코드삽입" 버튼을 이용 해 주세요.
  • 마크다운 문법으로 본문을 작성 해 주세요.
  • 풀이를 읽는 사람들을 위하여 풀이에 대한 설명도 부탁드려요. (아이디어나 사용한 알고리즘 또는 참고한 자료등)
  • 작성한 풀이는 다른 사람(빨간띠 이상)에 의해서 내용이 개선될 수 있습니다.
목록으로
코딩도장

코딩도장은 프로그래밍 문제풀이를 통해서 코딩 실력을 수련(Practice)하는 곳입니다.


언어별 풀이 현황
전 체 x 153
objectivec x 2
java x 32
javascript x 2
python x 47
기 타 x 19
cpp x 35
cs x 6
delphi x 1
go x 1
ruby x 2
lisp x 2
clojure x 1
scala x 3