[코딩테스트] ⚙️ 톱니바퀴 돌리기 - 구현문제 삼성 SW 역량

2025. 9. 20. 20:01알고리즘

문제

백준 - 톱니바퀴 돌리기

난이도 골드 5

소요시간: 1시간 ㅠㅠ

회고: 복잡한 알고리즘 없이 문제를 구현하면 되는 문제였다. 풀고 나니 복잡한 게 없는 문제인데 머리가 멈춘 거 같다 🤯

var gears: [[Int]] = []

func solution() -> Int {
    for _ in 0..<4 {
        var gear: [Int] = []
        let gearString = readLine()!
        var index = gearString.startIndex
        while index != gearString.endIndex {
            let value = Int(String(gearString[index]))!
            gear.append(value)
            index = gearString.index(after: index)
        }
        gears.append(gear)
    }

    let rotateCount = Int(readLine()!)!
    var rotations = [(Int, Int)]()

    for _ in 0..<rotateCount {
        let rotateInfo = readLine()!.split(separator: " ").compactMap { Int($0) }
        let gearIndex = rotateInfo[0] - 1
        let rotateDirection = rotateInfo[1]
        rotations.append((gearIndex, rotateDirection))
    }

    while !rotations.isEmpty {
        let (gearIndex, rotateDirection) = rotations.removeFirst()
        let currentGear = gears[gearIndex]
        rotate(parentIndex: gearIndex, childIndex: gearIndex + 1, isCW: rotateDirection == 1)
        rotate(parentIndex: gearIndex, childIndex: gearIndex - 1, isCW: rotateDirection == 1)
        gears[gearIndex] = shift(currentGear, isCW: rotateDirection == 1)
    }

    var answer = 0
    var mul = 1

    for gear in gears {
        answer += gear[0] * mul
        mul *= 2
    }

    return answer
}

func rotate(parentIndex: Int, childIndex: Int, isCW: Bool) {
    if childIndex < 0 || childIndex > gears.count - 1 { return }

    let isParentLeft = parentIndex < childIndex
    let parentValue = isParentLeft ? gears[parentIndex][2] : gears[parentIndex][6]
    let childValue = isParentLeft ? gears[childIndex][6] : gears[childIndex][2]

    if parentValue == childValue { return }
    rotate(parentIndex: childIndex, childIndex: isParentLeft ? childIndex + 1 : childIndex - 1, isCW: !isCW)
    gears[childIndex] = shift(gears[childIndex], isCW: !isCW)
}

func shift(_ gear: [Int], isCW: Bool) -> [Int] {
    var gear = gear
    if isCW {
        gear.insert(gear[7], at: 0)
        gear.removeLast()
        return gear
    } else {
        gear.append(gear[0])
        gear.removeFirst()
        return gear
    }
}

print("answer: \(solution())")