어쩌다 풀다, 못 풀어서 다시 풀어 본 코딩 테스트 문제

Explanation

어제인가, 그제인가 우연히 회사에서 코딩 테스트 문제를 풀어 볼 일이 있었습니다. 총 4문제였는데, 어디서 온 자신감인지 당연히 다 풀 수 있을 줄 알았는데, 마지막 문제를 한 시간 동안 풀지 못했습니다.

하...

그 문제는 이러했습니다.

정확하게 기억나지 않지만 함수에 인자 값으로 x, y를 주며 x는 행 y는 열을 나타낸다. 그리고 1부터 시작해서 시계방향 소용돌이 모양으로 값을 출력한다.
예를 들어 x=2, y=2가 주어진다면 출력값은 아래와 같습니다.

1  2
4  3

조금 더 이해를 위해 x=5, y=7가 주어지면 출력해야 하는 값은 아래와 같습니다.

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

약간의 오기가 생겨, 오늘은 이 문제를 풀어보았습니다.

풀이

function main(x, y) {

	function directionFnc() {
		let direction = ['right', 'bottom', 'left', 'top'];
		let idx = -1;
		return () => {
			idx = idx + 1 > 3 ? 0 : idx + 1;
			return direction[idx];
		};
	}

	const direction = directionFnc();
	const dataCase = [];
	
	let nowDirection = direction();
	let endCheck = false;
	let no = 1;
	let posX = 0;
	let posY = 0;

	for(let i=0; i<x; i++) {
		dataCase.push([]);
		for(let j=0; j<y; j++) {
			dataCase[i].push(0);
		}
	}

	function moveFillData() {

		if(typeof dataCase[posX] === 'undefined' || typeof dataCase[posX][posY] === 'undefined') return dataCase;
		
		switch(nowDirection) {
			case 'right':
				if(posY + 1 === y || dataCase[posX][posY + 1] !== 0) {
					if(endCheck && dataCase[posX + 1][posY] !== 0 && dataCase[posX][posY] !== 0) return dataCase;
					nowDirection = direction();
					endCheck = true;
					dataCase[posX][posY] = no;
					no += 1;
					posX += 1;
				} else {
					endCheck = false;
					dataCase[posX][posY] = no;
					no += 1;
					posY += 1;
				}
				return moveFillData();
			case 'bottom':
				if(posX + 1 === x || dataCase[posX + 1][posY] !== 0) {
					if(endCheck && dataCase[posX][posY - 1] !== 0 && dataCase[posX][posY] !== 0) return dataCase;
					nowDirection = direction();
					endCheck = true;
					dataCase[posX][posY] = no;
					no += 1;
					posY -= 1;
				} else {
					endCheck = false;
					dataCase[posX][posY] = no;
					no += 1;
					posX += 1;
				}
				return moveFillData();
			case 'left':
				if(posY - 1  === -1 || dataCase[posX][posY - 1] !== 0) {
					if(endCheck && dataCase[posX - 1][posY] !== 0 && dataCase[posX][posY] !== 0) return dataCase;
					nowDirection = direction();
					endCheck = true;
					dataCase[posX][posY] = no;
					no += 1;
					posX -= 1;
				} else {
					endCheck = false;
					dataCase[posX][posY] = no;
					no += 1;
					posY -= 1;
				}
				return moveFillData();
			case 'top':
				if(posX - 1  === -1 || dataCase[posX - 1][posY] !== 0) {
					if(endCheck && dataCase[posX][posY + 1] !== 0 && dataCase[posX][posY] !== 0) return dataCase;
					nowDirection = direction();
					endCheck = true;
					dataCase[posX][posY] = no;
					no += 1;
					posY += 1;
				} else {
					endCheck = false;
					dataCase[posX][posY] = no;
					no += 1;
					posX -= 1;
				}
				return moveFillData();
		}
	};
	
	return moveFillData();
}

main(3, 2);
// 1 2
// 6 3
// 5 4

무언가 굉장히 보기 안좋은 코드가 된 것 같습니다... 분명 더 좋은 방법이 있을텐데,
역시 코딩 테스트 문제는 쉽지가 않네요.

결국 이 문제를 푸는데, 집에 와서도 한두 시간 고민을...
하...

끝