CODING TEST/Code Tree

[코드트리 챌린지] 5주차 - 이어서 쉬어가는 한 주( 빙빙 돌며 숫자 사각형 채우기 / 빙빙 돌며 숫자 사각형 채우기2 )

더라 2023. 10. 9. 23:00
728x90

실력진단

5주차: 487 → 498

저번주에 이어서 이번주도 쉬어가는 주다. 실력진단의 경우 2주간 공부량이 줄어서 큰 변화가 없었다.

이번주도 동일하게 dx, dy 시뮬레이션을 공부했다. 이번주의 바뀐 점을 코드 작성시 x, y 와 행, 열 배치가 헷갈려서 y, x로 표기하기로 했다. dx, dy를 공부하면서 가장 중요한 건 행, 열을 바꾸어 작성하지 않도록 주의하는 것 같다.(대부분의 오답이 행, 열을 잘못배치한 것이다. 😂 왜그리 헷갈리는지 정말..)

 

개인적인 스케줄이 하나 정리되어서 6주차 부터는 다시 공부량을 조금 늘릴 수 있을 것 같다. 그래도 한 주도 빠지지 않고 해나가는 나 칭찬한다.

 

부족한점

5주차도 dx, dy 시뮬레이션이다. 시계방향, 반시계 방향으로 배열을 채워나가는 문제를 풀었다. 아마 6주차에 dx, dy문제를 다 풀 수 있을 것으로 예상한다.


학습내용

빙빙 돌며 사각형 채우기

 

[코드트리]빙빙 돌며 사각형 채우기

 

 

n, m = map(int, input().split())
arr=[
    [0]*m
    for _ in range(n)
]

def in_range(dy, dx):
    return 0 <= dy and dy<n and 0<=dx and dx < m

dys, dxs = [0, 1, 0, -1], [1, 0, -1, 0]
y, x =0, 0

dir_n = 0
for i in range(n*m):
    arr[y][x] = chr((i%26)+ord('A'))

    dy, dx = y + dys[dir_n], x + dxs[dir_n]
    if in_range(dy, dx) and arr[dy][dx]==0:
        y = dy
        x = dx

    else:
        dir_n = (dir_n+1)%4
        y=y + dys[dir_n]
        x=x + dxs[dir_n]

for i in range(n):
    for j in range(m):
        print(arr[i][j], end=' ')
    print()

 

시계 방향으로 돌아가며 A-Z를 채워나간다. Z이후에는 A부터 다시 채우며 배열 끝 까지 반복한다.

이를 위해 반복문을 사용하고 배열 인덱스를 증가시켜 해당 위치가 배열을 넘지 않고, 가보지 않은 칸인지 확인한다.

가보지 않은 칸을 체크하기 위해 미리 0으로 채워진 n * m배열은 만든다. 반약 배열의 값이 0이라면 가보지 않은 위치, 다른 값이라면 이미 간 위치라 다른 값이 채워져 있다.

 

알파벳을 채우기 위해 아스키코드를 이용한다. 알파벳은 대문자만 다루기 때문에 총 26개다. 반복문 횟수인 i를 26으로 나눈 나머지에 'A'인 65를 더한다. ord()를 사용하면 문자열이 숫자 아스키코드로 변환된다. 결론적으로 (i%26)+ord('A')를 chr() 사용한다. 이는 ord()의 반대로 숫자를 문자열 아스키코드로 값으로 변환해준다.

 

만약 현재 배열인덱스가 배열칸을 넘고, 가본 칸이라면 방향을 시계 방향으로 90도 회전한다. 그리고 위의 내용처럼 해당 배열에 알파벳을 넣는다.

 

 


 

 

빙빙 돌며 사각형 채우기2

코드트리]빙빙 돌며 사각형 채우기2

 

n, m = map(int, input().split())

arr=[
    [0]*m
    for _ in range(n)
]

dys, dxs  = [0, 1, 0, -1], [1, 0, -1 ,0]
def in_range(r, c):
    return 0<=r and r<n and 0<=c and c<m

r, c = 0, 0
dir_n = 1
for i in range(1, n*m+1):
    arr[r][c]=i

    dy, dx = r+dys[dir_n], c+dxs[dir_n]
    if in_range(dy, dx) and arr[dy][dx]==0:
        r = dy
        c = dx
            
    else:
        dir_n = (dir_n-1) % 4
        r = r+dys[dir_n]
        c = c+dxs[dir_n]

for i in range(n):
    for j in range(m):
        print(arr[i][j], end=' ')
    print()

 

빙빙 돌며 사각형 채우기와 빙빙 돌며 사각형 채우기2는 방향과 채워넣는 값만 다르다.

빙빙 돌며 사각형 채우기2의 경우 반 시계방향으로 1부터 배열 크기 값인 n*m까지 채워 넣는다.

이때 반복문 범위는 (1, n*m+1)이다. 0부터 시작이 아닌 1부터 시작이기에 끝 값인 n*m+1을 해야 n*m값까지 배열에 담긴다.

 

이후 빙빙 돌며 사각형 채우기처럼 현재 배열 인덱스가 배열을 벗어나지 않는 값이고, 가보지 않은 위치라면 숫자를 채워넣는다.

 

💭 처음에 while문을 사용했었는데 다른 분들의 코드를 참고하고, 다시 생각해보니 while문을 사용할 필요가 없을 것 같아 제거했다. while을 사용했던 코드를 참고용으로 기록한다. 

더보기
n, m = map(int, input().split())

arr=[
    [0]*m
    for _ in range(n)
]

dys, dxs  = [0, 1, 0, -1], [1, 0, -1 ,0]
def in_range(r, c):
    return 0<=r and r<n and 0<=c and c<m

arr[0][0] = 1
r, c = 0, 0
dir_n = 1
for i in range(2, n*m+1):
    while(True):
        dy, dx = r+dys[dir_n], c+dxs[dir_n]
        if in_range(dy, dx) and arr[dy][dx]==0:
            r = dy
            c = dx
            arr[r][c]=i
            break
        else:
            dir_n = (dir_n-1) % 4

for i in range(n):
    for j in range(m):
        print(arr[i][j], end=' ')
    print()

 

 


이번에 행과 열을 x, y로 표기할 때 코딩에서 y, x로 배치를 바꾸어 표현했더니 코딩할 때 덜 헷갈렸다.

그래도 처음과 달리 기본적인 문제는 어렵지 않게 해결해 나갈 수 있는 것 같다. 시뮬레이션 완주를 향해 화이팅!

728x90