import Foundation enum Direction { case n, s, e, w mutating func turnRight() { switch self { case .n: self = .e case .s: self = .w case .e: self = .s case .w: self = .n } } func move(x: Int, y: Int) -> (Int, Int) { switch self { case .n: return (x-1, y) case .s: return (x+1, y) case .e: return (x, y+1) case .w: return (x, y-1) } } } struct Map { var floor: [[Character]] var guardX: Int var guardY: Int var guardDir = Direction.n var done = false func print() { for (i, row) in floor.enumerated() { Swift.print(String(row.enumerated().map { ($0 == self.guardY && i == self.guardX) ? "G" : $1 })) } } func countSteps() -> Int { return floor .map { $0.map { $0 == "^" ? 1 : 0 }.reduce(0, +) } .reduce(0, +) } mutating func step() { let (nextX, nextY) = guardDir.move(x: guardX, y: guardY) if nextX < 0 || nextX >= floor.count || nextY < 0 || nextY >= floor[0].count { done = true } else if floor[nextX][nextY] == "#" { guardDir.turnRight() } else { floor[nextX][nextY] = "^" (guardX, guardY) = (nextX, nextY) } } } func readInput(_ filePath: String) throws -> Map { let content = try String(contentsOfFile: filePath, encoding: .ascii) let rows = content.split(separator: "\n").map(Array.init) let (guardX, guardY) = rows.map { $0.enumerated().compactMap { j, cell in cell == "^" ? j : nil } }.enumerated().compactMap { $1.count > 0 ? ($0, $1[0]) : nil }[0] return Map(floor: rows, guardX: guardX, guardY: guardY) } var map = try readInput(CommandLine.arguments[1]) while !map.done { map.step() } map.print() print(map.countSteps())