@@ -5,7 +5,10 @@ enum Direction: Int {
55 case East, South, West
66
77 func heading( ) -> Coord {
8- Coord . cross [ rawValue]
8+ if Coord . cross. indices. contains ( rawValue) {
9+ return Coord . cross [ rawValue]
10+ }
11+ fatalError ( )
912 }
1013
1114 static func fromHeading( coord: Coord ) -> Self {
@@ -18,7 +21,7 @@ enum Direction: Int {
1821
1922}
2023
21- struct Guard {
24+ struct Guard : Hashable {
2225 var pos : Coord
2326 var direction : Direction
2427
@@ -61,29 +64,28 @@ struct Day06: AdventDay {
6164 return ( locations, steps, obstacles)
6265 }
6366
64- func doesComeBack( step: Coord ) -> Bool {
65- var officer = Guard ( pos: grid. firstCoord ( of: " ^ " ) !, direction: . North)
66- var locations : [ Coord ] = [ Coord] ( )
67- while grid. includes ( coord: officer. pos) {
68- locations. append ( officer. pos)
67+ func doesComeBack( step: Coord , path: [ Coord ] . SubSequence, grid newGrid: Grid < Character > ) -> Bool {
68+ guard let officerPos = newGrid. firstCoord ( of: " ^ " ) else {
69+ return false
70+ }
71+ var officer = Guard ( pos: officerPos, direction: . North)
72+ var locations : [ Guard ] = [ Guard] ( )
73+ while newGrid. includes ( coord: officer. pos) {
74+ // check if we are going over our steps
75+ if locations. contains ( officer) {
76+ return true
77+ }
78+ locations. append ( officer)
6979
7080 // move the guard
7181 let nextPos = officer. pos + officer. direction. heading ( )
72- // behave like there is a real obstacle
73- if nextPos == step {
74- officer. direction = officer. direction. makeTurn ( )
75- } else {
76- if !grid. includes ( coord: nextPos) {
77- return false
78- }
79- if grid [ nextPos] == " # " {
80- // guard is blocked
81- officer. direction = officer. direction. makeTurn ( )
82- }
82+
83+ if !newGrid. includes ( coord: nextPos) {
84+ return false
8385 }
84- // check if we are going over our steps
85- if locations . contains ( [ officer . pos , nextPos ] ) {
86- return true
86+ if let nextChar = newGrid [ nextPos ] , nextChar == " # " {
87+ // guard is blocked
88+ officer . direction = officer . direction . makeTurn ( )
8789 }
8890 // move officer one step
8991 officer. pos = officer. pos + officer. direction. heading ( )
@@ -125,35 +127,25 @@ struct Day06: AdventDay {
125127 }
126128
127129 func part2( ) -> Int {
130+
131+ let ( _, steps, _) = guardPatrol ( )
128132 var count = 0
129- let ( _, steps, obstacles) = guardPatrol ( )
130-
131- var newObstacles : [ Coord ] = [ Coord] ( )
132- for (offset, candidates) in obstacles. windows ( ofCount: 4 ) . enumerated ( ) {
133- var c = Array ( candidates)
134- let wrappedOffset = offset % 4
135- if let coord = isAValidLoop ( wrappedOffset: wrappedOffset, c: c) {
136- count += 1
137- newObstacles. append ( coord)
138- }
139- if offset > 4 {
140-
141- // TODO: this is not right
142- for (_, elem) in obstacles [ 0 ... offset] . enumerated ( ) {
143- let wrappedOffset = offset % 4
144- c [ 3 ] = elem
145- if let coord = isAValidLoop ( wrappedOffset: wrappedOffset, c: c) {
146- if steps. contains ( coord) {
147- count += 1
148- newObstacles. append ( coord)
149- }
150- }
133+ let newSteps = steps. dropFirst ( )
134+ for (stepIdx, step) in newSteps. enumerated ( ) {
135+ var newGrid = grid
136+ if newGrid. includes ( coord: step) {
137+ newGrid. raw [ step. y] [ step. x] = " # "
138+ if doesComeBack ( step: step, path: newSteps [ 0 ..< stepIdx] , grid: newGrid) {
139+ count += 1
140+ print ( " found a loop at " , step)
151141 }
152-
153142 }
154143 }
155-
144+ // 125 -> too low
145+ // 200 -> too low
156146 // 115 -> too low
147+ // 1713 -> not the right answer
148+
157149 return count
158150 }
159151}
0 commit comments