clamp
Clamp
clamp
글쓰기 관리
전체 방문자
오늘
어제
  • 분류 전체보기 (509)
    • IOS (85)
    • SwiftUI+TCA+Combine (9)
    • RxSwift + MVVM (56)
    • Clean Architecture (12)
    • SWIFT (56)
    • iOS - TDD (2)
    • 디자인패턴 (4)
    • CS (56)
      • 알고리즘 (29)
      • 운영체제 (15)
      • 자료구조 (2)
      • 네트워킹 (4)
      • 기타 (6)
    • 회고 (0)
    • Firebase (18)
    • SwiftUI (10)
    • iOS - UIKit (11)
    • iOS - 오픈소스 (6)
    • 코딩테스트 (166)
      • 프로그래머스 (164)
    • 정보처리기사 (14)
    • GitHub (2)
글쓰기 / 관리자

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • ㅅ
  • Swift
  • uikit
  • Q

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
clamp

Clamp

프로그래머스 - [1차] 프렌즈4블록 Swift(구현, 좌표)
코딩테스트/프로그래머스

프로그래머스 - [1차] 프렌즈4블록 Swift(구현, 좌표)

2023. 2. 11. 20:41

    프렌즈4블록

    블라인드 공채를 통과한 신입 사원 라이언은 신규 게임 개발 업무를 맡게 되었다. 이번에 출시할 게임 제목은 "프렌즈4블록".
    같은 모양의 카카오프렌즈 블록이 2×2 형태로 4개가 붙어있을 경우 사라지면서 점수를 얻는 게임이다.


    만약 판이 위와 같이 주어질 경우, 라이언이 2×2로 배치된 7개 블록과 콘이 2×2로 배치된 4개 블록이 지워진다. 같은 블록은 여러 2×2에 포함될 수 있으며, 지워지는 조건에 만족하는 2×2 모양이 여러 개 있다면 한꺼번에 지워진다.

    블록이 지워진 후에 위에 있는 블록이 아래로 떨어져 빈 공간을 채우게 된다.

    만약 빈 공간을 채운 후에 다시 2×2 형태로 같은 모양의 블록이 모이면 다시 지워지고 떨어지고를 반복하게 된다.

    위 초기 배치를 문자로 표시하면 아래와 같다.

    TTTANT
    RRFACC
    RRRFCC
    TRRRAA
    TTMMMF
    TMMTTJ
    

    각 문자는 라이언(R), 무지(M), 어피치(A), 프로도(F), 네오(N), 튜브(T), 제이지(J), 콘(C)을 의미한다

    입력으로 블록의 첫 배치가 주어졌을 때, 지워지는 블록은 모두 몇 개인지 판단하는 프로그램을 제작하라.

    입력 형식

    • 입력으로 판의 높이 m, 폭 n과 판의 배치 정보 board가 들어온다.
    • 2 ≦ n, m ≦ 30
    • board는 길이 n인 문자열 m개의 배열로 주어진다. 블록을 나타내는 문자는 대문자 A에서 Z가 사용된다.

    출력 형식

    입력으로 주어진 판 정보를 가지고 몇 개의 블록이 지워질지 출력하라.

    입출력 예제

    m       n       board                                                                                                                                                                   answer
    4 5 ["CCBDE", "AAADE", "AAABF", "CCBBF"] 14
    6 6 ["TTTANT", "RRFACC", "RRRFCC", "TRRRAA", "TTMMMF", "TMMTTJ"] 15

    예제에 대한 설명

    • 입출력 예제 1의 경우, 첫 번째에는 A 블록 6개가 지워지고, 두 번째에는 B 블록 4개와 C 블록 4개가 지워져, 모두 14개의 블록이 지워진다.
    • 입출력 예제 2는 본문 설명에 있는 그림을 옮긴 것이다. 11개와 4개의 블록이 차례로 지워지며, 모두 15개의 블록이 지워진다.

    풀이 및 소스코드

     

    초기화) 반복 정보를 true 처리한다.(아래 설명)

    1. x와 y의 좌표는 m - 2, n -2까지 이동한다. 왜냐하면 검사하는 과정에서 m+1, y+1을 검사하기 때문이다.

    5라면 index는 4까지 있는데, 3까지만 직접 좌표를 이동하고 4는 검사 과정에서 자동으로 체크가 된다.

     

    2. map[x][y], map[x][y+1], map[x+1][y+1], map[x+1][y] 가 모두 같다면 네모다. 따라서 맵을 한번 다 훑고 check 배열에 체크를 해 놨다가  맵 전체를 순회하면 그 때에 카운트를 해준다. 그리고 아직 네모가 남아있을 수 있다는 뜻이므로 반복정보를 false로 저장한다.

     

    예제를 1회 체크한 배열의 상태

    [false, false, false, false, false, false]

    [true,   true,  false, false, true,  true]

    [true,   true,  true,   false, true,  true]

    [false, true,  true,   false, false, false]

    [false, false, false, false, false, false]

    [false, false, false, false, false, false]

    반드시 1회전이 끝나고 후 처리를 해야함.

     

    3. 체크 배열의 true에 해당하는 위치를 "~"로 변환하고 count한다.

     

    4. 네모가 체크되어 사라진 공간을 체크해야 하는데, 네모인지 검사할때와 반대로 아래서 위로 이동한다.

    x좌표를 아래에서 위로 이동하며 빈 공간("~")를 만다면 x좌표가 0이 될 때 까지 -1하여(위로 올라가서) "~"이 아닌 위치를 찾아서 빈공간 위치와 "~" 이 아닌 위치를 교체한다.

     

    5. 반복정보가 false인동안 초기화 ~ 5)를 반복한다. 만약 반복정보가 2번에서 false로 바뀌지 않았다면 다음회전 초기화때 true로 남게되므로 한 바퀴 회전하고 끝이난다

     

    // m = 높이, n = 폭
    func solution(_ m:Int, _ n:Int, _ board:[String]) -> Int {
        
        var x = 0, y = 0
        
        
        var end = false
        var map  = [[Character]]()
        var count = 0
        for i in board{
            map.append(Array(i))
        }
        
        while end != true{
            
            end = true
            //네모인지 체크 할 2중배열
            var check = [[Bool]](repeating: [Bool](repeating: false, count: n), count: m)
            
            //x, y좌표로 시작
            for x_idx in 0..<m-1{
                x = x_idx
                for y_idx in 0..<n-1{
                    y = y_idx
                    //현재 좌표의 값, 현재 좌표가 ("~")가 아니면 네모의 값을 읽어옴
                    let now = map[x][y]
                    if now != Character("~"){
                        let r = map[x][y+1]
                        let dr = map[x+1][y+1]
                        let d = map[x+1][y]
                        //네모면 check배열에 체크
                        if now == r && r == dr && dr == d{
                            end = false
                            check[x][y] = true
                            check[x][y+1] = true
                            check[x+1][y+1] = true
                            check[x+1][y] = true
                        }
                    }
                }
            }
            //체크배열의 네모위치에 해당하는 위치를 count 하고 ~로 바꿈
            for x in 0..<m{
                for y in 0..<n{
                    if check[x][y] == true{
                        map[x][y] = Character("~")
                        count += 1
                    }
                }
            }
            
            //빈 공간 채우기
            for x in (0..<m).reversed(){
                for y in 0..<n{
                    if map[x][y] == Character("~"){
                        var x_find = x
                        while x_find != 0{
                            x_find -= 1
                            
                            if map[x_find][y] != Character("~"){
                                map[x][y] = map[x_find][y]
                                map[x_find][y] = Character("~")
                                break
                            }
                        }
                    }
                }
            }
        }
    
        return count
    }

     

     

    저작자표시 비영리 동일조건 (새창열림)
      '코딩테스트/프로그래머스' 카테고리의 다른 글
      • 프로그래머스 - 모음 사전 Swift(DFS)
      • 프로그래머스 - [3차] 파일명 정렬 Swift(구현, 정렬)
      • 프로그래머스 - 방문 길이 Swift(좌표, 중복)
      • 프로그래머스 - 땅따먹기 Swift (Dynamic Programing: DP)
      clamp
      clamp
      주니어 iOS개발자의 발악!!!!!!!

      티스토리툴바