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

[Swift] 2020 KAKAO BLIND RECRUITMENT ๋ธ”๋ก ์ด๋™ํ•˜๊ธฐ

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

 

Problem

 

 

์ฝ”๋”ฉํ…Œ์ŠคํŠธ ์—ฐ์Šต - ๋ธ”๋ก ์ด๋™ํ•˜๊ธฐ

[[0, 0, 0, 1, 1],[0, 0, 0, 1, 0],[0, 1, 0, 1, 1],[1, 1, 0, 0, 1],[0, 0, 0, 0, 0]] 7

programmers.co.kr


Solution

 

ํ•ด๋‹น ๋ฌธ์ œ๋Š” BFS๋กœ ํ’€์–ด์•ผํ•˜๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

 

1. ํ˜„์žฌ ์œ„์น˜, ์›€์ง์ผ ๋ช…๋ น, ๋ฐฉํ–ฅ์„ ์ดˆ๊ธฐํ™”ํ•ด์ค๋‹ˆ๋‹ค.

 

struct Current {
    var x:Int,y:Int,d:Direction,count:Int,past:Command
}

enum Command:CaseIterable {
    case up,down,left,right,rotateClockwise,rotateAntiClockwise,rotateClockwise2,rotateAntiClockwise2
}

enum Direction:CaseIterable {
    case right,down,left,up
}

 

ํ˜„์žฌ ์œ„์น˜๋Š” x,y,๋ฐฉํ–ฅ,์‹œ๊ฐ„,๊ณผ๊ฑฐ์— ์›€์ง์ธ ๋ช…๋ น์„ ํ”„๋กœํผํ‹ฐ๋กœ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

 

๋ช…๋ น์€ ์œ„,์•„๋ž˜,์™ผ์ชฝ,์˜ค๋ฅธ์ชฝ๊ณผ ๋กœ๋ด‡์˜ ์ฒซ๋ฒˆ์งธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์‹œ๊ณ„๋ฐฉํ–ฅ,๋ฐ˜์‹œ๊ณ„ ๋ฐฉํ–ฅ,๋‘๋ฒˆ์งธ๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์‹œ๊ณ„๋ฐฉํ–ฅ,๋ฐ˜์‹œ๊ณ„๋ฐฉํ–ฅ

 

์ด 8๊ฐ€์ง€์˜ ๋ช…๋ น์„ ์„ค์ •ํ•ด์ค๋‹ˆ๋‹ค.

 

(์•„๋ž˜์ฒ˜๋Ÿผ ๋กœ๋ด‡์˜ 1๋ฒˆ์งธ์™€ 2๋ฒˆ์งธ๋ผ๊ณ  ๋ถ€๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.)

 

 

๋ฐฉํ–ฅ์€ ํ˜„์žฌ ๋กœ๋ด‡์˜ 1๋ฒˆ์งธ ๊ธฐ์ค€์œผ๋กœ ๋‘๋ฒˆ์งธ ๋กœ๋ด‡์ด ์–ด๋Š ๋ฐฉํ–ฅ์— ์žˆ๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

 

 

 

2. ๋ช…๋ น์— ๋”ฐ๋ผ ํ˜„์žฌ ์œ„์น˜๋ฅผ ์›€์ง์—ฌ์ค๋‹ˆ๋‹ค.

 

//๋ช…๋ น์— ๋”ฐ๋ผ ์›€์ง์ธ ์œ„์น˜๋ฅผ ๋ฐ˜ํ™˜
func move(current:Current,command:Command) -> Current {
    var newCurrent = current
    let allDirection = Direction.allCases
    let index = allDirection.firstIndex(of: current.d) ?? -1
    
    switch command {
    case .up:
         newCurrent.y -= 1
     case .down:
         newCurrent.y += 1
     case .left:
         newCurrent.x -= 1
     case .right:
         newCurrent.x += 1
    case .rotateClockwise:
        newCurrent.d = index == 3 ? .right:allDirection[index+1]
    case .rotateAntiClockwise:
        newCurrent.d = index == 0 ? .up:allDirection[index-1]
    case .rotateClockwise2:
        newCurrent = current2(current: current)
        newCurrent.d = index == 0 ? .up :allDirection[index-1]
    case .rotateAntiClockwise2:
        newCurrent = current2(current: current)
        newCurrent.d = index == 3 ? .right :allDirection[index+1]
    }
    return newCurrent
}

 

3. ์ด๋™ํ•œ ์œ„์น˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์œ„์น˜์— ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์ค๋‹ˆ๋‹ค.

 

์šฐ์„  ํ˜„์žฌ ์œ„์น˜๊ฐ€ ์ง€๋„ ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ 

 

ํ˜„์žฌ ์œ„์น˜๊ฐ€ 1์ด ์•„๋‹Œ์ง€ ํ™•์ธํ•˜๊ณ  

 

ํ˜„์žฌ ์œ„์น˜๊ฐ€ ์ด๋ฏธ ๋ฐฉ๋ฌธํ•œ ์œ„์น˜๊ฐ€ ์•„๋‹Œ์ง€ ์ด๋ ‡๊ฒŒ ์ด 3๊ฐ€์ง€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.

 

์—ฌ๊ธฐ์„œ ๋งŒ์•ฝ ํ˜„์žฌ ์œ„์น˜์˜ ๊ณผ๊ฑฐ๊ฐ€ ํšŒ์ „ํ•ด์„œ ๋„์ฐฉํ•œ ์œ„์น˜๋ผ๋ฉด 

 

๊ฐ ๋งจํ•˜ํŠผ ๊ฑฐ๋ฆฌ๊ฐ€ 1์ด ์•„๋‹ˆ์˜€๋Š”์ง€ ํ™•์ธํ•ด์ค๋‹ˆ๋‹ค.

 

//์ด๋™ํ•œ ์œ„์น˜๊ฐ€ ๊ฐ€๋Šฅํ•œ ์œ„์น˜์ธ์ง€ ํ™•์ธ
func isEnabled(current:Current,b:[[Int]]) -> Bool {
    let second = current2(current: current)
    //ํ˜„์žฌ ๋กœ๋ด‡์ด ์ง€๋„ ๋‚ด์— ์žˆ๋Š”์ง€ ํ™•์ธ
    if 0..<b.count ~= current.x && 0..<b.count ~= current.y && 0..<b.count ~= second.x && 0..<b.count ~= second.y {
        //ํ˜„์žฌ ๋กœ๋ด‡์ด ์žˆ๋Š” ๊ณณ์ด ๋ชจ๋‘ 0์ธ์ง€ ํ™•์ธ
        if b[current.y][current.x] == 0 &&  b[second.y][second.x] == 0 {
            //ํ˜„์žฌ ๋กœ๋ด‡์ด ์žˆ๋Š” ๊ณณ์ด ์ด๋ฏธ ์ง€๋‚˜๊ฐ„ ๊ณณ์ด ์•„๋‹Œ์ง€ ํ™•์ธ
            if !dontMove[current.d]![current.y][current.x] {
                //์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ ํšŒ์ „ํ–ˆ์„ ๊ฒฝ์šฐ ๊ฐ ํ˜„์žฌ ์œ„์น˜ ๋งจํ•˜ํŠผ ๊ฑฐ๋ฆฌ๊ฐ€ 0์ธ์ง€ ํ™•์ธ
                if current.past == .rotateClockwise || current.past == .rotateClockwise2{
                    return b[current.y+clockManhattan[current.d]!.1][current.x+clockManhattan[current.d]!.0] == 0
                //๋ฐ˜์‹œ๊ณ„๋ฐฉํ–ฅ์œผ๋กœ ํšŒ์ „ํ–ˆ์„ ๊ฒฝ์šฐ ๊ฐ ํ˜„์žฌ ์œ„์น˜ ๋งจํ•˜ํŠผ ๊ฑฐ๋ฆฌ๊ฐ€ 0์ธ์ง€ ํ™•์ธ
                }else if current.past == .rotateAntiClockwise || current.past == .rotateAntiClockwise2{
                    return b[current.y+antiClockManhattan[current.d]!.1][current.x+antiClockManhattan[current.d]!.0] == 0
                }else {
                    return true
                }
            }
        }
    }
    return false
}

 

4. BFS๋ฅผ ์ด์šฉํ•ด์„œ ์ง€๋„์˜ ๋งจ ๋์— ๋„์ฐฉํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณตํ•ด์ค๋‹ˆ๋‹ค.

 

ํ๋ฅผ ์ด์šฉํ•ด์„œ ํ˜„์žฌ ์œ„์น˜๋ฅผ ๋‹ด๊ณ  ๋กœ๋ด‡์ด ๊ฐ€๋Šฅํ•œ ์œ„์น˜์— ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ 

 

๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด ๋ชจ๋“  ๋ช…๋ น์— ๋”ฐ๋ผ ์›€์ง์ด๊ฒŒ ํ•˜๊ณ  ํ์— ๋‹ด์•„์ค€ ๋’ค 

 

์ง€๋„์˜ ๋งจ ๋์— ๋กœ๋ด‡์ด ๋„์ฐฉํ–ˆ๋‹ค๋ฉด ํ•ด๋‹น ์‹œ๊ฐ„์„ ๋ฐ˜ํ™˜ํ•ด์ค๋‹ˆ๋‹ค.

 

func findMinCountByBFS(board:[[Int]]) -> Int {
    let allCommand = Command.allCases
    var queue:[Current] = [Current(x: 0, y: 0, d: .right, count: 0, past: .right)]
    
    while !queue.isEmpty {
        var first = queue.removeFirst()
        let second = current2(current: first)
        
        if isEnabled(current: first, b: board) {
            if (first.x == board.count-1 && first.y == board.count-1) || (second.x == board.count-1 && second.y == board.count-1){
                return first.count
            }
            
            //๋ฐฉ๋ฌธ ํ‘œ์‹œ
            dontMove[first.d]![first.y][first.x] = true
            //์นด์šดํŠธ 1์ฆ๊ฐ€
            first.count += 1
            
            //๋ช…๋ น๋ณ„๋กœ ์›€์ง์—ฌ์คŒ
            for command in allCommand {
                var newCurrent = move(current: first, command: command)
                newCurrent.past = command
                queue.append(newCurrent)
            }
        }
    }
    return 0
}

Source Code

 


ํ›„๊ธฐ

 

์ด๋ฒˆ ๋ฌธ์ œ๋Š” ํ•œ 3์ผ๋™์•ˆ ํ’€์—ˆ๋˜ ๋ฌธ์ œ๋‹ค...

 

๋ฌธ์ œ๋ฅผ ๋ณด์ž๋งˆ์ž BFS๋กœ ํ’€๋ฉด ๊ธˆ๋ฐฉ ํ’€๋ฆฌ๊ฒ ๋„ค? ํ•˜๊ณ  ํ’€์—ˆ๋Š”๋ฐ

 

๊ตฌํ˜„๊ณผ์ •์—์„œ ์ด๋ ‡๊ฒŒ ์–ด๋ ค์›€์„ ๊ฒช์€๊ฑด ์ฒ˜์Œ์ด์—ˆ๋‹ค..

 

์ฒ˜์Œ์—” x1,y1,x2,y2๋กœ ์„ค์ •ํ•ด๋†“๊ณ  ๋กœ๋ด‡์„ ์›€์ง์ด๋ คํ•˜๋‹ˆ ํšŒ์ „์— ๋”ฐ๋ผ ์ฝ”๋“œ ๊ตฌํ˜„์ด ์—„์ฒญ ๋ณต์žกํ•ด์ง€๊ณ  ํ•˜๋‚˜๋ผ๋„

 

๋†“์น˜๋ฉด ์–ด๋””์„œ ํ‹€๋ ธ๋Š”์ง€ ํ™•์ธํ•˜๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ ธ๋‹ค.. ์ฒ˜์Œ๋ถ€ํ„ฐ ๋ฐฉํ–ฅ์œผ๋กœ ์„ค์ •ํ–ˆ๋‹ค๋ฉด ๊ธˆ๋ฐฉ ํ’€์—ˆ์„ํ…๋ฐ..

 

๋˜ํ•œ ํ…Œ์ŠคํŠธ์ผ€์ด์Šค 1๋ฒˆ์ด ๊ณ„์† ํ‹€๋ ค์„œ ์™œ ํ‹€๋ฆฌ๋Š”์ง€ ์–ด๋–ค ์ผ€์ด์Šค์ธ์ง€ ํ™•์ธํ•˜๋ ค๋Š” ๊ณผ์ •์ด ์˜ค๋ž˜ ๊ฑธ๋ ธ๋‹ค...

 

๊ฒฐ๊ตญ ์•Œ์•„๋ƒˆ๋Š”๋ฐ ํ…Œ์ŠคํŠธ์ผ€์ด์Šค 1๋ฒˆ์€ ๋กœ๋ด‡์ด ์ง€๋„ ๋งจ ๋์— ๋„์ฐฉํ–ˆ์„ ๋•Œ ๊ฐ€๋Šฅํ•œ ์œ„์น˜์— ์žˆ๋Š”์ง€ ์—†๋Š”์ง€ ํ™•์ธํ•ด์•ผํ–ˆ๋‹ค.

 

ex)

 

0 0 0 0 0

0 0 0 0 0

0 0 0 0 0

0 0 0 r1 r2

0 0 0 1 0

 

์•„๋ž˜์™€ ๊ฐ™์ด ๋กœ๋ด‡์ด ์žˆ๋‹ค๋ฉด ๋งˆ์ง€๋ง‰์— ์•„๋ž˜๋กœ ์ด๋™ํ•œ ๊ฒฝ์šฐ ๊ฐ€์žฅ ๋งจ ๋์— ์ด๋™ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

ํ•˜์ง€๋งŒ r1์— 1์ด ์žˆ์œผ๋ฏ€๋กœ ๋„์ฐฉํ–ˆ๋‹ค ํ•˜๋”๋ผ๋„ ๊ฐ€๋Šฅํ•œ์ง€ ์—ฌ๋ถ€๋ฅผ ํŒŒ์•…ํ•ด์•ผํ•œ๋‹ค.

728x90
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€