치춘짱베리굿나이스

[백준] 2447 본문

별 찍기 - 10

문제

재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다.

크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이 하나씩 있는 패턴이다.

***
* *
***

N이 3보다 클 경우, 크기 N의 패턴은 공백으로 채워진 가운데의 (N/3)×(N/3) 정사각형을 크기 N/3의 패턴으로 둘러싼 형태이다. 예를 들어 크기 27의 패턴은 예제 출력 1과 같다.

입력

첫째 줄에 N이 주어진다. N은 3의 거듭제곱이다. 즉 어떤 정수 k에 대해 N=3k이며, 이때 1 ≤ k < 8이다.

출력

첫째 줄부터 N번째 줄까지 별을 출력한다.

풀이

const recurStar = (size) => {
  if (size === 3) return ["***", "* *", "***"];
  const prev = recurStar(size / 3);
  let ret = [];
  for (let line of prev) {
    ret.push(line.repeat(3));
  }
  for (let line of prev) {
    ret.push(line + " ".repeat(size / 3) + line);
  }
  for (let line of prev) {
    ret.push(line.repeat(3));
  }
  return ret;
};

const star = () => {
  let input = parseInt(
    require("fs").readFileSync("/dev/stdin").toString().trim()
  );
  const arr = recurStar(input);
  console.log(arr.join("\n"));
};

star();

반성회

const recurStar = (size) => {
  if (size === 3) return ["***", "* *", "***"]; 
    //size가 3일 때, (재귀 탈출 조건) 3 * 3짜리 배열 바로 반환

  const prev = recurStar(size / 3);
    //재귀 다음 단계에서의 반환 배열을 받아옴
    //만약 현재 size가 27일 경우, size가 9일 때의 배열 받아오기

  let ret = [];
    //다음에 반환할 배열 선언

  for (let line of prev) {
    ret.push(line.repeat(3));
  }
  for (let line of prev) {
    ret.push(line + " ".repeat(size / 3) + line);
  }
  for (let line of prev) {
    ret.push(line.repeat(3));
  }
    //다음 단계에서의 배열을 3 * 3번 반복함
    //반복 방법은 배열의 각 원소가 각 줄 (row)을 표현한다고 가정
    //한 줄에 반복이 3번씩 이루어지므로, repeat(3) 을 통해 3번 반복
    //단, 가운데 3개의 줄 (4, 5, 6번째 row) 는 중앙이 뻥 뚫려 있어야 하므로
    //3회 반복 대신 중앙에 공백을 size / 3만큼 넣어서 문자열 덧셈

    //예를 들어, 다음 단계가 ["***", "* *", "***"] 이고 현재 size가 9일 경우
        //첫 번째 for문:
        // ret.push("*********"); ("***" 을 3번 반복)
        // ret.push("* ** ** *"); ("* *" 을 3번 반복)
        // ret.push("*********"); ("***" 을 3번 반복)
        //두 번째 for문:
        // ret.push("***   ***"); ("***" + " "을 9 / 3회 반복 + "***")
        // ret.push("* *   * *"); ("* *" + " "을 9 / 3회 반복 + "* *")
        // ret.push("***   ***"); ("***" + " "을 9 / 3회 반복 + "***")
        //세 번째 for문:
        // ret.push("*********"); ("***" 을 3번 반복)
        // ret.push("* ** ** *"); ("* *" 을 3번 반복)
        // ret.push("*********"); ("***" 을 3번 반복)

  return ret; //만든 배열 반환, 이전 단계로 되돌아감
};

const star = () => {
  let input = parseInt(
    require("fs").readFileSync("/dev/stdin").toString().trim()
  );
  const arr = recurStar(input);
  console.log(arr.join("\n")); //문자열 덧셈으로 각 row를 만들었으므로, \n을 기준으로 합침
};

star();

어려웠다... 파이썬 기준으로 문자열 파싱 코드가 좀 달라서 다른 예제들은 컨셉 참고 정도만 했다

'Javascript + Typescript > 자바스크립트로 알고리즘풀기' 카테고리의 다른 글

[백준] 1002  (0) 2022.02.13
[백준] 3053  (0) 2022.02.13
[백준] 10822  (0) 2022.02.13
[백준] 17608  (0) 2022.02.13
[백준] 4948  (0) 2022.02.13
Comments