diff --git a/day06/d06p1.swift b/day06/d06p1.swift new file mode 100644 index 0000000..cb29e4b --- /dev/null +++ b/day06/d06p1.swift @@ -0,0 +1,80 @@ +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()) diff --git a/day06/d06p2.swift b/day06/d06p2.swift new file mode 100644 index 0000000..6d6eacf --- /dev/null +++ b/day06/d06p2.swift @@ -0,0 +1,112 @@ +import Foundation + +enum Direction : Hashable { + case n, s, e, w + func turnRight() -> Direction { + let map: [Direction: Direction] = [.n: .e, .s: .w, .e: .s, .w: .n] + return map[self]! + } + func asChar() -> Character { + let map: [Direction: Character] = [.n: "^", .s: "v", .e: ">", .w: "<"] + return map[self] ?? "?" + } +} + +struct GuardPos : Hashable { + let x: Int + let y: Int + let dir: Direction + func turnRight() -> GuardPos { + return GuardPos(x: x, y: y, dir: dir.turnRight()) + } + func move() -> GuardPos { + switch dir { + case Direction.n: + return GuardPos(x: x-1, y: y, dir: dir) + case Direction.s: + return GuardPos(x: x+1, y: y, dir: dir) + case Direction.e: + return GuardPos(x: x, y: y+1, dir: dir) + case Direction.w: + return GuardPos(x: x, y: y-1, dir: dir) + } + } +} + +struct Map { + var obst: [[Bool]] + var patrol: GuardPos + var visited: Set + var done = false + var looped = false + + func print() { + for (i, row) in obst.enumerated() { + Swift.print(String(row.enumerated().map { j, c in + (i == patrol.x && j == patrol.y) ? + patrol.dir.asChar() : (c ? "#" : ".") + })) + } + } + + mutating func step() { + let next = patrol.move() + if next.x < 0 || next.x >= obst.count + || next.y < 0 || next.y >= obst[0].count { + done = true + } else if obst[next.x][next.y] { + patrol = patrol.turnRight() + } else if visited.contains(next) { + looped = true + done = true + } else { + visited.insert(next) + patrol = next + } + } + + func addObst(x: Int, y: Int) -> Map? { + if obst[x][y] { + return nil + } + var newObst = obst + newObst[x][y] = true + return Map( + obst: newObst, patrol: patrol, + visited: visited, done: done, looped: looped + ) + } +} + +func readInput(_ filePath: String) throws -> Map { + let content = try String(contentsOfFile: filePath, encoding: .ascii) + let rows = content.split(separator: "\n").map(Array.init) + let (patrolX, patrolY) = rows.map { + $0.enumerated().compactMap { j, cell in cell == "^" ? j : nil } + }.enumerated().compactMap { $1.count > 0 ? ($0, $1[0]) : nil }[0] + let initPatrol = GuardPos(x: patrolX, y: patrolY, dir: Direction.n) + return Map( + obst: rows.map { $0.map { $0 == "#" } }, + patrol: initPatrol, + visited: [initPatrol] + ) +} + +var map = try readInput(CommandLine.arguments[1]) +var count = 0 +for x in 0..