From 3a56d737ea268186f735e283841efc845ec2a1f7 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Fri, 21 Dec 2018 15:39:51 -0800 Subject: [PATCH 1/3] feature(2018 day-13): support removing carts when crashed --- 2018/day-13/solution.js | 13 ++++++++++++- 2018/day-13/tracks.js | 22 +++++++++++++++++----- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/2018/day-13/solution.js b/2018/day-13/solution.js index c6a5aab..eb0466a 100644 --- a/2018/day-13/solution.js +++ b/2018/day-13/solution.js @@ -13,7 +13,18 @@ const init = (data) => { const answer = [track.collision.x, track.collision.y] // console.log(`Track state:`) // console.log(track.display()) - const answer2 = '' + + // Execute again, this time, removing crashed carts instead of stopping + const track2 = new Track(data, { removeCrashedCarts: true }) + while (track2.carts.filter((c) => c.ghost !== true).length > 1 && track2.frame < 10) { + track2.advance() + } + + console.log(`Only one cart remaining at frame ${track2.frame}`) + // console.log(track2.display()) + const remaining = track2.carts.find((c) => c.ghost !== true) + const answer2 = [remaining.x, remaining.y] + console.log(`-- Part 1 --`) console.log(`Answer: ${answer}`) console.log(`-- Part 2 --`) diff --git a/2018/day-13/tracks.js b/2018/day-13/tracks.js index afe89f1..ad22b28 100644 --- a/2018/day-13/tracks.js +++ b/2018/day-13/tracks.js @@ -1,19 +1,22 @@ const { dynamicSortMultiple } = require('../day-04/helpers') class Track { - constructor (track) { + constructor (track, options) { this.layout = [] this.carts = [] this.cartDirections = ['^', '>', 'v', '<'] this.collision = false this.frame = 0 this.interSectionOrder = [-1, 0, 1] + this.options = options || { + removeCrashedCarts: false + } this.trackTurns = ['\\', '/'] this.trackTypes = this.trackTurns.concat(['-', '|', '+']) this.setLayout(track) } - _isCollision (x, y) { return (this.carts.filter((c) => c.x === x && c.y === y).length > 1) } + _isCollision (x, y) { return (this.carts.filter((c) => c.x === x && c.y === y && c.ghost !== true).length > 1) } _isIntersection (s) { return s === '+' } _isTurn (s) { return this.trackTurns.indexOf(s) >= 0 } @@ -98,7 +101,7 @@ class Track { let output = '' const layout = JSON.parse(JSON.stringify(this.layout)) // Deep copy // Include the carts - this.carts.forEach((cart) => { + this.carts.filter((c) => c.ghost !== true).forEach((cart) => { // If another cart is at the spot, draw a collision instead if (this.cartDirections.indexOf(layout[cart.y][cart.x]) >= 0) { layout[cart.y][cart.x] = 'X' @@ -166,17 +169,26 @@ class Track { // Check for collision if (this._isCollision(cart.x, cart.y)) { this.collision = { x: cart.x, y: cart.y } - throw new Error(`collision at ${cart.x}, ${cart.y}`) // Stop everything + + if (!this.options.removeCrashedCarts) { + throw new Error(`collision at ${cart.x}, ${cart.y}`) // Stop everything + } + this.carts.filter((c) => c.x === cart.x && c.y === cart.y).forEach((c) => { + c.ghost = true // Ghost carts are dead and no longer collide + // we leave them in the array so that it doesn't mess up the loops + // necessary to finish out each cycle tick + }) } // rotate the cart when entering a turn if (this._isTurn(s)) { cart.direction = this._rotate(s, a, d) - return + return true } // rotate (or not) the cart when entering an intersection if (this._isIntersection(s)) { cart.direction = this._intersect(cart) } + return true } /** From 02311a9f9ec7a077cf78dbe9c027c060a5f0f29d Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Fri, 21 Dec 2018 16:34:48 -0800 Subject: [PATCH 2/3] fix(2018 day-13): array offset errors when multiple collisions in a single frame --- 2018/day-13/tracks.js | 37 +++++++++++++++++++++---------------- 2018/day-13/tracks.test.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 16 deletions(-) diff --git a/2018/day-13/tracks.js b/2018/day-13/tracks.js index ad22b28..ea16d98 100644 --- a/2018/day-13/tracks.js +++ b/2018/day-13/tracks.js @@ -16,7 +16,7 @@ class Track { this.setLayout(track) } - _isCollision (x, y) { return (this.carts.filter((c) => c.x === x && c.y === y && c.ghost !== true).length > 1) } + _isCollision (x, y) { return (this.carts.filter((c) => c.x === x && c.y === y).length > 1) } _isIntersection (s) { return s === '+' } _isTurn (s) { return this.trackTurns.indexOf(s) >= 0 } @@ -84,14 +84,16 @@ class Track { */ advance () { this.frame++ - this.carts.sort(dynamicSortMultiple('y', 'x')).forEach((c) => { - try { - this.moveCart(c) - } catch (err) { - console.error(`Problem moving cart in frame ${this.frame}`) - console.error(err) - } - }) + while (this.carts.filter((c) => c.moved === this.frame).length < this.carts.length) { + this.carts.filter((c) => c.moved !== this.frame).sort(dynamicSortMultiple('y', 'x')).forEach((c) => { + try { + this.moveCart(c) + } catch (err) { + console.error(`Problem moving cart in frame ${this.frame}`) + console.error(err) + } + }) + } } /** @@ -101,7 +103,7 @@ class Track { let output = '' const layout = JSON.parse(JSON.stringify(this.layout)) // Deep copy // Include the carts - this.carts.filter((c) => c.ghost !== true).forEach((cart) => { + this.carts.forEach((cart) => { // If another cart is at the spot, draw a collision instead if (this.cartDirections.indexOf(layout[cart.y][cart.x]) >= 0) { layout[cart.y][cart.x] = 'X' @@ -160,6 +162,7 @@ class Track { const l = (d % 3 === 0) ? -1 : 1 // (+/-) distance of travel on the axis // move the cart cart[a] = cart[a] + l + cart.moved = this.frame const s = this.getSegment(cart.x, cart.y) // Segment of track the cart is now on // Make sure cart hasn't run off the rails @@ -169,16 +172,18 @@ class Track { // Check for collision if (this._isCollision(cart.x, cart.y)) { this.collision = { x: cart.x, y: cart.y } + console.log(`Collision in frame ${this.frame}. removeCrashedCarts is ${this.options.removeCrashedCarts}`) - if (!this.options.removeCrashedCarts) { + // Handle crashed carts + if (this.options.removeCrashedCarts) { + this.carts.filter((c) => c.x === cart.x && c.y === cart.y).forEach((c) => { + this.carts.splice(this.carts.indexOf(c), 1) + }) + } else { throw new Error(`collision at ${cart.x}, ${cart.y}`) // Stop everything } - this.carts.filter((c) => c.x === cart.x && c.y === cart.y).forEach((c) => { - c.ghost = true // Ghost carts are dead and no longer collide - // we leave them in the array so that it doesn't mess up the loops - // necessary to finish out each cycle tick - }) } + // rotate the cart when entering a turn if (this._isTurn(s)) { cart.direction = this._rotate(s, a, d) diff --git a/2018/day-13/tracks.test.js b/2018/day-13/tracks.test.js index 7c9ff5c..f143593 100644 --- a/2018/day-13/tracks.test.js +++ b/2018/day-13/tracks.test.js @@ -201,4 +201,33 @@ describe('--- Day 13: Mine Cart Madness ---', () => { }) }) }) + describe('Part 2:', () => { + describe('new Track(layout, options)', () => { + it('removes crashed carts when enabled', () => { + const testData = `/>-<\\ +| | +| /<+-\\ +| | | v +\\>+/` + const expected = `/---\\ +| | +| /-+-\\ +| | | | +\\-+-/ ^ + | | + \\---/`.trim() + const track = new Track(testData, { removeCrashedCarts: true }) + while (track.carts.length > 1) { + track.advance() + } + const actual = track.display().trim() + expect(actual).to.equal(expected) + expect(track.carts[0].x).to.equal(6) + expect(track.carts[0].y).to.equal(4) + expect(track.frame).to.equal(3) + }) + }) + }) }) From 578645a0cc80c20acfa5f30f21e16e596b9b1cba Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Fri, 21 Dec 2018 16:35:58 -0800 Subject: [PATCH 3/3] feat(2018 day-13): solution for day 13 part 2 --- 2018/day-13/solution.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/2018/day-13/solution.js b/2018/day-13/solution.js index eb0466a..5e85716 100644 --- a/2018/day-13/solution.js +++ b/2018/day-13/solution.js @@ -16,13 +16,14 @@ const init = (data) => { // Execute again, this time, removing crashed carts instead of stopping const track2 = new Track(data, { removeCrashedCarts: true }) - while (track2.carts.filter((c) => c.ghost !== true).length > 1 && track2.frame < 10) { + while (track2.carts.length > 1) { track2.advance() } - console.log(`Only one cart remaining at frame ${track2.frame}`) // console.log(track2.display()) - const remaining = track2.carts.find((c) => c.ghost !== true) + const remaining = track2.carts[0] + // console.log(`${remaining.length} cart(s) of ${track2.carts.length} remaining at frame ${track2.frame}`) + // console.log(remaining) const answer2 = [remaining.x, remaining.y] console.log(`-- Part 1 --`) pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy