Post

미세먼지 안녕!

백준 사이트의 17144번 문제

코딩 계획

  1. 입력값을 받아 변수에 저장
  2. 공기 청정기 위치 탐색
  3. 미세먼지 확산 구현
  4. 공기 청정기 작동 구현
  5. 잔여 미세먼지 양 계산 및 출력

구현

1. 입력값을 받아 변수에 저장

미세먼지 양을 좌표에 기록하는 Room 클래스

1
2
3
4
5
6
7
8
9
10
11
12
class Room:
    def __init__(self, grid, r, c):
        self.n_rows = r
        self.n_cols = c
        self.dust = grid

r, c, t = map(int, input().split())
grid = []
for _ in range(r):
    grid.append(list(map(int, input().split())))
    
room = Room(grid, r, c)

2. 공기 청정기 위치 탐색

공기 청정기 클래스를 따로 만들까 고민하다가 Room 클래스 안에서 해결하기로 함

1
2
3
4
5
6
7
8
class Room:
    def __init__(self, grid, r, c):
        self.n_rows = r
        self.n_cols = c
        self.air_cleaner = [(i, 0) for i in range(r) if grid[i][0] == -1]
        for i, j in self.air_cleaner:
            grid[i][j] = 0
        self.dust = grid

3. 미세먼지 확산 구현

Room.grid[x][y] 인덱스 사용 가능한지 확인하기 위해 Room.is_inside() 메소드 구현
미세먼지 확산 로직이 중복되지 않도록 new_dust 변수를 새로 생성하여 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Room:
    ...
        
    def is_inside(self, x, y):
        return -1 < x < self.n_rows and -1 < y < self.n_cols
    
    def diffuse(self):
        new_dust = [[0 for _ in range(self.n_cols)] for _ in range(self.n_rows)]
        for i in range(self.n_rows):
            for j in range(self.n_cols):
                if (dust := self.dust[i][j]) > 0:
                    dust_diffused = dust // 5
                    for dx, dy in [[0, 1], [0, -1], [-1, 0], [1, 0]]:
                        x = i + dx
                        y = j + dy
                        if self.is_inside(x, y) and (x, y) not in self.air_cleaner:
                            new_dust[x][y] += dust_diffused
                            dust -= dust_diffused
                    new_dust[i][j] += dust
        self.dust = new_dust

표현식의 일부를 변수값으로 할당하기 위해 walrus operator := 활용

4. 공기 청정기 작동 구현

시계방향과 반시계방향 상수 변수로 선언
Room.is_inside() 메소드를 활용하여 방향 전환 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
CLOCKWISE = [[0, 1], [1, 0], [0, -1], [-1, 0]]
ANTI_CLOCKWISE = [[0, 1], [-1, 0], [0, -1], [1, 0]]


class Room:
    ...
        
    def clean(self):
        for start, orientations in zip(self.air_cleaner, [ANTI_CLOCKWISE, CLOCKWISE]):
            i, j = start
            orientation_idx = 0
            dx, dy = orientations[orientation_idx]
            carry_dust = 0
            while True:
                if not self.is_inside(i + dx, j + dy):
                    orientation_idx += 1
                    dx, dy = orientations[orientation_idx]
                x = i + dx
                y = j + dy
                
                if (x, y) == start:
                    break
                    
                new_carry_dust = self.dust[x][y]
                self.dust[x][y] = carry_dust
                carry_dust = new_carry_dust
                
                i = x
                j = y

5. 잔여 미세먼지 양 계산 및 출력

1
2
3
4
5
6
7
8
9
10
class Room:
    ...
            
    def count_dust(self):
        total = 0
        
        for line in self.dust:
            total += sum(line)
            
        return total

최종 코드

https://github.com/yehoon17/beakjoon/blob/main/python/17144.py

This post is licensed under CC BY 4.0 by the author.