Swift) 백준 14891번 톱니바퀴 - G5

https://www.acmicpc.net/problem/14891

 

14891번: 톱니바퀴

총 8개의 톱니를 가지고 있는 톱니바퀴 4개가 아래 그림과 같이 일렬로 놓여져 있다. 또, 톱니는 N극 또는 S극 중 하나를 나타내고 있다. 톱니바퀴에는 번호가 매겨져 있는데, 가장 왼쪽 톱니바퀴

www.acmicpc.net

단순 구현문제. 기어가 돌아가는 방식이 서로 다른 극일때 기어가 돌아 갈 수 있다. 즉 기어다 돌아가기 전에 다른 극이어야지만 돌아가지, 이전에 같은 극이었다가 기어가 돌아 간 후 다른 극이 된 상태에서는 돌아가지 않는다.

 

나같은 경우는 큐를 이용하여 rotate할 기어의 방향과 번호를 저장 후 큐에서 빼낸 후 해당 기어의 번호 +-1씩 해준 후 해당 번호의 기어가 돌아 갈 수 있다면 큐에서 빼낸 기어가 돌아가는 방향을 토글해서 큐에 넣는 방식으로 문제를 해결.

import Foundation

var gearArr: [[Int]] = Array(repeating: Array(repeating: 0, count: 0), count: 5)

struct RotateGear {
    let num: Int
    let direction: Bool
}

// direction이 true이면 시계, false면 반시계
//체크 2, 6
func solution(gearNum: Int, direction: Bool) {
    var rotateGearQueue: [RotateGear] = []
    var rotatingGearArr: [RotateGear] = []
    var visited: [Bool] = Array(repeating: false, count: 5)
    
    func checkShouldRotate(num: Int) -> [Int] {
        var shouldRotateGear: [Int] = []
        if num+1 <= 4 {
            if gearArr[num][2] != gearArr[num+1][6] {
                if !visited[num+1] {
                    shouldRotateGear.append(num+1)
                }
            }
        }
        if num-1 > 0 {
            if gearArr[num][6] != gearArr[num-1][2] {
                if !visited[num-1] {
                    shouldRotateGear.append(num-1)
                }
            }
        }
        return shouldRotateGear
    }
    
    
    visited[gearNum] = true
    rotatingGearArr.append(.init(num: gearNum, direction: direction))
    let a = checkShouldRotate(num: gearNum)
    for i in a {
        visited[i] = true
    }
    rotateGearQueue.append(contentsOf: a.map { .init(num: $0, direction: !direction) })
    
    while !rotateGearQueue.isEmpty {
        let popGear = rotateGearQueue.removeFirst()
        rotatingGearArr.append(popGear)
        let appendGear = checkShouldRotate(num: popGear.num)
        for i in appendGear {
            rotateGearQueue.append(.init(num: i, direction: !popGear.direction))
            visited[i] = true
        }
    }
    for q in rotatingGearArr {
        gearRotate(num: q.num, direction: q.direction)
    }
    //print(gearArr)
}



func gearRotate(num: Int, direction: Bool) {
    if direction {
        var gear = gearArr[num]
        let last = gear.removeLast()
        gear.insert(last, at: 0)
        gearArr[num] = gear
    } else {
        var gear = gearArr[num]
        let last = gear.removeFirst()
        gear.append(last)
        gearArr[num] = gear
    }
}

for i in 0..<4 {
    let read = readLine()!
    let input = Array(read).map{ String($0) }.map{Int($0)!}
    gearArr[i+1] = input
}

let n = Int(readLine()!)!
for _ in 0..<n {
    let input = readLine()!.split(separator: " ").map{ Int($0)! }
    solution(gearNum: input[0], direction: input[1] > 0)
}
var answer = 0
answer += gearArr[1][0] == 1 ? 1 : 0
answer += gearArr[2][0] == 1 ? 2 : 0
answer += gearArr[3][0] == 1 ? 4 : 0
answer += gearArr[4][0] == 1 ? 8 : 0
print(answer)