# Algorithm/--- 프로그래머스

[프로그래머스] 프렌즈 4블록 with Swift

jiniz.ll 2022. 7. 5. 13:17

 

문제

출처. 해당 문제 페이지

  • 다음과 같은 블록이 있을 때, 같은 모양의 블록이 2x2 형태로 붙어 있다면 블록이 지워지며 점수를 얻을 수 있음
  • 이 때, 2x2 배치가 여러개 있는 경우 한번에 지워진다.

 

  • 한 번 지워지고 나면 남은 블록은 위에서 아래로 떨어지게 됨
  • 빈 공간을 채운 후에 다시 2x2 형태의 블록이 모이면 다시 지워지고 떨어지는 것을 반복
  • 지워지는 블록의 총 개수를 구하기

 

  • 높이 m, 폭 n의 board
  • n, m 은 2 이상 30 이하
  • board 는 길이 n인 문자열 m개의 배열로 주어짐. 블록을 나타내는 문자는 대문자 A~Z가 사용됨

 

Idea

  • 보드판을 하나씩 체크하면서 4블록이 만들어지는지 확인하여
  • 4블록이 만들어지면 체크해두기

 

  • 한 열씩 아래서 부터 비어있는 칸 채우기
  • 위에 블록이 없는 경우는 소문자 “x”로 채움
  • 위 과정을 반복하며 4블록이 만들어지지 않는 경우 종료

 

  • 비어 있는 칸의 개수를 세서 반환

 

Code

Swift

func solution(_ m:Int, _ n:Int, _ board:[String]) -> Int {
    
    var board = board.map { Array($0).map { String($0) } }
    var checked = Array(repeating: Array(repeating: false, count: n), count: m)
    
    func checkBlock() -> Bool {
        var isChecked = false
        for r in 0..<m-1 {
            for c in 0..<n-1 {
                if board[r][c] == "x" { continue }
                let block = board[r][c]
                if board[r][c+1] == block, 
                   board[r+1][c+1] == block, 
                   board[r+1][c] == block {
                    checked[r][c] = true
                    checked[r][c+1] = true
                    checked[r+1][c+1] = true
                    checked[r+1][c] = true
                    isChecked = true
                }
            }
        }
        return isChecked
    }
    
    func rearrangeBoard() {
        for c in 0..<n {
            for r in (0..<m).reversed() {
                if checked[r][c] {
                    var i = r-1
                    while i >= 0 && checked[i][c] {
                        i -= 1
                    }
                    if i < 0 {
                        checked[r][c] = true
                        board[r][c] = "x"
                    } else {
                        checked[i][c] = true
                        checked[r][c] = false
                        let value = board[i][c]
                        board[i][c] = "x"
                        board[r][c] = value
                    }
                }
            }
        }
    }
    
    while checkBlock() {
        rearrangeBoard()
    }
    
    return checked.reduce(0) { $0 + $1.filter{ $0 }.count }
}