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 매트릭스에 나선형 회전을 한 값을 출력해야 한다.

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

31개의 풀이가 있습니다. 1 / 4 Page

public enum Direction { // 방향을 나타내는 enum입니다~
    RIGHT(1), BOTTOM(2), LEFT(3), TOP(4);
    private int value;

    private Direction(int value) {
        this.value = value;
    }
}

public class Sprial {

public void sprialArray(int row, int col) {
        int[][] arr = new int[row][col];

        // -1로 초기화
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr.length; j++) {
                arr[i][j] = -1;
            }
        }

        int num = 0; // 시작 숫자
        int rIdx = 0, cIdx = 0; // row, col에 대한 index
        Direction direction = Direction.RIGHT;

        while( num < row * col ) {
            arr[rIdx][cIdx] = num++;

            switch ( direction ) {
            case RIGHT:
                if( cIdx+1<col && arr[rIdx][cIdx+1] == -1 ){
                    cIdx++;
                }else {
                    direction = Direction.BOTTOM;
                    rIdx++;
                }
                break;
            case BOTTOM:
                if( rIdx+1<row && arr[rIdx+1][cIdx] == -1 ){
                    rIdx++;
                }else {
                    direction = Direction.LEFT;
                    cIdx--;
                }
                break;
            case LEFT:
                if( cIdx-1>=0 && arr[rIdx][cIdx-1] == -1 ){
                    cIdx--;
                }else {
                    direction = Direction.TOP;
                    rIdx--;
                }               
                break;
            case TOP:
                if( rIdx-1>=0 && arr[rIdx-1][cIdx] == -1 ){
                    rIdx--;
                }else {
                    direction = Direction.RIGHT;
                    cIdx++;
                }
                break;
            default:
                break;
            }
        }
    }
}

~_~ 전 이 문제 푸는데 되게 오래 걸렸어요.. 내공이 많이 부족함을 느낍니다 ㅠㅠ 분명 예~전에 처음 플그래밍 배울때 봤던 문제였떤 것 같은데, 그때 어렵다고 패스했던 것을 다시 공부하지 않은 탓인것 같네요..ㅜ

+1 switch case 에 enum 을 같이 쓰니 소스가 참 보기 좋네요 ^^ - 길가의풀, 2014/05/09 08:55 M D
1,2,3,4로 했었는데, 보다 암걸릴 것 같아서 enum 으로 바꿨어요^^ 이참에 활용 잘 해봐야겠어요~~ - 이 승효, 2014/05/09 13:11 M D
enum 처리 보기좋네요ㅎㅎ - 이재범, 2014/06/18 13:50 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

4일이나 걸렸어요... 매일 2시간씩 해서 했는데

이 코드는 아무래도 if문이 너무 많아서 반복문내에서 매 번 if문을 하나하나 다 검사한다는게

썩 좋진 않아보이네요. 실행속도가 현저히 느릴거 같아요... 그래도 완성해서 매우 기쁩니다!

/*
입력: 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 매트릭스에 나선형 회전을 한 값을 출력해야 한다.
*/

import java.util.Arrays;
import java.util.Scanner;

public class Spiral_Array
{
    public static void main(String[] args)
    {
        // 출력될 숫자
        int output_Number=0; 

        // 값을 두 개 입력받습니다.
        Scanner in = new Scanner(System.in);
        int n1 = in.nextInt();
        int n2 = in.nextInt();

        // 숫자가 들어갈 매트릭스를 생성합니다.
        int[][] Matrix = new int[n1][n2];

        // 배열 값들을 다 -1로 초기화 (2D)
        for (int[] row: Matrix)
            Arrays.fill(row, -1);

        //위치 선택용 변수
        int col=0, row=0, t_col=0, t_row=1, angle = 0;

        // row가 늘고 col가 늘고 row가 줄고 col가 줄고 row가 늘고 col가 늘고 ... 계속 반복함
        for(int i=0; i<(n1*n2); i++)
        {
            Matrix[col][row]=output_Number;
            output_Number++;
            row = row + t_row;
            col = col + t_col;

            if(row==n2){ // 1번째 코너
                row--;
                col++;
                t_col = t_row;
                t_row = 0;
            }
            if(col==n1){ // 2번째 코너
                col--;
                row--;
                t_row = -t_col;
                t_col = 0;
            }
            if(row<0){ // 3번째 코너
                row++;
                col--;
                t_col = t_row;
                t_row = 0;
            }

            if(Matrix[col][row] != -1)  // 다른 수가 있다면(3번째 이후 모서리 봉착)
            {
                angle++; 
                if(angle == 1)// ┌자 구간에 진입했을때
                {
                    row++;
                    col++;
                    t_col = 0;
                    t_row = 1;
                }
                else if(angle == 2) // ┐자 구간에 진입했을때
                {
                    col++;
                    row--;
                    t_col = 1;
                    t_row = 0; 
                }

                else if(angle == 3) // ┘자 구간에 진입했을때
                {
                    col--;
                    row--;
                    t_col = 0;
                    t_row = -1;
                }
                else if(angle == 4) // └자 구간에 진입했을때
                {
                    col--;
                    row++;
                    t_col = -1;
                    t_row = 0;

                    angle = 0; // 다시 초기화
                }
            }
        }

        // 출력
        for(int a=0; a<n1; a++){
            for(int b=0; b<n2; b++){
                System.out.print(Matrix[a][b] + "\t");
            }
            System.out.println();
        }
    } // main
} // class
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.

안녕하세요^^ Java를 배우고 있는 학생입니다. 초보이지만 한번 짜봤어요^^ 좋은 크리틱 해주시면 감사하게 듣겠습니다^^

package h10_spiral_array;
import java.util.Scanner;
public class SpriralArray {

    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        int r1, r2, n, i, j, direction;
        r1=in.nextInt(); r2=in.nextInt(); //값 두개 입력받기
        int total=r1*r2;
        int[][] arr=new int[r1][r2];
        boolean[][] check=new boolean[r1][r2];
        for(i=0;i<r1;i++) for(j=0;j<r2;j++) check[i][j]=false; //check배열 초기화
        n=0; i=0; j=0; direction=0; //direction 방향 0:east, 1:south, 2:west, 3:north
        while(n<total){
            if(i>=0&&i<r1&&j>=0&&j<r2&& check[i][j]==false){ //값 차례대로 넣기
                arr[i][j]=n; check[i][j]=true; n++;
                if(direction==0) j++;
                else if(direction==1) i++;
                else if(direction==2) j--;
                else if(direction==3) i--;
            }
            else{ //한 방향으로 끝까지 갔을 경우 방향 바꾸기
                if(direction==0){ direction=1; j--; i++; }
                else if(direction==1){ direction=2; i--; j--; }
                else if(direction==2){ direction=3; j++; i--; }
                else if(direction==3){ direction=0; i++; j++; }
            }
        }
        for(i=0;i<r1;i++){ //값 출력하기. 일단 total이 100미만인 경우만 생각했어요^^
            for(j=0;j<r2;j++){
                if(arr[i][j]<10) System.out.print(" ");
                System.out.print(arr[i][j]+" ");
            } System.out.println();
        }
    }
}

※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
private void test() {
    int size = 6;
    int[][] arr = new int[size][size];
    for(int i=0; i<6; i++) {
        for(int k=0; k<6; k++) {
            arr[i][k] = -1;
        }
    }
    int m = 1;
    int x = 0;
    int y = 0;
    int n = 0;
    while(n<size*size) {
        if(x>-1 && x<arr[0].length && y>-1 && y<arr.length && (arr[y][x]== -1)) {
            arr[y][x] = n;  
            n++;
            if(1 == m) {//오른쪽
                x++;
            } else if(2 == m) {//아래
                y++;
            } else if(3 == m) {//왼쪽
                x--;
            } else if(4 == m) {//위
                y--;
            }   
        } else {
            if(1 == m) {
                m = 2; x--; y++;
            } else if(2 == m) {
                m = 3; x--; y--;
            } else if(3 == m) {
                m = 4; x++; y--;
            } else if(4 == m) {
                m = 1; x++; y++;
            }   
        }
    }

    for(int i=0; i<6; ++i) {
        String a = "";
        for(int k=0; k<6; ++k) {
            if(10 > arr[i][k]) {
                a += "  "+arr[i][k];
            } else {
                a += " "+arr[i][k];
            }
        }
        LOG.v(" "+a);
    }
}
풀고보니 윗님하고 비슷..ㅎㅎ/ - 김대원, 2014/03/30 21:32 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
// 처음에 고민했는데 낮잠자다가 생각나서 풀었네요ㅎㅎ Java입니다ㅎㅎ
import java.util.Scanner;

public class SpiralArray {
    public static void main(String[] args) {
        System.out.println("생성할 Spiral Array의 크기를 입력해주세요(예> 6 6)");
        Scanner sc = new Scanner(System.in);
        int a,b = 0;

        // Validation Check

        a = sc.nextInt();
        b = sc.nextInt();

        int[][] arr = new int[a][b];

        for(int k=0; k<a; k++){
            for(int l=0; l<b; l++){
                arr[k][l] = a*b;
            }
        }

        int count=0, i=0, j=0;
        // type 1 _ j++ (->)
        // type 2 _ i++ (밑)
        // type 3 _ j-- (<-)
        // type 4 _ i-- (위)
        int type = 1;

        // while 4번
        while(count < (a * b)){
            if(type == 1){
                arr[i][j++] = count++;
                if(j==b || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
                    j--;
                    i++;
                    type++;
                }
            }else if(type == 2){
                arr[i++][j] = count++;
                if(i==a || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
                    i--;
                    j--;
                    type++;
                }
            }else if(type == 3){
                arr[i][j--] = count++;
                if(j==-1 || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
                    j++;
                    i--;
                    type++;
                }
            }else{ // type == 4
                arr[i--][j] = count++;
                if(i==-1 || (arr[i][j] != a*b)){ // 다음 값이 이미 존재하거나 배열의 끝이면
                    i++;
                    j++;
                    type = 1;
                }
            }
        }

        // Spiral Array 확인
        for(int k=0; k<a; k++){
            for(int l=0; l<b; l++){
                System.out.print(arr[k][l] + "  ");
            }
            System.out.println();
        }

    }
}

적고 보니 Scanner 받은 데이터 유효성 체크하는거 까먹었네요ㅠ - 이재범, 2014/06/18 13:52 M D
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
import java.util.Arrays;


public class SpiralArray {
    int data[][];
    int row;
    int col;    
    public static final int UP=0, RIGHT=1, DOWN=2, LEFT=3; 
    String msg;
    public SpiralArray(int row, int col) {
        super();
        this.row = row;
        this.col = col;
        this.data= new int[row][col];
        for(int i=0;i<row;i++){
            for(int j=0;j<col;j++)
                data[i][j]=-1;
        }
        msg=null;
    }
    public void fill(){
        int x=0, y=0, way=RIGHT;        
        if(data==null) {
            System.out.println("Cannot fill SpiralArray!");
            return;
        }       

        for(int i=0;i<row*col;i++){         
            data[y][x]=i;           
            switch(way){
                case UP:
                    if(y==0 || data[y-1][x]!=-1){
                        way=RIGHT;
                        x+=1;
                    }else{
                        y-=1;
                    }
                    break;
                case DOWN:
                    if(y==row-1 || data[y+1][x]!=-1){
                        way=LEFT;
                        x-=1;
                    }else{
                        y+=1;
                    }
                    break;
                case RIGHT:
                    if(x==col-1 || data[y][x+1]!=-1){
                        way=DOWN;
                        y+=1;
                    }else{
                        x+=1;
                    }
                    break;
                case LEFT:
                    if(x==0 || data[y][x-1]!=-1){
                        way=UP;
                        y-=1;
                    }else{
                        x-=1;
                    }
                    break;                  
            }           
        }
    }
    public void show(){     
        if(data==null || msg!=null) {
            System.out.println("Cannot print SpiralArray!");
            return;
        }

        msg="";
        for(int i=0;i<row;i++){
            for(int j=0;j<col;j++)
                msg+=String.format(" %4d", data[i][j]);
            msg+="\n";
        }
        System.out.println(msg);
        msg=null;
    }
    public static void main(String[] args) {
        int row, col;
        SpiralArray spiralArray = new SpiralArray(6, 6);
        spiralArray.fill();
        spiralArray.show();
    }
}

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

JAVA

공부 열심히 해야겠습니다.

import java.util.Scanner;

public class go {

    public static void main(String args[]) {

        Scanner sc = new Scanner(System.in);
        System.out.print("숫자를 입력하세요  ex) 6 6 : ");
        int num1 = sc.nextInt();
        int num2 = sc.nextInt();

        spiralArray(num1, num2);

    }

    public static void spiralArray(int x, int y) {

        int[][] copy = new int[x][y]; 
        int count = 0;      // 0  ~  x*y-1 값
        int flag = 0;       // 진행방향
        int i = 0, j = 0;   

        while (true) {
            switch (flag) {                         //  진행방향    -> 
            case 0:                                 //  방에 값을 넣고 1 증가 시킴
                copy[i][j++] = count++;             //  다음 방향으로 한칸 이동
                if (j == y || copy[i][j] != 0) {    //  이동한 방에 값이 있거나 방이 없으면
                    j--;                            //  이전 방으로 돌아온다
                    i++;                            //  다음 진행할 방향으로 한칸이동
                    flag = 1;                       //  진행방향 설정
                }
                break;
            case 1:                                 //  진행방향    ↓
                copy[i++][j] = count++;
                if (i == x || copy[i][j] != 0) {
                    i--;
                    j--;
                    flag = 2;
                }
                break;
            case 2:                                 //  진행방향    <-
                copy[i][j--] = count++;
                if (j == -1 || copy[i][j] != 0) {
                    i--;
                    j++;
                    flag = 3;
                }
                break;
            case 3:                                 //  진행방향    ↑
                copy[i--][j] = count++;
                if (i == 0 || copy[i][j] != 0) {
                    i++;
                    j++;
                    flag = 0;
                }
                break;
            }

            if (count == x * y)    // 모든방에 값이 들어가면 나가기
                break;
        }

        for (i = 0; i < x; i++) {
            for (j = 0; j < y; j++) {
                System.out.print(copy[i][j] + "\t");
            }
            System.out.println();
        }
    }

}

결과 값

숫자를 입력하세요 ex) 6 6 : 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

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

import java.util.Scanner;

//나선형 행렬
public class Test2 {

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        int i = 0;
        int j = 0;
        int end_row,end_col; //행,열 상한 값
        int start_row = 0; //행 하한 값
        int start_col = 0; //열 하한 값
        int count1 = 0; //한바퀴(우,하,좌,상) 횟수
        int count2 = 0; //입력할 정수
        int row,col; // 행열의 크기
        int exit = 1; // 다 돌았을 경우 종료

        Scanner scan = new Scanner(System.in);

        //행, 열 입력 받기
        System.out.println("행 수를 입력하세요.");
        row = scan.nextInt();
        System.out.println("열 수를 입력하세요.");
        col = scan.nextInt();

        end_row = row;
        end_col = col;

        //매트릭스 배열 선언
        int[][] list = new int[row][col];

        //반복문 횟수
        count1 = (row+1)/2;

        for(i=0; i<row; i++)
        {
            for(j=0; j<col; j++)
            {
                list[i][j] = -1;
            }

        }

        i=0;
        j=0;

        while(count1 > 0)
        {
            //우
            for(j=start_col; j<end_col; j++)
            {
                if(list[i][j] == -1)
                {
                    list[i][j] = count2++;
                }
                else
                {
                    exit = 0;
                    break;
                }
            }

            start_row++;
            j--;

            //하
            for(i=start_row; i<end_row; i++)
            {
                if(list[i][j] == -1)
                {
                    list[i][j] = count2++;
                }
                else
                {
                    exit = 0;
                    break;
                }
            }

            i--;
            end_col--;

            //좌
            for(j=end_col-1; j>=start_col; j--)
            {
                if(list[i][j] == -1)
                {
                    list[i][j] = count2++;
                }
                else
                {
                    exit = 0;
                    break;
                }
            }

            j++;
            end_row--;

            //상
            for(i=end_row-1; i>=start_row; i--)
            {
                if(list[i][j] == -1)
                {
                    list[i][j] = count2++;
                }
                else
                {
                    exit = 0;
                    break;
                }
            }

            if(exit == 0)
                break;
            else
            {
                start_col++;
                i++;
                count1--;
            }
        }


        //행렬 출력
        for(i=0; i<row; i++)
        {
            for(j=0; j<col; j++)
            {
                System.out.printf("%3d\t", list[i][j]);
            }
            System.out.println();
        }
    }

}

후 오래걸렸네요... 더 개선할 수 있으면 지적 좀 해주세요!!

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

자바입니다.##

class SpiralArray
{
    private int row, col;

    public SpiralArray(int row, int col)
    {
        this.row = row;
        this.col = col;
    }

    public void calc()
    {
        int row = this.row-1;
        int col = this.col-1;
        int arr[][] = new int[row+1][col+1];
        int count = 0;
        int temp = 0;
        int last = 0;

        while(temp <= row / 2)
        {
            for(int j=temp; j<=col - temp; j++)
            {
                arr[temp][j] = last + count++;
            }
            count = 0;
            for(int i=temp; i<=row-temp; i++)
            {
                arr[i][col-temp] = arr[temp][col-temp] + count++;
            }
            count = 0;
            for(int j=col-temp; j>=temp; j--)
            {
                arr[row-temp][j] = arr[row-temp][col-temp] + count++;
            }
            count = 0;
            for(int i=row-temp; i>temp; i--)
            {
                arr[i][temp] = arr[row-temp][temp] + count++;
            }
            last = arr[temp+1][temp]+1;
            count = 0;
            temp++;
        }

        print(arr);
    }

    public void print(int[][] arr)
    {
        for(int i=0; i<row; i++)
        {
            for(int j=0; j<col; j++)
            {
                System.out.printf("%4d", arr[i][j]);
            }
            System.out.println();
        }
    }
}
※ 상대에게 상처를 주기보다 서로에게 도움이 될 수 있는 댓글을 달아 주세요.
package rootcucu.codefight;
import java.util.*;
import java.awt.Point;
public class Spiral {
    int width;
    int height;
    int arr[];
    Spiral(int width, int height){
        this.width = width;
        this.height = height;
    }

    public void write(){
        for (int y = 0; y < height; y++){
            for (int x = 0; x < width; x++){
                System.out.format("%3d ", arr[y*width + x]);
            }
            System.out.print("\n\n");
        }
    }
    void make(){
        arr = new int[width * height];
        Arrays.fill(arr, -1);
        Point p = new Point(0, 0);
        int dX = 1, dY = 0; // prefix d means delta.
        for (int number = 0; number < width*height; number++){
            setValue(p, number);
            Point pNext = getNext(p, dX, dY);
            if (!isWritableLocation(pNext)){
                pNext = findNextLocation(p);
                if (pNext != null){
                    dX = pNext.x - p.x;
                    dY = pNext.y - p.y;
                }
            }
            p = pNext;
        }
    }

    private Point getNext(Point p, int dX, int dY){
        return new Point(p.x + dX, p.y + dY);
    }

    private void setValue(Point p, int number){
        arr[getPos(p)] = number;
    }

    private boolean isWritableLocation(Point p){
        int x = p.x;
        int y = p.y;
        if ((x < 0) || (x >= width) || (y < 0) || (y >= height))
            return false;
        return arr[getPos(p)] == -1;
    }

    // findWritableLocationAdjacentTo 가 더 적절해 보임.
    private Point findNextLocation(Point p){
        int[][] directions = new int[][]{{0,1},{0,-1},{1,0},{-1,0}};
        for (int[] direction:directions){
            Point pNext = new Point(p.x + direction[0], p.y + direction[1]);
            if (isWritableLocation(pNext)){
                return pNext;
            }
        }
        return null;
    }

    private int getPos(Point p){
        return p.y*width + p.x;
    }
    public static void main(String[] args){
        Scanner scanner = new Scanner(System.in);
        while (true){
            System.out.println("input width, height (-1 to finish)");
            int width = scanner.nextInt();
            if (width < 0)
                return;
            int height = scanner.nextInt();
            Spiral obj = new Spiral(width, height);
            obj.make();
            obj.write();
        }
    }

}

실행 결과

input width, height (-1 to finish)
3 4
0 1 2

9 10 3

8 11 4

7 6 5

input width, height (-1 to finish)
8 5
0 1 2 3 4 5 6 7

21 22 23 24 25 26 27 8

20 35 36 37 38 39 28 9

19 34 33 32 31 30 29 10

18 17 16 15 14 13 12 11

input width, height (-1 to finish)
-1


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

풀이 작성

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

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


언어별 풀이 현황
전 체 x 142
기 타 x 14
java x 31
cpp x 35
python x 44
lisp x 2
ruby x 2
cs x 6
scala x 3
clojure x 1
objectivec x 1
go x 1
delphi x 1
javascript x 1