Level3 - 기둥과 보 설치
문제 설명 |
빙하가 깨지면서 스노우타운에 떠내려 온 **"죠르디"**는 인생 2막을 위해 주택 건축사업에 뛰어들기로 결심하였습니다. "죠르디"는 기둥과 보를 이용하여 벽면 구조물을 자동으로 세우는 로봇을 개발할 계획인데, 그에 앞서 로봇의 동작을 시뮬레이션 할 수 있는 프로그램을 만들고 있습니다.프로그램은 2차원 가상 벽면에 기둥과 보를 이용한 구조물을 설치할 수 있는데, 기둥과 보는 길이가 1인 선분으로 표현되며 다음과 같은 규칙을 가지고 있습니다.
2차원 벽면은 n x n 크기 정사각 격자 형태이며, 각 격자는 1 x 1 크기입니다. 맨 처음 벽면은 비어있는 상태입니다. 기둥과 보는 격자선의 교차점에 걸치지 않고, 격자 칸의 각 변에 정확히 일치하도록 설치할 수 있습니다. 다음은 기둥과 보를 설치해 구조물을 만든 예시입니다. 예를 들어, 위 그림은 다음 순서에 따라 구조물을 만들었습니다.
벽면의 크기 n, 기둥과 보를 설치하거나 삭제하는 작업이 순서대로 담긴 2차원 배열 build_frame이 매개변수로 주어질 때, 모든 명령어를 수행한 후 구조물의 상태를 return 하도록 solution 함수를 완성해주세요. |
제한 조건 |
|
입출력 예 |
||
n | build_frame | return |
5 | [[1,0,0,1],[1,1,1,1],[2,1,0,1],[2,2,1,1],[5,0,0,1],[5,1,0,1],[4,2,1,1],[3,2,1,1]] | [[1,0,0],[1,1,1],[2,1,0],[2,2,1],[3,2,1],[4,2,1],[5,0,0],[5,1,0]] |
5 | [[0,0,0,1],[2,0,0,1],[4,0,0,1],[0,1,1,1],[1,1,1,1],[2,1,1,1],[3,1,1,1],[2,0,0,0],[1,1,1,0],[2,2,0,1]] | [[0,0,0],[0,1,1],[1,1,1],[2,1,1],[3,1,1],[4,0,0]] |
아홉 번째 작업의 경우, (1, 1)에서 오른쪽에 있는 보를 삭제하면 (2, 1)에서 오른쪽에 있는 보는 조건을 만족하지 않으므로 무시됩니다. 열 번째 작업의 경우, (2, 2)에서 위쪽 방향으로 기둥을 세울 경우 조건을 만족하지 않으므로 무시됩니다. |
나의 풀이
- frame[x][y][a] = null / 1 을 담는 3중배열 생성
- 조건에 맞춰 기둥과 보를 설치 가능한지를 판별하는 함수 생성
- 삭제할 때는 3중 배열 값을 null로 변경하고 앞서 설치한 재료들이 문제가 없는지 탐색
class Solution {
private lateinit var frame: Array<Array<Array<Int?>>>
private var range: Int = 1
fun solution(n: Int, build_frame: Array<IntArray>): Array<IntArray> {
val answer = arrayListOf<IntArray>()
range = n
frame = Array(n+1) { Array(n+1) { Array(n+1) { null } } }
build_frame.forEach {
val x = it[0]
val y = it[1]
val a = it[2]
when (it[3]) {
0 -> canDelete(x, y, a)
1 -> when (a) {
0 -> canInstallPillar(x, y)
1 -> canInstallPaper(x, y)
}
}
}
frame.forEachIndexed { x, first ->
first.forEachIndexed { y, second ->
second.forEachIndexed { a, i ->
i?.let {
answer.add(intArrayOf(x,y,a))
}
}
}
}
return answer.toTypedArray()
}
private fun canInstallPillar(x: Int, y: Int, isCheck: Boolean = false): Boolean {
var isInstall = false
if (y == 0) {
isInstall = true
} else if (y in 1 until range) {
if (frame[x][y-1][0] != null || frame[x][y][1] != null) {
isInstall = true
} else if (x > 0) {
if (frame[x-1][y][1] != null) {
isInstall = true
}
}
}
if (isInstall && !isCheck) frame[x][y][0] = 1
return isInstall
}
private fun canInstallPaper(x: Int, y: Int, isCheck: Boolean = false): Boolean {
var isInstall = false
if (y != 0 && x in 0 until range) {
if (frame[x][y-1][0] != null || frame[x+1][y-1][0] != null) {
isInstall = true
} else if (x>0) {
if ((frame[x-1][y][1] != null && frame[x+1][y][1] != null)) {
isInstall = true
}
}
}
if (isInstall && !isCheck) frame[x][y][1] = 1
return isInstall
}
private fun canDelete(x: Int, y: Int, value: Int) {
frame[x][y][value] = null
run loop@ {
frame.forEachIndexed { i, first ->
first.forEachIndexed { j, second ->
second.forEachIndexed { a, b ->
b?.let {
val isBoolean = when (a) {
0 -> canInstallPillar(i, j, true)
1 -> canInstallPaper(i, j, true)
else -> true
}
if (!isBoolean) {
frame[x][y][value] = 1
return@loop
}
}
}
}
}
}
}
}
더보기
이 문제는 어려운 알고리즘을 쓴다기 보단 문제에만 충실하면 되는 문제였따.
하지만 조건을 따지는 부분이나 예외처리를 해주는 부분이 까다롭고 손이 많이 가서 level3이 아닌가 싶다.
처음에 설치/삭제를 막 진행했더니 꼬여버려서 순서대로 예외처리를 해주며 진행했더니 바로 통과했다.
'프로그래머스 > Kotlin | Level3' 카테고리의 다른 글
[프로그래머스/Kotlin]Level3 - 베스트앨범 (0) | 2023.03.26 |
---|---|
[프로그래머스/Kotlin]Level3 - 연속 펄스 부분 수열의 합 (0) | 2023.03.12 |
[프로그래머스/Kotlin]Level3 - 징검다리 건너기 (0) | 2023.02.26 |
[프로그래머스/Kotlin]Level3 - 합승 택시 요금 (0) | 2023.02.26 |
[프로그래머스/Kotlin]Level3 - 섬 연결하기 (0) | 2023.02.26 |