Skip to content

Commit

Permalink
day 9, part 2
Browse files Browse the repository at this point in the history
  • Loading branch information
coderbyheart committed Dec 15, 2018
1 parent 5bf4697 commit d039451
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 34 deletions.
48 changes: 32 additions & 16 deletions day9.js
@@ -1,6 +1,5 @@
class Circle {
constructor (numPlayers) {
this.marbles = []
this.numPlayers = numPlayers
this.scores = {}
for (let i = 0; i < numPlayers; i++) {
Expand All @@ -10,35 +9,52 @@ class Circle {

placeMarble () {
if (this.currentMarble === undefined) {
this.currentMarble = 0
const marble = {n: 0}
marble.next = marble
marble.prev = marble
this.currentMarble = marble
this.firstMarble = marble
this.placements = 0
this.marbles.push(this.currentMarble)
} else {
const marbleToBePlaced = ++this.placements
const marbleToBePlacedValue = ++this.placements
const currentPlayer = this.placements % this.numPlayers
if (marbleToBePlaced % 23 === 0) {
if (marbleToBePlacedValue % 23 === 0) {
// However, if the marble that is about to be placed has a number which is a multiple of 23, something entirely different happens:
// First, the current player keeps the marble they would have placed, adding it to their score.
this.scores[currentPlayer] += marbleToBePlaced
this.scores[currentPlayer] += marbleToBePlacedValue
// In addition, the marble 7 marbles counter-clockwise from the current marble is removed from the circle
let idx = (this.marbles.indexOf(this.currentMarble) - 7) % this.marbles.length
// Correct negative offset
if (idx < 0) {
idx = this.marbles.length + idx
let marbleToRemove = this.currentMarble
for (let i = 0; i < 7; i++) {
marbleToRemove = marbleToRemove.prev
}
marbleToRemove.prev.next = marbleToRemove.next
// The marble located immediately clockwise of the marble that was removed becomes the new current marble.
this.currentMarble = this.marbles[(idx + 1) % this.marbles.length]
this.currentMarble = marbleToRemove.next
// and also added to the current player's score.
this.scores[currentPlayer] += this.marbles[idx]
this.marbles.splice(idx, 1)
this.scores[currentPlayer] += marbleToRemove.n
} else {
const idx = (this.marbles.indexOf(this.currentMarble) + 1) % this.marbles.length
this.marbles.splice(idx + 1, 0, marbleToBePlaced)
this.currentMarble = marbleToBePlaced
const marble = {
n: marbleToBePlacedValue,
prev: this.currentMarble.next,
next: this.currentMarble.next.next
}
this.currentMarble.next.next = marble
this.currentMarble.next.next.next.prev = marble
this.currentMarble = marble
}
}
}

marbles () {
const marbles = []
let marble = this.firstMarble
do {
marbles.push(marble.n)
marble = marble.next
} while (marble !== this.firstMarble)
return marbles
}

winningScore () {
return Object.keys(this.scores).reduce((max, player) => this.scores[player] > max ? this.scores[player] : max, 0)
}
Expand Down
37 changes: 19 additions & 18 deletions day9.spec.js
Expand Up @@ -9,41 +9,41 @@ describe('marble mania', () => {
it('should calculate the winning score', () => {
const c = new Circle(5)
c.placeMarble()
expect(c.currentMarble).toEqual(0)
expect(c.marbles).toEqual([0])
expect(c.currentMarble.n).toEqual(0)
expect(c.marbles()).toEqual([0])
c.placeMarble()
expect(c.currentMarble).toEqual(1)
expect(c.marbles).toEqual([0, 1])
expect(c.currentMarble.n).toEqual(1)
expect(c.marbles()).toEqual([0, 1])
c.placeMarble()
expect(c.currentMarble).toEqual(2)
expect(c.marbles).toEqual([0, 2, 1])
expect(c.currentMarble.n).toEqual(2)
expect(c.marbles()).toEqual([0, 2, 1])
c.placeMarble()
expect(c.currentMarble).toEqual(3)
expect(c.marbles).toEqual([0, 2, 1, 3])
expect(c.currentMarble.n).toEqual(3)
expect(c.marbles()).toEqual([0, 2, 1, 3])
c.placeMarble()
expect(c.currentMarble).toEqual(4)
expect(c.marbles).toEqual([0, 4, 2, 1, 3])
expect(c.currentMarble.n).toEqual(4)
expect(c.marbles()).toEqual([0, 4, 2, 1, 3])
for (let i = 0; i < 18; i++) {
c.placeMarble()
}
expect(c.currentMarble).toEqual(22)
expect(c.marbles).toEqual([
expect(c.currentMarble.n).toEqual(22)
expect(c.marbles()).toEqual([
0, 16, 8, 17, 4, 18, 9, 19, 2, 20, 10, 21, 5, 22, 11, 1, 12, 6, 13, 3, 14, 7, 15
])
// Rule 23
c.placeMarble()
expect(c.currentMarble).toEqual(19)
expect(c.marbles).toEqual([
expect(c.currentMarble.n).toEqual(19)
expect(c.marbles()).toEqual([
0, 16, 8, 17, 4, 18, 19, 2, 20, 10, 21, 5, 22, 11, 1, 12, 6, 13, 3, 14, 7, 15
])
c.placeMarble()
expect(c.currentMarble).toEqual(24)
expect(c.marbles).toEqual([
expect(c.currentMarble.n).toEqual(24)
expect(c.marbles()).toEqual([
0, 16, 8, 17, 4, 18, 19, 2, 24, 20, 10, 21, 5, 22, 11, 1, 12, 6, 13, 3, 14, 7, 15
])
c.placeMarble()
expect(c.currentMarble).toEqual(25)
expect(c.marbles).toEqual([
expect(c.currentMarble.n).toEqual(25)
expect(c.marbles()).toEqual([
0, 16, 8, 17, 4, 18, 19, 2, 24, 20, 25, 10, 21, 5, 22, 11, 1, 12, 6, 13, 3, 14, 7, 15
])
expect(c.winningScore()).toEqual(32)
Expand All @@ -57,5 +57,6 @@ describe('marble mania', () => {
})
it('should calculate the puzzle', () => {
expect(getWinningScore(413, 71082)).toEqual(416424)
expect(getWinningScore(413, 7108200)).toEqual(3498287922)
})
})

0 comments on commit d039451

Please sign in to comment.