본문 바로가기

코테

시공의 돌풍

728x90
반응형
SMALL

Well know의 청소기 문제였다.

한 번 봤던 문제라서 1시간 정도 걸렸다.

 

개선점을 찾으려고 chatGPT 에게 코드 리뷰를 부탁 했는데, 웬일로 칭찬????을 하나 싶었으나...

순살치킨 되버렸다... 그만 때려..ㅠㅠㅠ

 

  1. 함수 내에서 전역 변수(global)를 사용하지 않는 것이 좋습니다. 함수의 입력값으로 전달받아서 사용하거나, 함수의 반환값으로 결과를 돌려주는 방식으로 변경하는 것이 좋습니다.
  2. 함수명이 어떤 역할을 하는지 잘 나타나지 않는 경우가 있습니다. 예를 들면 extend_trash 함수는 쓰레기가 있는 위치를 확장하는 함수라는 것이지만, 이름에서는 그렇게 알기 어려운데요. 함수명이 그 역할을 잘 표현하도록 변경하는 것이 좋습니다.
  3. 코드의 가독성을 높이기 위해서는 각 함수와 전역 변수에 대한 설명이 필요합니다. 이렇게 하면 코드를 읽는 사람이 코드 구조를 빠르게 파악할 수 있게 됩니다.
  4. validation 함수를 단순화하여, ny, nx 값이 범위 내에 있는지를 간단히 확인하는 것이 좋습니다. 예를 들어 return 0 <= ny < n and 0 <= nx < m으로 변경할 수 있습니다.
  5. extend_trash 함수에서 tmp_graph를 불필요하게 생성하지 않고, graph의 값을 직접 업데이트하는 방식으로 변경하는 것이 좋습니다.
  6. extend_trash 함수에서 trashs_infos 리스트를 사용하지 않고, for 루프를 한 번 더 사용하여 코드를 단순화할 수 있습니다. 예를 들어 다음과 같이 변경할 수 있습니다.
  7. clear_trashs 함수에서 continue 문이 많이 사용되고 있습니다. if 문을 한 번 더 사용하여, 조건이 맞지 않을 때는 바로 q.append 문으로 넘어가도록 변경하는 것이 가독성을 높이는 데 도움이 됩니다.
  8. 마지막으로, cal_trash_count 함수에서 answer 변수를 전역 변수로 사용하지 않고, 반환값으로 결과를 돌려주는 것이 좋습니다.

 

 

import sys
from collections import deque
n, m, t = map(int, sys.stdin.readline().strip().split())
graph = [list(map(int, sys.stdin.readline().strip().split())) for _ in range(n)]
answer = 2
m1_y, m1_x = 0, 0
m2_y, m2_x = 0, 0
m_d = 0

dx, dy = [0, 0, -1, 1], [1, -1, 0, 0]
m1_dy, m1_dx = [-1, 0, 1, 0], [0, 1, 0, -1]
m2_dy, m2_dx = [1, 0, -1, 0], [0, 1, 0, -1]

def clear_trashs(y, x):
   
    global m1_dy, m1_dx, m2_dy, m2_dx , m_d, graph, m1_y, m2_y, m
    machine = 1

    if y == m1_y and x == m1_x: dx, dy = m1_dx, m1_dy; machine = 1
    else: dx, dy = m2_dx, m2_dy; machine = 2
    d = m_d

    q = deque([])
    q.append((y, x))
    while q:
        y, x = q.popleft()
        ny = y + dy[d]
        nx = x + dx[d]
        if validation(ny, nx):
            if graph[y][x] == -1: #시작점이 기계이면
                q.append((ny, nx)) #다음 좌표로 이동
                continue
            if machine == 1 and ny == m2_y and nx == m - 1:
                d = (d + 1) % 4
                q.append((y, x))
                continue
            if machine == 2 and ny == m1_y and nx == m - 1:
                d = (d + 1) % 4
                q.append((y, x))
                continue


            if graph[ny][nx] == -1: #다음칸이 기계이면
                graph[y][x] = 0 #현재칸의 먼지량은 0
                continue
            #시작점이 기계가 아니면
            graph[y][x] = graph[ny][nx] #현재칸의 먼지량은 다음칸의 먼지량이 됌
            q.append((ny,nx))
            continue
        else: #범위를 넘어가면 방향을 바꿈
            d = (d + 1) % 4
            q.append((y, x))
    
def fine_machine_location():
    global graph, n, m, m1_y, m1_x, m2_y, m2_x
    count = 1
    for y in range(n):
        for x in range(m):
            if count == 1 and graph[y][x] == -1:
                count += 1
                m1_y, m1_x = y, x
            elif count ==2 and graph[y][x] == -1:
                m2_y, m2_x = y, x
    return

def validation(ny, nx):
    global n, m 
    if ny >= n or ny < 0 or nx >= m or nx < 0:
        return False
    return True

def check_trash_mount_locations(y, x):
    global graph, dy, dx
    trashs_infos = []
    trash_mount = graph[y][x] // 5
    for d in range(4):
        ny = y + dy[d]
        nx = x + dx[d]
        if validation(ny, nx):
            if graph[ny][nx] == -1:
                continue
            trashs_infos.append((ny, nx))
    return trash_mount, trashs_infos

def extend_trash():
    global graph, n, m
    tmp_graph = [[0 for _ in range(m)] for _ in range(n)]
    for y in range(n):
        for x in range(m):
            if graph[y][x] == -1: # 기계면 continue
                continue
            trash_mount, locations = check_trash_mount_locations(y, x)
            for t_add_y, t_add_x in locations:
                tmp_graph[t_add_y][t_add_x] += trash_mount
            tmp_graph[y][x] -= trash_mount * len(locations)
    for y in range(n):
        for x in range(m):
            graph[y][x] += tmp_graph[y][x] 
    return

def cal_trash_count():
    global graph, n, m, answer
    for y in range(n):
        for x in range(m):
            answer += graph[y][x] 
    return

fine_machine_location()
for _ in range(t):
    extend_trash()
    clear_trashs(m1_y, m1_x)
    clear_trashs(m2_y, m2_x)

cal_trash_count()
print(answer)

 

 

그나마 개선해 본 코드..

import sys
from collections import deque
n, m, t = map(int, sys.stdin.readline().strip().split())
graph = [list(map(int, sys.stdin.readline().strip().split())) for _ in range(n)]
answer = 2
m1_y, m1_x = 0, 0
m2_y, m2_x = 0, 0
m_d = 0

dx, dy = [0, 0, -1, 1], [1, -1, 0, 0]
m1_dy, m1_dx = [-1, 0, 1, 0], [0, 1, 0, -1]
m2_dy, m2_dx = [1, 0, -1, 0], [0, 1, 0, -1]

def clean_trash(y, x):
   
    global m1_dy, m1_dx, m2_dy, m2_dx , m_d, graph, m1_y, m2_y, m
    machine = 1

    if y == m1_y and x == m1_x: dx, dy = m1_dx, m1_dy; machine = 1
    else: dx, dy = m2_dx, m2_dy; machine = 2
    d = m_d

    q = deque([])
    q.append((y, x))
    while q:
        y, x = q.popleft()
        ny = y + dy[d]
        nx = x + dx[d]
        if validation(ny, nx):
            if graph[y][x] == -1: #시작점이 기계이면
                q.append((ny, nx)) #다음 좌표로 이동
                continue
            if (machine == 1 and ny == m2_y and nx == m - 1) or (machine == 2 and ny == m1_y and nx == m - 1):
                d = (d + 1) % 4
                q.append((y, x))
                continue
            if graph[ny][nx] == -1: #다음칸이 기계이면
                graph[y][x] = 0 #현재칸의 먼지량은 0
                continue
            #시작점이 기계가 아니면
            graph[y][x] = graph[ny][nx] #현재칸의 먼지량은 다음칸의 먼지량이 됌
            q.append((ny,nx))
        else: #범위를 넘어가면 방향을 바꿈
            d = (d + 1) % 4
            q.append((y, x))
    
def fine_machine_location():
    global graph, n, m, m1_y, m1_x, m2_y, m2_x
    count = 1
    for y in range(n):
        for x in range(m):
            if count == 1 and graph[y][x] == -1:
                count += 1
                m1_y, m1_x = y, x
            elif count ==2 and graph[y][x] == -1:
                m2_y, m2_x = y, x
    return

def validation(ny, nx):
    global n, m 
    return 0 <= ny < n and 0 <= nx < m

def check_trash_mount_locations(y, x):
    global graph, dy, dx
    trashs_infos = []
    trash_mount = graph[y][x] // 5
    for d in range(4):
        ny = y + dy[d]
        nx = x + dx[d]
        if validation(ny, nx):
            if graph[ny][nx] == -1:
                continue
            trashs_infos.append((ny, nx))
    return trash_mount, trashs_infos

def spread_trash():
    global graph, n, m
    tmp_graph = [[0 for _ in range(m)] for _ in range(n)]
    for y in range(n):
        for x in range(m):
            if graph[y][x] == -1: # 기계면 continue
                continue
            trash_mount, locations = check_trash_mount_locations(y, x)
            for t_add_y, t_add_x in locations:
                tmp_graph[t_add_y][t_add_x] += trash_mount
            tmp_graph[y][x] -= trash_mount * len(locations)
    for y in range(n):
        for x in range(m):
            graph[y][x] += tmp_graph[y][x] 
    return

def cal_trash_count():
    global graph, n, m, answer
    for y in range(n):
        for x in range(m):
            answer += graph[y][x] 
    return

fine_machine_location()
for _ in range(t):
    spread_trash()
    clean_trash(m1_y, m1_x)
    clean_trash(m2_y, m2_x)

cal_trash_count()
print(answer)
728x90
반응형
LIST

'코테' 카테고리의 다른 글

생명과학부 랩 인턴  (0) 2023.03.28
2개의 사탕  (0) 2023.03.28
팩맨  (0) 2023.03.27
꼬리잡기놀이  (0) 2023.03.25
산타의 선물 공장2  (0) 2023.03.24