Skip to content

Commit 02311a9

Browse files
fix(2018 day-13): array offset errors when multiple collisions in a single frame
1 parent 3a56d73 commit 02311a9

File tree

2 files changed

+50
-16
lines changed

2 files changed

+50
-16
lines changed

2018/day-13/tracks.js

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class Track {
1616
this.setLayout(track)
1717
}
1818

19-
_isCollision (x, y) { return (this.carts.filter((c) => c.x === x && c.y === y && c.ghost !== true).length > 1) }
19+
_isCollision (x, y) { return (this.carts.filter((c) => c.x === x && c.y === y).length > 1) }
2020
_isIntersection (s) { return s === '+' }
2121
_isTurn (s) { return this.trackTurns.indexOf(s) >= 0 }
2222

@@ -84,14 +84,16 @@ class Track {
8484
*/
8585
advance () {
8686
this.frame++
87-
this.carts.sort(dynamicSortMultiple('y', 'x')).forEach((c) => {
88-
try {
89-
this.moveCart(c)
90-
} catch (err) {
91-
console.error(`Problem moving cart in frame ${this.frame}`)
92-
console.error(err)
93-
}
94-
})
87+
while (this.carts.filter((c) => c.moved === this.frame).length < this.carts.length) {
88+
this.carts.filter((c) => c.moved !== this.frame).sort(dynamicSortMultiple('y', 'x')).forEach((c) => {
89+
try {
90+
this.moveCart(c)
91+
} catch (err) {
92+
console.error(`Problem moving cart in frame ${this.frame}`)
93+
console.error(err)
94+
}
95+
})
96+
}
9597
}
9698

9799
/**
@@ -101,7 +103,7 @@ class Track {
101103
let output = ''
102104
const layout = JSON.parse(JSON.stringify(this.layout)) // Deep copy
103105
// Include the carts
104-
this.carts.filter((c) => c.ghost !== true).forEach((cart) => {
106+
this.carts.forEach((cart) => {
105107
// If another cart is at the spot, draw a collision instead
106108
if (this.cartDirections.indexOf(layout[cart.y][cart.x]) >= 0) {
107109
layout[cart.y][cart.x] = 'X'
@@ -160,6 +162,7 @@ class Track {
160162
const l = (d % 3 === 0) ? -1 : 1 // (+/-) distance of travel on the axis
161163
// move the cart
162164
cart[a] = cart[a] + l
165+
cart.moved = this.frame
163166
const s = this.getSegment(cart.x, cart.y) // Segment of track the cart is now on
164167

165168
// Make sure cart hasn't run off the rails
@@ -169,16 +172,18 @@ class Track {
169172
// Check for collision
170173
if (this._isCollision(cart.x, cart.y)) {
171174
this.collision = { x: cart.x, y: cart.y }
175+
console.log(`Collision in frame ${this.frame}. removeCrashedCarts is ${this.options.removeCrashedCarts}`)
172176

173-
if (!this.options.removeCrashedCarts) {
177+
// Handle crashed carts
178+
if (this.options.removeCrashedCarts) {
179+
this.carts.filter((c) => c.x === cart.x && c.y === cart.y).forEach((c) => {
180+
this.carts.splice(this.carts.indexOf(c), 1)
181+
})
182+
} else {
174183
throw new Error(`collision at ${cart.x}, ${cart.y}`) // Stop everything
175184
}
176-
this.carts.filter((c) => c.x === cart.x && c.y === cart.y).forEach((c) => {
177-
c.ghost = true // Ghost carts are dead and no longer collide
178-
// we leave them in the array so that it doesn't mess up the loops
179-
// necessary to finish out each cycle tick
180-
})
181185
}
186+
182187
// rotate the cart when entering a turn
183188
if (this._isTurn(s)) {
184189
cart.direction = this._rotate(s, a, d)

2018/day-13/tracks.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,4 +201,33 @@ describe('--- Day 13: Mine Cart Madness ---', () => {
201201
})
202202
})
203203
})
204+
describe('Part 2:', () => {
205+
describe('new Track(layout, options)', () => {
206+
it('removes crashed carts when enabled', () => {
207+
const testData = `/>-<\\
208+
| |
209+
| /<+-\\
210+
| | | v
211+
\\>+</ |
212+
| ^
213+
\\<->/`
214+
const expected = `/---\\
215+
| |
216+
| /-+-\\
217+
| | | |
218+
\\-+-/ ^
219+
| |
220+
\\---/`.trim()
221+
const track = new Track(testData, { removeCrashedCarts: true })
222+
while (track.carts.length > 1) {
223+
track.advance()
224+
}
225+
const actual = track.display().trim()
226+
expect(actual).to.equal(expected)
227+
expect(track.carts[0].x).to.equal(6)
228+
expect(track.carts[0].y).to.equal(4)
229+
expect(track.frame).to.equal(3)
230+
})
231+
})
232+
})
204233
})

0 commit comments

Comments
 (0)