ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Programmers.co.kr/Swift] 쿼드 압축 후 세기
    Legacy/Be Refactoring.. 2021. 3. 3. 08:28

    Programmers.co.kr/코딩테스트 연습 - 월간 코드 챌린지 1 - 쿼드 압축 후 세기 (Lv. 2)

    programmers.co.kr/learn/courses/30/lessons/68936

     

    코딩테스트 연습 - 쿼드압축 후 개수 세기

    [[1,1,0,0],[1,0,0,0],[1,0,0,1],[1,1,1,1]] [4,9] [[1,1,1,1,1,1,1,1],[0,1,1,1,1,1,1,1],[0,0,0,0,1,1,1,1],[0,1,0,0,1,1,1,1],[0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,1],[0,0,0,0,1,0,0,1],[0,0,0,0,1,1,1,1]] [10,15]

    programmers.co.kr


    TODO :

    0과 1로 이루어진 2ᴺ x 2 크기의 2차원 정수 배열 arr이 있습니다.

    당신은 이 arr을 쿼드 트리와 같은 방식으로 압축하고자 합니다.

    구체적인 방식은 다음과 같습니다.

    1. 당신이 압축하고자 하는 특정 영역을 S라고 정의합니다.
    2. 만약 S 내부에 있는 모든 수가 같은 값이라면, S를 해당 수 하나로 압축시킵니다.
    3. 그렇지 않다면, S를 정확히 4개의 균일한 정사각형 영역으로 쪼갠 뒤, 각 정사각형 영역에 대해 같은 방식의 압축을 시도합니다.

    arr이 매개변수로 주어집니다.

    위와 같은 방식으로 arr을 압축했을 때,

    배열에 최종적으로 남는 0의 개수와 1의 개수를 배열에 담아서 return 하도록 solution 함수를 완성해주세요.

     

    Constraints : 

    • arr의 행의 개수는 1 이상 1024 이하이며, 2의 거듭 제곱수 형태를 하고 있습니다. 즉, arr의 행의 개수는 1, 2, 4, 8, ..., 1024 중 하나입니다.
      • arr의 각 행의 길이는 arr의 행의 개수와 같습니다. 즉, arr은 정사각형 배열입니다.
      • arr의 각 행에 있는 모든 값은 0 또는 1 입니다.

    Sample Input :

    arr
    [[1,1,0,0],[1,0,0,0],[1,0,0,1],[1,1,1,1]]
    [[1,1,1,1,1,1,1,1],[0,1,1,1,1,1,1,1],[0,0,0,0,1,1,1,1],[0,1,0,0,1,1,1,1],[0,0,0,0,0,0,1,1],[0,0,0,0,0,0,0,1],[0,0,0,0,1,0,0,1],[0,0,0,0,1,1,1,1]]

    Sample Output :

    result
    [4,9]
    [10,15]

    Solution.swift : 

    //  Created by Yongwoo Marco on 2021/01/19.
    //  Copyright © 2020 Yongwoo Marco Kim. All rights reserved.
    //
    import Foundation
    func solution(_ arr:[[Int]]) -> [Int] {
        var zeroCount = 0, oneCount = 0, size = arr.count
        
        func check(_ square: [[Int]]) -> Int? {
            let first = square[0][0]
            
            for y in 0..<square.count {
                for x in 0..<square.count {
                    if !(x == 0 && y == 0), square[y][x] != first {
                        return nil
                    }
                }
            }
            
            return first == 0 ? 0 : 1
        }
        
        func quadCompress(_ arr: [[Int]],_ size: Int) {
            var quads = [[[Int]]](repeating: [], count: 4)
            
            for i in 0..<size/2 {
                var temp1 = [Int]()
                var temp2 = [Int]()
                for one in 0..<size/2 {
                    temp1.append(arr[i][one])
                }
                quads[0].append(temp1)
                for two in size/2..<size {
                    temp2.append(arr[i][two])
                }
                quads[1].append(temp2)
            }
            
            for i in size/2..<size {
                var temp1 = [Int]()
                var temp2 = [Int]()
                for three in 0..<size/2 {
                    temp1.append(arr[i][three])
                }
                quads[2].append(temp1)
                for four in size/2..<size {
                    temp2.append(arr[i][four])
                }
                quads[3].append(temp2)
            }
            
            for quad in quads {
                if let num = check(quad) {
                    if num == 0 {
                        zeroCount += 1
                    } else {
                        oneCount += 1
                    }
                } else {
                    quadCompress(quad, size/2)
                }
            }
        }
        
        if let num = check(arr) {
            if num == 0 {
                zeroCount += 1
            } else {
                oneCount += 1
            }
        } else {
            quadCompress(arr, size)
        }
        
        return [zeroCount, oneCount]
    }

    How I tried this :

    문제는 생각 보다 간단하다.

    주어진 정사각형을 4등분 하는데 각 작은 사각형의 포함된 수가 모두 0 또는 1로 같으면

    그냥 두고 같지 않으면 또 4등분을 하고 각각의 사각형의 포함된 숫자를 확인한다.

     

    결과는 1의 갯수와 0의 갯수를 세면 되는데

    만약 2x2로 만들어진 사각형이 0으로 압축되었다면 0은 하나 인거고

    16x16로 만들어진 사각형도 0으로 압축되었다면 0은 똑같이 하나 라는 거다..

     

    코드가 길어서 나누어 설명하려 한다

    func solution(_ arr:[[Int]]) -> [Int] {
        var zeroCount = 0, oneCount = 0, size = arr.count
        
        func check(_ square: [[Int]]) -> Int? {
        	// 주어진 사각형이 0 또는 1로 압축가능 한가?
        }
        
        func quadCompress(_ arr: [[Int]],_ size: Int) {
         	// 주어진 사각형을 4등분 하기
        }
        
        if let num = check(arr) {
            if num == 0 {
                zeroCount += 1
            } else {
                oneCount += 1
            }
        } else {
            quadCompress(arr, size)
        }
        
        return [zeroCount, oneCount]
    }

    다음과 같이 코드를 진행한다.

     

    1. 4각형모양의 이차배열을 4등분 한다.

    2. 4등분 한 각 이차배열을 check() 한다

    3. check() 이 0 또는 1을 리턴하면 zeroCount 또는 oneCount를 +1 하고 함수는 마감

    4. check() 이 nil (내용이 모두 동일하지 않다)을 리턴하면 그 이차배열을 다시 4등분 한다.

    func check(_ square: [[Int]]) -> Int? {
        let first = square[0][0]
            
        for y in 0..<square.count {
            for x in 0..<square.count {
                if !(x == 0 && y == 0), square[y][x] != first {
                    return nil
                }
            }
        }
            
        return first == 0 ? 0 : 1
    }

    주어진 이차배열을 하나 씩 방문하는데 그 과정에서 [0][0] 내용을 기준으로

    계속 같으면 압축가능하므로 해당하는 0또는 1로 압축 가능한 내용물을 리턴 해준다.

    만약 최초 내용과 다른 내용이 나온다면 함수를 마치며 nil을 리턴한다 

     

    func quadCompress(_ arr: [[Int]],_ size: Int) {
        var quads = [[[Int]]](repeating: [], count: 4)
            
        for i in 0..<size/2 {
            var temp1 = [Int]()
            var temp2 = [Int]()
    
            for one in 0..<size/2 {
                temp1.append(arr[i][one])
            }
            quads[0].append(temp1)
            for two in size/2..<size {
                temp2.append(arr[i][two])
            }
            quads[1].append(temp2)
        }
            
        for i in size/2..<size {
            var temp1 = [Int]()
            var temp2 = [Int]()
        
        	for three in 0..<size/2 {
                temp1.append(arr[i][three])
            }
            quads[2].append(temp1)
            for four in size/2..<size {
                temp2.append(arr[i][four])
            }
            quads[3].append(temp2)
        }       
        
        // 각 작은 사각형 확인하기
        for quad in quads {
            if let num = check(quad) {
                if num == 0 {
                    zeroCount += 1
                } else {
                    oneCount += 1
                }
            } else {
                quadCompress(quad, size/2)
            }
        }
    }

    다시 짜라고 해도 머리가 사실 아프다

    내용은 간단하다 예를들어 4x4 이차배열을

    2x2 네 개의 이차배열로 나눌건데.

    직관적으로 

    [[0, 1],

    [1, 1]]

    같은 모양을 유지하도록 

    for문을 구성해서 4번 진행했다

    두번의 for문과 i 는 이차배열의 첫번째 인덱스 [y][x] -> y를 의미하고

    one, three 는 2사분면과 3사분면 이차배열의 두번째 인덱스 x (0..<최대크기/2)

    two, four 는 1사분면과 4사분면 이차배열의 두번째 인덱스 x (최대크기/2..<최대크기)

     

    각 쪼개진 사각형은 quad로 지칭해서 

    다시 하나씩 확인했다.

     

    What I got is : 

     

     

    I have to study :

     

    문제에 관한 모든 저작권 : https://programmers.co.kr/
     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

Designed by Tistory.