2447 별 찍기 - 10

Solution

아직 문제만 보고 패턴을 파악하는 능력이 많이 부족하다. 패턴을 분석하는 능력을 많이 길러야겠다.

먼저 N 이 9일 때를 가정해보자.

*********
* ** ** *
*********
***   ***
* *   * *
***   ***
*********
* ** ** *
*********

패턴을 보면 이중 반복문을 사용해야 한 다는 것 쯤은 금방 알 수 있을 것이다. 각 반복문의 변수를 i, j 라고 생각하고 가장 큰 공백을 제외하고 살펴볼 때, 공백은 가로 방향기준 (1, 1), (1, 4), (1,7) ... , 세로방향 기준 (1, 1), (4, 1), (7, 1)... 패턴이다.

그렇다 위 패턴에서 i와 j 를 3으로 나누었을 때 나머지가 1인 좌표가 공백이 된다. 공식으로 풀어내자면,

if (i % 3 === 1 && j % 3 === 1) {
  // 공백 처리
}

여기까지 풀어내면 아래와 같은 모습을 확인할 수 있다.

*********
* ** ** *
*********
*********
* ** ** *
*********
*********
* ** ** *
*********

다음으로 가운데, 큰 정사각형 형태의 공백을 처리해줘야한다.

해당 공식은 각 좌표 i 와 j 를 3으로 나누어 위에서 한자리 공백을 처리할 때와 동일하게 작성할 수 있다.

((i/3) % 3 === 1 && (j/3) % 3 === 1) {
	// 공백 처리
}

위 공식을 활용해 아래와 같이 풀이할 수 있다.

최종 풀이

const input = Number(require('fs').readFileSync('dev/stdin').toString().trim());
const lines = [];
function fillStar(num) {
  for (i = 0; i < num; i++) {
    for (j = 0; j < num; j++) {
      star(i, j, num);
    }
    lines.push('\n');
  }
}

function star(i, j, num) {
  if (i % 3 === 1 && j % 3 === 1) {
    lines.push(' ');
  } else {
    if (num === 1) {
      lines.push('*');
    } else {
      star(Math.floor(i / 3), Math.floor(j / 3), Math.floor(num / 3));
    }
  }
}

fillStar(input);
console.log(lines.join(''));

참고 문서