-
[백준] 톱니바퀴 (14891번) Swift알고리즘 2021. 10. 12. 14:44
문제 내용
4개의 톱니바퀴가 존재한다.톱니는 S, N 극으로 존재하고회전하는 톱니 A 와 맞닿은 톱니 B 가 맞닿은 부분이 같은 극이라면 회전하지 않고서로 다른 극이라면 회전한다.모두 회전하고 난 후 톱니바퀴의 12시 방향으로 총 점수를 내라.1번 톱니의 12시 방향이 S 극이면 + 1, 2번은 + 2, 3번은 + 4, 4번은 + 8
전체 코드
import Foundation // 1. 톱니를 저장할 배열 var gears: [Gear] = [] // 2. 결과를 저장할 값 var result = 0 // 3. 4개의 톱니의 값을 얻어옴 for _ in 0..<4 { // 5. 얻은 톱니 정보를 let gear = readLine()!.map{ Int(String($0))! } // 6. 톱니 구조체를 생성하고 배열에 저장함 gears.append(Gear(info: gear)) } // 7. k 값을 받음 let k = Int(readLine()!)! for _ in 0..<k { let order = readLine()!.split { $0 == " " }.map { Int(String($0))! } // 8. 회전 정보를 담은 배열을 생성 var rotate: [Rotate] = Array(repeating: .none, count: 4) // 9. 1일 때는 시계 방향(right), -1 일 때는 반시계 방향(left)으로 회전 switch order[1] { // 시계 case 1: rotate[order[0] - 1] = .right // 반시계 case -1: rotate[order[0] - 1] = .left default: continue } // 10. 기준점 (order[0] - 1) 로 부터 왼쪽에 있는 톱니 if order[0] - 2 >= 0 { for i in stride(from: order[0] - 2, through: 0, by: -1) { // 11. 만약 현재 톱니의 우측 극과 // 현재 톱니 오른쪽에 있는 톱니의 왼쪽 극이 같으면 // 종료 if gears[i].right() == gears[i + 1].left() { break // 12. 그렇지 않으면 // 오른쪽에 있는 톱니 회전의 반대 방향으로 회전함 } else { switch rotate[i + 1] { case .right: rotate[i] = .left case .left: rotate[i] = .right case .none: break } } } } // 13. 기준점 (order[0] - 1) 로 부터 오른쪽에 있는 톱니 if order[0] < 4 { for i in order[0] ..< 4 { // 14. 만약 현재 톱니의 왼쪽 극과 // 현재 톱니 왼쪽에 있는 톱니의 오른쪽 극이 같으면 // 종료 if gears[i].left() == gears[i - 1].right() { break // 15. 그렇지 않으면 // 왼쪽에 있는 톱니 회전의 반대 방향으로 회전함 } else { switch rotate[i - 1] { case .right: rotate[i] = .left case .left: rotate[i] = .right case .none: break } } } } // 16. 저장한 회전 명령대로 회전 for i in 0..<4 { switch rotate[i] { case .right: gears[i].moveRight() case .left: gears[i].moveLeft() case .none: continue } } } // 17. 주어진 규칙대로 결과 값을 저장함 for i in 0..<4 { result += gears[i].top() * Int(pow(2.0, Double(i))) } print(result) // 18. 회전 열거형, (반시계, 시계, 회전 안함) enum Rotate { case left case right case none } // 19. 톱니 구조체 struct Gear { // 20. 톱니의 정보를 저장함 // 톱니 자체를 돌리는 것이 아닌 top, left, right 의 index 를 변경할 것이므로 let 으로 설정함 let info: [Int] // 21. top, right, left index. // 외부에서 따로 접근하지 않으므로 private 로 선언 private var topIndex: Int private var rightIndex: Int private var leftIndex: Int // 22. 초기화 init(info: [Int]) { self.info = info // 23. 주어진 배열에 맞게 index 를 초기화함 // 굳이 여기서 안하고 처음 생성할 때 이렇게 해도 될 듯 self.topIndex = 0 self.rightIndex = 2 self.leftIndex = 6 } // 23. 시계 방향 회전 mutating func moveRight() { // 24. 시계 방향으로 회전하므로 // index 가 전체적으로 -1 되어야 함 self.topIndex = topIndex - 1 == -1 ? 7 : topIndex - 1 self.rightIndex = rightIndex - 1 == -1 ? 7 : rightIndex - 1 self.leftIndex = leftIndex - 1 == -1 ? 7 : leftIndex - 1 } // 24. 반시계 방향 회전 mutating func moveLeft() { // 전체적으로 +1 self.topIndex = topIndex + 1 == 8 ? 0 : topIndex + 1 self.rightIndex = rightIndex + 1 == 8 ? 0 : rightIndex + 1 self.leftIndex = leftIndex + 1 == 8 ? 0 : leftIndex + 1 } // 25. top, right, left 값 출력 함수 func top() -> Int { return info[topIndex] } func right() -> Int { return info[rightIndex] } func left() -> Int { return info[leftIndex] } }
결론
구조체로 만들어서 풀면 확실히 코드가 길어지는 것 같은데
구조체 생성 외에는 코드가 짧아져서 재밌고
가독성이 높아져서 기분이 좋다.
실제 시험 볼 때는 이렇게 안하고 배열로 할 것 같다.
출처 : 백준 톱니바퀴
https://www.acmicpc.net/problem/14891'알고리즘' 카테고리의 다른 글
[프로그래머스] 피로도 (위클리 챌린지 12주차) Swift (0) 2021.10.25 [프로그래머스] 교점에 별 만들기 (위클리 챌린지 10주차) Swift (0) 2021.10.14 [백준] 구슬 탈출 2 (13460번) Swift (0) 2021.10.11 [백준] 주사위 굴리기 (14499번) Swift (0) 2021.10.10 [백준] 뱀 (3190번) Swift (0) 2021.10.09