1+ const { dynamicSortMultiple } = require ( '../day-04/helpers' )
2+
13class Track {
24 constructor ( track ) {
35 this . layout = [ ]
46 this . carts = [ ]
57 this . cartDirections = [ '^' , '>' , 'v' , '<' ]
6- this . trackTurns = [ '\\' , '/' ]
7- this . trackTypes = this . trackTurns . concat ( [ '-' , '|' , '+' ] )
88 this . collision = false
99 this . frame = 0
10+ this . trackTurns = [ '\\' , '/' ]
11+ this . trackTypes = this . trackTurns . concat ( [ '-' , '|' , '+' ] )
1012 this . setLayout ( track )
1113 }
1214
@@ -16,21 +18,18 @@ class Track {
1618
1719 /**
1820 * Determines the next direction for a cart rotating at an intersection
19- * Order of rotations is left (counterclockwise), right (clockwise), straight
21+ * Order of rotations is left (counterclockwise), straigh, right (clockwise), straight
2022 * @private
2123 * @param {Object } cart the cart being turned
2224 * @returns {String } value of new direction
2325 */
2426 _intersect ( cart ) {
25- let r = 0
26- if ( typeof cart . lastIntersection === 'undefined' ) {
27- r = - 1
28- }
29- if ( cart . lastIntersection === - 1 ) {
30- r = 1
31- }
27+ let l = cart . lastIntersections
28+ let r = ( l [ 0 ] !== 0 ) ? 0 : l [ 1 ] * - 1
29+ // Track the intersections
30+ cart . lastIntersections . pop ( )
31+ cart . lastIntersections . splice ( 0 , 0 , r )
3232
33- cart . lastIntersection = r
3433 return this . cartDirections [ this . _roationDirection ( this . cartDirections . indexOf ( cart . direction ) , r ) ]
3534 }
3635
@@ -50,7 +49,6 @@ class Track {
5049 // (this.trackTurns.indexOf(s) === 0 && a === 'x') // horizontal turns counter-clockwise
5150 // (this.trackTurns.indexOf(s) === 1 && a === 'y') // vertical turns counter-clockwise
5251 ) ? 1 : - 1
53- console . log ( `${ s } for ${ a } is turning ${ r } ` )
5452 // Find the value of the new direction
5553 return this . cartDirections [ this . _roationDirection ( d , r ) ]
5654 }
@@ -63,17 +61,30 @@ class Track {
6361 * @returns {Number } Index of new direction
6462 */
6563 _roationDirection ( d , r ) {
66- console . log ( `rotating ${ d } , ${ r } ` )
6764 if ( d + r > this . cartDirections . length - 1 ) {
6865 return 0
6966 }
7067 if ( d + r < 0 ) {
7168 return this . cartDirections . length - 1
7269 }
73- console . log ( `new direction is ${ d + r } ` )
7470 return d + r
7571 }
7672
73+ /**
74+ * Advances the state of the entire layout
75+ */
76+ advance ( ) {
77+ this . frame ++
78+ this . carts . sort ( dynamicSortMultiple ( 'y' , 'x' ) ) . forEach ( ( c ) => {
79+ try {
80+ this . moveCart ( c )
81+ } catch ( err ) {
82+ console . error ( `Problem moving cart in frame ${ this . frame } ` )
83+ console . error ( err )
84+ }
85+ } )
86+ }
87+
7788 /**
7889 * Displays the current state of the track with the carts placed
7990 */
@@ -108,7 +119,8 @@ class Track {
108119 this . carts . push ( {
109120 x : idx ,
110121 y : idy ,
111- direction : x
122+ direction : x ,
123+ lastIntersections : [ 0 , 1 ] // Assume the first intersection the cart will turn left
112124 } )
113125 // Replace the cart on the track with a track segment
114126 // (Assuming cart initial states aren't on instersections)
@@ -124,7 +136,7 @@ class Track {
124136 * @param {* } x Number
125137 * @param {* } y Number
126138 */
127- getSegmentType ( x , y ) {
139+ getSegment ( x , y ) {
128140 return this . layout [ y ] [ x ]
129141 }
130142
@@ -139,22 +151,20 @@ class Track {
139151 const l = ( d % 3 === 0 ) ? - 1 : 1 // (+/-) distance of travel on the axis
140152 // move the cart
141153 cart [ a ] = cart [ a ] + l
142- const s = this . layout [ cart . y ] [ cart . x ] // Segment of track the cart is now on
154+ const s = this . getSegment ( cart . x , cart . y ) // Segment of track the cart is now on
143155
144156 // Make sure cart hasn't run off the rails
145157 if ( this . trackTypes . indexOf ( this . layout [ cart . y ] [ cart . x ] ) < 0 ) {
146- return new Error ( `cart ran off the track at ${ cart . x } , ${ cart . y } ` )
158+ throw new Error ( `cart ran off the track at ${ cart . x } , ${ cart . y } ` )
147159 }
148160 // Check for collision
149161 if ( this . _isCollision ( cart . x , cart . y ) ) {
150162 this . collision = { x : cart . x , y : cart . y }
151- return new Error ( `collision at ${ cart . x } , ${ cart . y } ` ) // Stop everything
163+ throw new Error ( `collision at ${ cart . x } , ${ cart . y } ` ) // Stop everything
152164 }
153165 // rotate the cart when entering a turn
154166 if ( this . _isTurn ( s ) ) {
155- console . log ( `Cart direction was ${ cart . direction } ` )
156167 cart . direction = this . _rotate ( s , a , d )
157- console . log ( `Cart direction is ${ cart . direction } ` )
158168 return
159169 }
160170 // rotate (or not) the cart when entering an intersection
0 commit comments