반응형

달팽이 배열은 배열에 데이터를 달팽이 껍질형태로 차례대로 채워나가는 것을 말한다.

 

달팽이 배열

 

채우는 동작 원리)

- 4 x 4 배열 생성

1. 생성 방식은 첫 행인 0행부터 마지막 열인 3열까지 차례대로 숫자를 찍는다.

(작업이 끝나면 첫행을 1행으로 증가시킨다.)

  0열 1열 2열 3열
0행 1 2 3 4
1행        
2행        
3행        

 

2. 증가된 첫행인 1행부터 마지막 행 3행까지 마지막 열인 3열에 숫자를 넣는다.

(마지막 열인 3열을 하나 감소시킨다.)

  0열 1열 2열 3열
0행 1 2 3 4
1행       5
2행       6
3행       7

 

 

3. 마지막 열이 2열으로 바뀌었고(마지막 열이 2번에서 동작 후 감소됨) 부터 첫 열까지 차례대로 마지막 행 3행에 찍는다. (마지막 행인 3행을 감소시킨다.)

  0열 1열 2열 3열
0행 1 2 3 4
1행       5
2행       6
3행 10 9 8 7

 

4. 마지막 행인 2행부터 첫 행인 1행까지 숫자를 채운다.3번에서 마지막행이 3행에서 감소하여 2행이 됨, 1번에서 첫행이 증가하여 첫행은 1행이 됨 (첫열을 증가시킨다. 1열 증가시킨다.)

  0열 1열 2열 3열
0행 1 2 3 4
1행 12     5
2행 11     6
3행 10 9 8 7

 

5. 1번에서 했던 동작을 다시 반복한다.

  0열 1열 2열 3열
0행 1 2 3 4
1행 12 13 14 5
2행 11     6
3행 10 9 8 7

 

6. 2번에서 했던 동작을 반복한다.

  0열 1열 2열 3열
0행 1 2 3 4
1행 12 13 14 5
2행 11   15 6
3행 10 9 8 7

 

7. 3번에서 했던 동작을 반복한다.

  0열 1열 2열 3열
0행 1 2 3 4
1행 12 13 14 5
2행 11 16 15 6
3행 10 9 8 7

 

8. 4번에서 했던 동작을 반복한다.

for문 종료조건으로 인해 만족되지 않아 실행되지 않는다.

index.html

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Snail Array</title>
    <style media="screen">
      body{
        background: #fff;
      }
      td{
        width: 50px;
        height: 50px;
        background: #fff;
        color: #fff;
        text-align: center;
      }
    </style>
    <script type="text/javascript" src="js-snail.js"></script>
  </head>
  <body>
    <table id="snail">

    </table>
  </body>
</html>

 

js-snail.js

window.onload=function(){
  (function(){
    var rows = prompt("행의 개수를 입력하세요");
    var cols = prompt("열의 개수를 입력하세요");

    var drawArr = createSnailArray(rows, cols);
    drawAnimate(drawArr);
  })();

}

/* 달팽이 배열을 만드는 함수
 * @param rows : 생성할 2차원 배열의 행 개수
 * @param cols : 생성할 2차원 배열의 열 개수
 */
function createSnailArray(rows, cols){
  // 애니메이션 효과용 1차원 배열 선언 및 초기화
  var drawArr = new Array();

  // 달팽이 형태로 데이터를 삽입할 2차원 배열 선언 및 초기화
  var arr = new Array();
  for(i=0; i<rows; i++){
    arr[i] = new Array();
  }

  var num = 1; //삽입할 데이터  1, 2, 3, 4, 5 ...

  var row_min = 0;       //행 최소값
  var col_min = 0;       //열 최소값
  var row_max = rows-1;  //행 최대값
  var col_max = cols-1;  //열 최대값

  var cycle = 0;         //그리면서 for문을 돌릴 바퀴 수
  if(rows >= cols){
    cycle = cols/2;
  }else{
    cycle = rows/2;
  }

  for(i=0; i<cycle; i++){

    //상단 출력
    for(j=col_min; j<=col_max; j++){
      arr[row_min][j] = num++;
      drawArr.push("td"+row_min+j);
    }
    row_min++;
    if(cols*rows +1 == num)  //사이즈가 안맞는 경우 강제 종료
      break;


    //우측 출력
    for(j=row_min; j<=row_max; j++){
      arr[j][col_max] = num++;
      drawArr.push("td"+j+col_max);
    }
    col_max--;
    if(cols*rows +1 == num)  //사이즈가 안맞는 경우 강제 종료
      break;

    //하단 출력
    for(j=col_max; j>=col_min; j--){
      arr[row_max][j] = num++;
      drawArr.push("td"+row_max+j);
    }
    row_max--;
    if(cols*rows +1 == num)  //사이즈가 안맞는 경우 강제 종료
      break;

    //좌측 출력
    for(j=row_max; j>=row_min; j--){
      arr[j][col_min] = num++;
      drawArr.push("td"+j+col_min);
    }
    col_min++;
    if(cols*rows +1 == num)  //사이즈가 안맞는 경우 강제 종료
      break;

  }
  var snail = document.getElementById("snail");
  appendTag(snail, arr);

  return drawArr; //애니메이션을 차례대로 그릴 ID값이 담긴 1차원 배열 반환
}

/* HTML 태그 target을 지정하여 생성하는 함수
 * @param target : 생성, 접근할 요소 dom형태로 전달
 * @param data   : 생성할 데이터 배열 전달
 */
function appendTag(target, data){
  var tag = "";

  for(i=0; i<data.length; i++){
    tag += "<tr>"
    for(j=0; j<data[i].length; j++){
      tag += "<td id='td"+i+j+"'>"+data[i][j]+"</td>"
    }
    tag += "</tr>"
  }

  target.innerHTML = tag;
}

/* 0.3초마다 배열에서 ID값을 하나씩 접근하여 색상 처리
 * @param arr : 아이디값이 담긴 배열
 */
function drawAnimate(arr){

  for(i=0; i<arr.length; i++){    
    (function(x){
      setTimeout(()=>{
        document.getElementById(arr[x]).style.background = "#FAAC58";
      }, 300*x)
    })(i);
  }
}

 

prompt 창으로 열과 행의 입력을 받은 후, 빙글 빙글 돌아가면서 달팽이 형태로 배열을 채우고 출력하는 소스이다.

열과 행이 1개차이까진 문제가 없지만 2개이상 차이가 나면 계속해서 도는 문제가 있어

이너 for문안에서 종료조건을 마지막 데이터값으로 체크하여 break 처리를 하였다.

더 좋은 로직이 있다면 코멘트 부탁드립니다.

생성할 행 입력

 

생성할 열 입력

 

7 X 5 배열 생성 결과

반응형