반응형
안녕하세요. 개발 중인 정주입니다.
오늘은 "프로그래머스(Lv.2) - [1차] 프렌즈4블록" 문제를 풀었습니다.
Github
문제 링크
풀이
이번 문제는 구현 문제입니다.
딱 봐도 보이지만 원소를 하나씩 내리는 것이 포인트입니다.
1. 블록의 이름 String과 존재 유무를 나타내는 Bool을 Tuple로 묶어줍니다.
블록이 터졌는지 남아있는지 나타내는 Bool 값을 넣어줬습니다.
문제에 "같은 블록은 여러 2×2에 포함될 수 있으며"라는 조건이 포함되어 있기 때문입니다.
만약 4개가 있어 바로 터친다면 다른 2x2에 포함될 수 없을 것입니다.
2. 더이상 터질 게 없을 때까지 반복합니다.
더이상 터질 블록이 없을 때까지 반복문을 돌립니다.
3. 보드를 탐색하며 2x2가 동일한 지 확인합니다.
보드를 하나하나 살펴보며 2x2가 동일한지 확인합니다.
동일하다면 Bool 값을 false로 바꿉니다.
4. Bool 값이 false인 블록을 없애고 위 블록을 아래로 내립니다.
블록을 없애는 것은 이름을 ""로 바꿔주는 작업으로 진행 했습니다.
Bool 값을 체크하여 false면 블록을 아래로 내리고 원래 블록 위치에 ("", false)를 대입합니다.
5. 마지막에 false인 원소의 개수를 셉니다.
Bool 값이 false인 원소의 개수를 모두 셉니다.
이것이 바로 답!
전체 코드
import Foundation
let dx = [0, 1, 0, 1], dy = [0, 0, 1, 1]
func checkPop(_ i: Int, _ j: Int, _ board: [[(String, Bool)]]) -> Bool {
let item = board[i][j].0
for k in 0..<4 {
if item != board[i+dx[k]][j+dy[k]].0 {
return false
}
}
return true
}
func solution(_ m:Int, _ n:Int, _ board:[String]) -> Int {
//보드 만들기, (아이템, 존재 유무)
var nBoard: [[(String, Bool)]] = []
nBoard = board.map { $0.map { (String($0), true) } }
var isPop = true
while isPop { //더이상 터질 게 없을 때까지 반복
isPop = false
for i in 0..<nBoard.count-1 { //4개씩 체크
for j in 0..<nBoard[i].count-1 {
let item = nBoard[i][j].0
if !item.isEmpty && checkPop(i, j, nBoard) {
isPop = true
for k in 0..<4 {
nBoard[i+dx[k]][j+dy[k]] = (item, false)
}
}
}
}
for i in 0..<n { //내리기
for j in 0..<m {
if !nBoard[j][i].1 { //터진거면
var count = j-1
while count >= 0 && !nBoard[count][i].0.isEmpty {
nBoard[count+1][i] = nBoard[count][i]
nBoard[count][i] = ("", false)
count -= 1
}
}
}
}
}
var result = 0
for board in nBoard {
result += board.filter { $0.1 == false }.count
}
return result
}
아직은 초보 개발자입니다.
더 효율적인 코드 훈수 환영합니다!
공감과 댓글 부탁드립니다.
반응형