print("와챠의 개발 기록장")
[프로그래머스 / kotlin] 안전지대 본문
문제 설명
다음 그림과 같이 지뢰가 있는 지역과 지뢰에 인접한 위, 아래, 좌, 우 대각선 칸을 모두 위험지역으로 분류합니다.
지뢰는 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 함수만 모르고 나머진 다 아는 거였는데도 생각을 못했다.
그래도 이런 멋진 코드를 발견하니 기분이 넘 조타
천재들에게 ㄱㅅ를...
'코딩 일기장 > CodingTest' 카테고리의 다른 글
[프로그래머스 / kotlin] 택배 상자 꺼내기 (0) | 2025.04.16 |
---|---|
[프로그래머스 / kotlin] 특이한 정렬 / sortedWith (2) | 2025.04.09 |
[BOJ/Kotlin] 11758번 CCW (0) | 2022.06.03 |
[BOJ/Kotlin]히스토그램에서 가장 큰 직사각형 (0) | 2022.03.08 |
[백준]탈옥/9376 풀이 JAVA (0) | 2021.08.09 |