지난 2월에 회사 워크샵에서 풀었던 나선형 배열 문제에 대한 글을 올린 적이 있었지요. ( http://blog.benelog.net/901106 )
알고보니 xper.org에도 이 문제가 올라와 있더군요 (http://xper.org/wiki/seminar/SpiralArray). 거기에 가면 다른 분들의 풀이도 많이 볼 수 있습니다. 저는 이 문제를 실컷 가지고 논 후에 더 이상 손 댈 것이 없다고 느껴질때 다른 분들의 풀이를 꼼꼼히 볼 생각입니다.
우연찮게 이에 대한 확장된 문제를 다른 블로그에서 보게 되었습니다. (http://blog.naver.com/itioma?Redirect=Log&logNo=40040118386 ). 그 포스트에서 본 문제에는 아래의 조건들이 더 추가되어 있었습니다.
-
작성된 코드에서 한 글자만 수정해서 '숫자는 1씩 늘어난다’를 '숫자는 2씩 늘어난다’로 바꾸시오.
-
코드에서 한 문장만 수정해서 시작점 좌표(x,y)를 마음대로 바꿀 수 있도록 만드시오
-
코드에서 한 문장만 수정해서 시작할 때의 진행방향을 (위/아래/왼쪽/오른쪽 중에서 ) 바꿀 수 있도록 만드시오
-
배열의 크기를 마음대로 정할 수 있도록 만드시오.
-
코드에서 한 문장만 수정해서 '시계방향으로 90도’를 '반시계 반향으로 90’도로 바꾸시오
-
코드에서 swich 문이나 else 문을 이용한 3단계 이상의 조건분기가 있다면 모두 제거하시오.
-
코드에서 한 글자만 수정해서 '한칸씩 진행하며’를 두칸씩 건너뛰며’로 바꾸시오.
-
1~7에서 수정되었던 문장/값/변수들이모두 하나의 함수 또는 블럭안에 존재하도록 고치시오.
그리고 숫자는 1에서 시작하고 , 채워지지 않은 부분이 있다면 0으로 표시된다는 점이 제가 처음에 풀었던 문제와 다르네요.
확장된 조건을 다 수용할 수 있는 만족시키는 코드를 다시 한번 만들어보았습니다.
소스코드
public class MatrixMain {
public static void main(String[] args) {
System.out.println("0.원래의 matrix");
ExtMatrix mp = new ExtMatrix(6,6);
mp.print();
System.out.println("1.숫자가 2씩 늘어나게");
mp.setIncrement(2);
mp.print();
System.out.println("2.시작점을 1,1로");
mp.setStartPoint(1, 1);
mp.print();
System.out.println("3.시작방향을 아래부터");
mp.setStartDirection(ExtMatrix.DOWN);
mp.print();
System.out.println("4.배열크기 바꾸는건 생성할때 파라미터 바꾸면 됨.");
System.out.println();
System.out.println("5.반시계 반향으로 회전");
mp.setReverseClockWiseTurn();
mp.print();
System.out.println("6.그런 조건 분기 없음.");
System.out.println();
System.out.println("7.한칸씩이 아닌 두칸씩 건너뛰며.");
mp.setMoveStep(2);
mp.print();
}
}
public class ExtMatrix {
public static final int RIGHT = 0;
public static final int DOWN = 1;
public static final int LEFT = 2;
public static final int UP = 3;
private static final int INIT_VALUE = 0;
private static final int CLOCK_WISE_TURN = 1;
private static final int REVERSE_CLOCK_WISE_TURN = -1;
private int m = 0;
private int n = 0;
private int startX = 0;
private int startY = 0;
private int[][] matrix;
private int startDirection = RIGHT;
private int increment = 1;
private int moveStep = 1;
private int turnDirection = CLOCK_WISE_TURN;
public ExtMatrix(int m, int n){
this.m = m;
this.n = n;
matrix = new int[m][n];
}
public void setIncrement(int increment){
this.increment = increment;
}
public void setStartPoint(int startX, int startY){
this.startX = startX;
this.startY = startY;
}
public void setClockWiseTurn(){
turnDirection = CLOCK_WISE_TURN;
}
public void setReverseClockWiseTurn(){
turnDirection = REVERSE_CLOCK_WISE_TURN;
}
public void setMoveStep(int moveStep){
this.moveStep = moveStep;
}
public void setStartDirection(int startDirection){
this.startDirection = startDirection;
}
public void print(){
locateNumbers();
for (int i=0;i< m ;i++){
for (int j=0;j<n;j++) System.out.print(matrix[i][j] + "\t");
System.out.println();
}
System.out.println();
}
private void locateNumbers() \{
init();
int[] startPosition = new int[]\{startX,startY};
matrix[startX][startY]= 1;
int direction = startDirection;
while(move(startPosition ,direction)) direction= getNextDirection(direction);
}
private void init(){
for (int i=0;i< m ;i++){
for (int j=0;j<n;j++) matrix[i][j] = INIT_VALUE;
}
}
private boolean move(int[] position, int direction){
int nowNumber = matrix[position[0]][position[1]];
boolean moved = false;
int[] nextPosition =getNextPosition(position,direction);
while(isMovable(nextPosition[0],nextPosition[1])){
moved = true;
nowNumber+= increment;
position[0] = nextPosition[0];
position[1] = nextPosition[1];
matrix[position[0]][position[1]]= nowNumber;
nextPosition = getNextPosition(position,direction);
}
return moved;
}
private int[] getNextPosition(int[] position,int direction){
int x = position[0];
int y = position[1];
if (direction == RIGHT) y+= moveStep;
else if (direction == DOWN) x+= moveStep;
else if (direction == LEFT) y-= moveStep;
else if (direction == UP) x-= moveStep;
return new int[]\{x,y};
}
private int getNextDirection(int direction){
direction+= turnDirection;
if (direction<0) direction+=4;
direction = direction %4;
return direction;
}
private boolean isMovable(int x, int y){
if (x>=m) return false;
if (y>=n) return false;
if (x<0) return false;
if (y<0) return false;
if (matrix[x][y]!= INIT_VALUE) return false;
return true;
}
}
방향을 int로 나타내는 것이 처음에는 좋은 아이디어 라고 생각했는데 mp.setStartDirection(ExtMatrix.DOWN);
부분을 보니 타입안전열거형이나 enum을 도입해야지 좀더 코드가 이뻐질 것 같네요.
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Email