print("와챠의 개발 기록장")

[프로그래머스 / kotlin] 안전지대 본문

코딩 일기장/CodingTest

[프로그래머스 / kotlin] 안전지대

minWachya 2025. 4. 3. 15:58
반응형

문제 설명

다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.


지뢰는 2차원 배열 board에 1로 표시되어 있고 board에는 지뢰가 매설 된 지역 1과, 지뢰가 없는 지역 0만 존재합니다.
지뢰가 매설된 지역의 지도 board가 매개변수로 주어질 때, 안전한 지역의 칸 수를 return하도록 solution 함수를 완성해주세요.

 

예시

board result
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 0, 0]] 16
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 1, 1, 0], [0, 0, 0, 0, 0]] 13
[[1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 1, 1]] 0

 

 

처음 풀이

접근:

1. for문 돌아서 board[i][j] == 1인 것들의 가로, 세로, 대각선을 -1로 바꾸기

2. 이때 범위 체크하기

3. board[i][j]==0인 것만 세어서 반환

 

그렇게 탄생한 노가다 코드...

class Solution {
    fun check(i: Int, j: Int, max: Int, temp: Array<IntArray>): Boolean {
        return if(-1 < i && i < max && -1 < j && j < max && temp[i][j] == 0) true
        else false
    }
    
    fun solution(board: Array<IntArray>): Int {
        var temp = board
        val max = board.size
        
        for(i in 0 until board.size) {
            for(j in 0 until board[0].size) {
                if(board[i][j] == 1) {
                    if(check(i-1, j-1, max, temp)) temp[i-1][j-1] = -1
                    if(check(i-1, j, max, temp)) temp[i-1][j] = -1
                    if(check(i-1, j+1, max, temp)) temp[i-1][j+1] = -1
                    
                    if(check(i, j-1, max, temp)) temp[i][j-1] = -1
                    if(check(i, j+1, max, temp)) temp[i][j+1] = -1
                    
                    if(check(i+1, j-1, max, temp)) temp[i+1][j-1] = -1
                    if(check(i+1, j, max, temp)) temp[i+1][j] = -1
                    if(check(i+1, j+1, max, temp)) temp[i+1][j+1] = -1
                    
                }
            }
        }
        
        var answer = 0
        
        for(i in 0 until board.size) {
            for(j in 0 until board[0].size) {
                if(temp[i][j] == 0) answer++
            }
        }
        
        return answer
    }
}

 

 

답은 맞긴 했는데 다른 사람 풀이 보고 kotlin을 잘 활용한 풀이가 아닌 거 같아서 재도전

 

다른 풀이

접근법은 위와 같음.

근데 kotlin 언어 특성을 최대한 활용하면 아래와 같이 나옴...

class Solution {
    fun solution(board: Array<IntArray>): Int =
        board.indices.forEach{ row ->
            board[row].indices.filter{ board[row][it] == 1 }.forEach { col ->
                ((row-1).coerceAtLeast(0)..(row+1).coerceAtMost(board.lastIndex)).forEach { row2 ->
                ((col-1).coerceAtLeast(0)..(col+1).coerceAtMost(board.lastIndex)).forEach { col2 ->
                    if(board[row2][col2] == 0) board[row2][col2] = 2
                }
                }
            }
        }.run {
            board.map{
                it.count{ it == 0 }
            }.sum()
        }
}

 

나는 board를 모두 돌면서 1인지 아닌지 체크했지만, 위 코드에서는 filter를 통해 board값이 1인 것만 for문을 돌아서 좀 더 효율적인듯.

그리고 board의 범위를 체크할 때 나는 if문을 겁나 써가면서 가독성 구리게 코딩했는데,

위 코드는 coerceAtLeast, coerceAtMost 함수를 활용해서 최소 0, 최대 board의 마지막 인덱스이게 쉽게 조절할 수 있었다...!!!!!!!!!!

board가 0인 것만 세는 것도 map, count, sum를 활용해 더 간단하게 만듦... 왜 이 생각을 못 했을까

 

coerceAtLeast, coerceAtMost 함수만 모르고 나머진 다 아는 거였는데도 생각을 못했다.

그래도 이런 멋진 코드를 발견하니 기분이 넘 조타

천재들에게 ㄱㅅ를...

반응형
Comments