갬쿠
개미 개발
갬쿠
전체 방문자
오늘
어제
  • ALL (137)
    • React (20)
    • JS & CSS & HTML (29)
    • Algorithm (62)
    • 웹 보안 (11)
    • 달리는 까까: 쿠키런 팬게임 (10)
    • Python (0)
    • 기타 (5)
    • 비공개 플젝 (0)

블로그 메뉴

  • GitHub
  • 방명록
  • 관리자 메뉴

공지사항

인기 글

태그

  • 게임
  • 백준
  • useEffect
  • 쿠키런 팬게임
  • 객체
  • HTML
  • SQL Injection
  • REACT
  • 크롬 공룡 게임
  • Best of the Best
  • 쿠키런 모작
  • Python
  • CSS
  • 게임 개발
  • useState
  • Baekjoon
  • EventListener
  • Programmers
  • 리액트
  • BEAKJOON
  • 크롬 공룡게임
  • 모의 해킹
  • 쿠키런
  • useReducer
  • 달리는 까까
  • js
  • transform
  • JavaScript
  • Object
  • node.js

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
갬쿠

개미 개발

[2447] 별 찍기 - JavaScript
Algorithm

[2447] 별 찍기 - JavaScript

2022. 6. 19. 20:27
/* 문제 */
재귀적인 패턴으로 별을 찍어 보자. N이 3의 거듭제곱(3, 9, 27, ...)이라고 할 때, 크기 N의 패턴은 N×N 정사각형 모양이다.
크기 3의 패턴은 가운데에 공백이 있고, 가운데를 제외한 모든 칸에 별이 하나씩 있는 패턴이다.

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

처음에는 각 단계에서 이전 단계의 결과물이 새로운 패턴 한 칸이 된다는 점을 이용해 문제를 풀려고 했다. 크기가 3인 리스트를 선언하고 각 요소를 첫째 줄, 둘째 줄, 셋째 줄로 설정해 계산한 후 마지막에 출력하는 방식이었다. 첫째 줄과 셋째 줄은 이전 단계의 결과물을 3번 반복한 패턴이고, 둘째 줄은 이전 단계의 결과물 + (N/3)*(N/3) 크기의 공백 +  이전 단계의 결과물이다. 그러나 개행 문자를 포함한 패턴을 반복하여 저장하는 데 어려움이 있었기 때문에 제대로 된 결과물이 나오지 않았다. 

그래서 선택한 방법이 출력 문자 하나하나의 위치를 좌표처럼 설정해 "*"가 출력될 지 " "가 출력될 지 결정하도록 하는 방식이었다.

const fs = require("fs");
const input = fs.readFileSync("./dev/stdin").toString().trim();
const n = parseInt(input);
let res = "";

const star = (i, j, num) => {
  if (i % 3 === 1 && j % 3 === 1) res += " ";
  else {
    if (num === 1) res += "*";
    else star(parseInt(i / 3), parseInt(j / 3), parseInt(num / 3));
  }
};

for (let i = 0; i < n; i++) {
  for (let j = 0; j < n; j++) {
    star(i, j, n);
  }
  res += "\n";
}

console.log(res);

우선 for 루프를 N * N번 돌며 각 좌표마다 *인지 공백인지를 결정하는 함수 star()를 호출한다. star()에서는 전달받은 좌표에 따라 문자를 하나씩 res에 더해주기 때문에, 좌표에 맞게 차례대로 문자가 저장된다. i가 x좌표, j가 y좌표를 의미한다고 볼 수 있기 때문에 한 줄이 끝나면 개행 문자를 더해 줄바꿈을 해준다. 

 

star() 함수를 하나하나 살펴보자.

if (i % 3 === 1 && j % 3 === 1) res += " ";

기본적으로 i%3 === 1이고 j%3 === 1이면 공백이 출력된다. 3*3 크기의 정사각형에서 가운데 한 칸이 비어있는 패턴이 이 문제의 기본 단위인 것이다.

  else {
    if (num === 1) res += "*";
    else star(parseInt(i / 3), parseInt(j / 3), parseInt(num / 3));
  }

위에서 설명한 기본 공백이 아니라면 "*"를 출력해야 할 것이다. 그러나 3보다 큰 N을 처리하기 위해서는 추가로 공백을 처리해 줘야 한다. 이 부분을 재귀함수로 처리하는데, 패턴을 크게 보면 결국 가운데 한 칸이 비어있는 정사각형 패턴의 반복이다. 즉 N번째 단계에서는 N*N 크기의 정사각형에서 가운데 (N/3)*(N/3) 칸이 비어있는 패턴이 나타나야 한다. 따라서 현재 star()에서 처리하고 있는 값들을 3으로 나누어 스케일을 줄여주는 과정을 반복한다. N이 1이 되면 최소한으로 쪼개진 것이므로 "*"를 출력한다. 이 최소 단위의 공백은 위의 if문에서 처리된다.

예를 들어 N이 9일 때

이 그림에서 빨간 부분에 해당하는 좌표는

(3,3)(4,3)(5,3)
(3,4)(4,4)(5,4)
(3,5)(4,5)(5,5)

인데, 모두 star(1,1,3)이 호출되어 공백이 출력된다.

같은 원리로 N이 27일 때 (9,9)에 해당하는 좌표에서는 star(3,3,9)가 호출되며, 다시 star(1,1,3)이 호출되어 공백이 출력된다.

728x90

'Algorithm' 카테고리의 다른 글

[2579] 계단 오르기 -Python  (0) 2022.11.03
[1912] 연속합 - Python  (0) 2022.10.30
[2941] 크로아티아 알파벳 - JavaScript  (0) 2022.06.15
[2775] 부녀회장이 될테야 - JavaScript  (0) 2022.06.15
[15552] 빠른 A+B - JavaScript (Node.js 시간 초과 해결)  (0) 2022.06.12
    'Algorithm' 카테고리의 다른 글
    • [2579] 계단 오르기 -Python
    • [1912] 연속합 - Python
    • [2941] 크로아티아 알파벳 - JavaScript
    • [2775] 부녀회장이 될테야 - JavaScript
    갬쿠
    갬쿠
    보안&소프트웨어 전공 프론트엔드 개발자

    티스토리툴바