๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๐Ÿ“– Problem Solution/Programmers

[Swift] 2019 KAKAO BLIND RECRUITMENT ๋ธ”๋ก ๊ฒŒ์ž„

by Fomagran ๐Ÿ’ป 2022. 3. 28.
728x90
๋ฐ˜์‘ํ˜•

Problem

 

 

์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์—ฐ์Šต - ๋ธ”๋ก ๊ฒŒ์ž„

[[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,4,0,0,0],[0,0,0,0,0,4,4,0,0,0],[0,0,0,0,3,0,4,0,0,0],[0,0,0,2,3,0,0,0,5,5],[1,2,2,2,3,3,0,0,0,5],[1,1,1,0,0,0,0,0,0,5]] 2

programmers.co.kr


Solution

 

1. ๋จผ์ € ๊ฒ€์€ ๋ธ”๋ก์„ ๋–จ์–ด๋œจ๋ ค ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก๋“ค์„ ์ฐพ์•„๋‚ธ๋‹ค.

 

์ฃผ์–ด์ง„ ๋ธ”๋ก์€ ์ฐจ๋ก€๋Œ€๋กœ 1๋ฒˆ ๋ธ”๋ก์˜ 0,1,2,3 ํƒ€์ž…, 2๋ฒˆ ๋ธ”๋ก์˜ 0,1,2,3 ํƒ€์ž… , 3๋ฒˆ ๋ธ”๋ก์˜ 0,1,2,3ํƒ€์ž…์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•  ๋•Œ

 

๊ฒ€์€ ๋ธ”๋ก์„ ์œ„์—์„œ ๋–จ์–ด๋œจ๋ ค์„œ ์ฑ„์›Œ์•ผ ํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ 1๋ฒˆ ๋ธ”๋ก์˜ 2,3 ํƒ€์ž…, 2๋ฒˆ ๋ธ”๋ก์˜ 1,2 ํƒ€์ž… 3๋ฒˆ ๋ธ”๋ก์˜ 0๋ฒˆ ํƒ€์ž…๋งŒ ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

 

 

2. ์ฃผ์–ด์ง„ ๋ณด๋“œ์—์„œ ๋ธ”๋ก์˜ ์ข…๋ฅ˜, ํƒ€์ž…, ์„ธ๋กœor๊ฐ€๋กœ, ์œ„์น˜๋ฅผ ์ฐพ์•„๋‚ธ๋‹ค.

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋ธ”๋ก์€ ํ–‰๊ณผ ์—ด์„ ํ†ตํ•ด์„œ ์„ธ๋กœ๋กœ ์žˆ๋Š”์ง€ ๊ฐ€๋กœ๋กœ ์žˆ๋Š”์ง€๋ฅผ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ด๊ฒƒ์„ ํ†ตํ•ด ๋จผ์ € ๊ฐ€๋กœ๋กœ ๋œ ๋ธ”๋ก๋“ค์„ ์ „์ฒด ๋ณด๋“œ์—์„œ ์ฐพ์Šต๋‹ˆ๋‹ค.

 

 

 

๋จผ์ € ์„ธ๋กœ๋กœ ๋œ ๋ธ”๋ก์„ ์ฐพ์•„๋‚ด๋Š” ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™์ด 2x3 ๋ชจ์–‘์„ (0,0) ๋ถ€ํ„ฐ (N-1,N-1) ๊นŒ์ง€ ํ™•์ธํ•ด์„œ ๋˜‘๊ฐ™์€ ์ˆซ์ž๊ฐ€ 4๊ฐœ๊ฐ€ ์žˆ๋‹ค๋ฉด ๋ธ”๋ก์ด ์กด์žฌํ•œ๋‹ค๋Š” ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.

 

 

๊ฐ€๋กœ๋กœ ๋œ ๋ธ”๋ก์€ 3x2 ๋ชจ์–‘์„ ์„ธ๋กœ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ (0,0) ๋ถ€ํ„ฐ (N-1,N-1) ๊นŒ์ง€ ํ™•์ธํ•ด์„œ ์ฐพ์•„์ค๋‹ˆ๋‹ค.

 

 

* ๋ธ”๋ก์„ ์ฐพ๋Š” ํ•จ์ˆ˜

 

func findBlocks(_ board:[[Int]],_ isVertical:Bool) {
    let row = isVertical ? 3 : 2
    let col = isVertical ? 2 : 3
    
    for i in 0...board.count-row {
        for j in 0...board.count-col {
            var block:[[Int]] = Array(repeating: [], count: row)
            for k in 0..<row {
                block[row-1-k] = Array(board[i+k][j...j+col-1])
            }
            let change = isExistEqual4Number(block)
            if let change = change {
                let equal = checkEqualBlock(change, isVertical: isVertical, position: CGPoint(x: j, y:i+row-1))
                if let equal = equal {
                    blocks.append(equal)
                }
            }
        }
    }
}

 

*  ๋˜‘๊ฐ™์€ ์ˆซ์ž๊ฐ€ 4๊ฐœ ์žˆ๋Š”์ง€ ํŒ๋ณ„ํ•˜๋Š” ํ•จ์ˆ˜

 

func isExistEqual4Number(_ block:[[Int]]) -> [[Int]]? {
    var numberCount:[Int:Int] = [:]
    var changeBlock:[[Int]] = []
    for b in block {
        for n in b {
            if numberCount[n] == nil && n != 0 {
                numberCount[n] = 1
            }else {
                numberCount[n]! += 1
            }
        }
    }
    
    for (n,c) in numberCount {
        if c == 4 {
            for (i,b) in block.enumerated() {
                changeBlock.append([])
                for e in b {
                    let oneOrZero = e == n ? 1 : 0
                    changeBlock[i].append(oneOrZero)
                }
            }
            return changeBlock
        }
    }
    return nil
}

 

* ์–ด๋Š ์ข…๋ฅ˜์˜ ๋ธ”๋ก์ธ์ง€ ํ™•์ธํ•˜๊ณ  ํ•ด๋‹น ๋ธ”๋ก์— ๋งž๊ฒŒ ๋ฐ”๊ฟ”์ฃผ๋Š” ํ•จ์ˆ˜

 

func checkEqualBlock(_ block:[[Int]],isVertical:Bool,position:CGPoint) -> Block? {
    let type = isVertical ? [1,3] : [0,2]
    for i in 1...3 {
        for t in type {
            if numberTypes[i]![t] == block {
                return Block(position: position, number: i, type: t, isVertical:isVertical)
            }
        }
    }
    return nil
}

 

3. ์ฐพ์•„๋‚ธ ๋ธ”๋ก ์ค‘ ์‚ญ์ œ ๊ฐ€๋Šฅํ•œ์ง€ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•œ๋‹ค.

 

๋ธ”๋ก์ด ์‚ญ์ œ๊ฐ€ ๊ฐ€๋Šฅํ•œ์ง€๋ฅผ ํŒ๋ณ„ํ•˜๊ธฐ ์œ„ํ•ด์„  ์šฐ์„  1์—์„œ ๊ตฌํ•œ 1๋ฒˆ ๋ธ”๋ก์˜ 2,3 ํƒ€์ž…, 2๋ฒˆ ๋ธ”๋ก์˜ 1,2 ํƒ€์ž… 3๋ฒˆ ๋ธ”๋ก์˜ 0๋ฒˆ ํƒ€์ž… ์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•˜๊ณ , ํ•ด๋‹น ๋ธ”๋ก์˜ ๋นˆ์นธ์˜ ์œ„์— ์•„๋ฌด๋Ÿฐ ๋ธ”๋ก์ด ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

* ์ด 5๊ฐœ ํƒ€์ž…์˜ ๋ธ”๋ก์˜ ์œ„ ์นธ์— ์•„๋ฌด๋Ÿฐ ๋ธ”๋ก์ด ์—†๋Š”์ง€ ํ™•์ธํ•˜๋Š” ํ•จ์ˆ˜

 

func checkAboveBlocks(_ block:Block,_ board:inout [[Int]]) {
    var xs:[Int] = []
    let x = Int(block.position.x)
    let y = Int(block.position.y)
    var remove:[(Int,Int)] = []
    if block.number == 1 && block.type == 2{
        xs = [x+1,x+2]
        remove = [(x,y),(x+1,y),(x+2,y),(x,y-1)]
    }else if block.number == 1 && block.type == 3 {
        xs = [x]
        remove = [(x,y),(x+1,y),(x+1,y-1),(x+1,y-2)]
    }else if block.number == 2 && block.type == 1 {
        xs = [x+1]
        remove = [(x,y),(x+1,y),(x,y-1),(x,y-2)]
    }else if block.number == 2 && block.type == 2 {
        xs = [x,x+1]
        remove = [(x,y),(x+1,y),(x+2,y),(x+2,y-1)]
    }else if block.number == 3 && block.type == 0 {
        xs = [x,x+2]
        remove = [(x,y),(x+1,y),(x+2,y),(x+1,y-1)]
    }else {
        return
    }
    for x in xs {
        for y in 0...y-1 {
            if board[y][Int(x)] != 0 {
                return
            }
        }
    }
    for r in remove {
        board[r.1][r.0] = 0
    }
    count += 1
}

 

4. ์‚ญ์ œ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก์˜ ๊ฐฏ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

์ฐพ์•„๋‚ธ ๋ธ”๋ก ์ „์ฒด์—์„œ ์‚ญ์ œ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก์˜ ๊ฐฏ์ˆ˜๋ฅผ ์ฐพ์•„์„œ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

* ์‚ญ์ œ ๊ฐ€๋Šฅํ•œ ๋ธ”๋ก์˜ ๊ฐฏ์ˆ˜๋ฅผ ๊ตฌํ•˜๋Š” ํ•จ์ˆ˜

 

func countRemovableBlocks(_ board:[[Int]]) -> Int {
    var board = board
    let sorted = blocks.sorted {$0.position.y < $1.position.y}
    for block in sorted {
        checkAboveBlocks(block,&board)
    }
    return count
}

Source Code

 

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€