[python] 2447_별 찍기-10

yeco_ob·2023년 2월 1일
0

문제

재귀적인 패턴으로 별을 찍어 보자. 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번째 줄까지 별을 출력한다.

해결 방법

💡 sys.setrecursionlimit(10 ** 6)

재귀를 사용해 문제를 풀 때 런타임 에러를 방지하기 위해 위와 같은 코드를 작성해야 한다. 그러면 재귀의 최대 깊이가 10 ** 6으로 바뀌게 된다. 필요에 따라 숫자는 바꿀 수 있다.

💡 재귀 함수 만들기

자... 이 문제는 대놓고 재귀함수를 쓰라고 적혀 있었으니 어떻게 만들지 아아주 고민했다.

3*3 패턴이 반복 되는 모양이니 이 모양을 함수로 만들고 반복해야 하나? > 재귀 아님.

비어있는 공간의 패턴을 알아내서 함수로 써볼까? > 복잡함. ( ゚д゚)つ Bye

이런 문제를 끝까지 물고 넘어져야 찐이지만.. ㅎ
(꼭 더 추가 해봐야지)

여기서 문제에 n//3 만큼의 공백이 있다는 것을 포인트로 잡았다. 그리고 각 줄을 나눠 첫 줄, 마지막 줄은 패턴으로 채우고 중간 줄은 공백을 주는 것을 재귀적으로 반복하면 된다.

그러니까 반복문은 총 3개로 1번째 줄, 2번째 줄, 3번째 줄을 의미한다.

✨아래 코드를 N이 3의 경우로 보자면

  1. def draw_star(3) > stars = draw_star(1) > if n == 1: return ['*'] > stars = '*'
  2. 1번 반복문: *** > 2번 반복문: * * > 3번 반복문: ***
  3. L 리턴
  4. 출력

이런 흐름이다. 그럼 n(27) 이라면 Stars=draw_stars(n//3) 에서 Stars=draw_stars(9)로 넘어가고 재귀 호출로 Stars=draw_stars(3)로 넘어가고 다시 Stars=draw_stars(1)이 되어서야 return ['*']을 만나 함수 스택이 하나하나 풀린다.

제출

import sys
sys.setrecursionlimit(10**6) #재귀 최대깊이 설정

def draw_star(n):
  if n == 1: #재귀 함수 없이 해결할 수 있는 최소의 문제
      return ['*']

  stars = draw_star(n//3) #n이 1이 아니라면 실행
  L = [] #리스트 생성
  
  for star in stars:
   L.append(star * 3)
  for star in stars:
   L.append(star + ' ' * (n//3) + star)
  for star in stars:
    L.append(star * 3)

  return L

N = int(input())
print('\n'.join(draw_star(N))) #join() 사용해서 문자열로 합체

0개의 댓글