-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay06.swift
68 lines (51 loc) · 1.92 KB
/
Day06.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import AOCCore
import Foundation
struct Day06: Day {
let title = "Guard Gallivant"
var rawInput: String?
func part1() throws -> Int {
let board = input().lines.map(\.characters)
let startPosition = board.findFirst(element: "^")!
return patrol(startPosition, .up, board).count
}
func part2() throws -> Int {
let board = input().lines.map(\.characters)
let startPosition = board.findFirst(element: "^")!
return patrol(startPosition, .up, board)
.count { isLoop(startPosition, .up, $0, board) }
}
private func isLoop(_ startPosition: Position, _ startDirection: Direction, _ obstacle: Position, _ board: [[Character]]) -> Bool {
var route: Set<Tuple<Position, Direction>> = []
var position = startPosition
var direction = startDirection
while board[position] != nil {
route.insert(.init(position, direction))
if board[position.offset(direction)] == "#" || position.offset(direction) == obstacle {
direction = direction.turn()
} else if !route.contains(.init(position.offset(direction), direction)) {
position = position.offset(direction)
} else {
return true
}
}
return false
}
private func patrol(_ startPosition: Position, _ startDirection: Direction, _ board: [[Character]]) -> Set<Position> {
var route: Set<Position> = []
var position = startPosition
var direction = startDirection
while board[position] != nil {
route.insert(position)
if board[position.offset(direction)] == "#" {
direction = direction.turn()
}
position = position.offset(direction)
}
return route
}
}
private extension Direction {
func turn() -> Direction {
.init(y: self.x, x: -self.y)
}
}