Skip to content

Commit 05b7a9b

Browse files
feat(2018 day-14): eliminate the need to define elves when creating recipes
moves elves to be a property of recipes so a list of elves doesn't have to be manually defined Breaks calculateXAfterY(x, y, elves), use calculateXAfterY(x, y) instead Breaks findPattern('XXX', recipes, elves), use findPattern('XXX', recipes) instead Breakds loopRecipesForElves(elves, recipes, X), use loopRecipesForElves(recipes, 15) instead
1 parent b008964 commit 05b7a9b

File tree

3 files changed

+64
-44
lines changed

3 files changed

+64
-44
lines changed

2018/day-14/recipes.js

Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,37 @@
1+
class Elf {
2+
constructor (location) {
3+
this.location = location
4+
}
5+
6+
move (distance) {
7+
for (let x = 0; x < distance; x++) {
8+
this.location = this.location.next
9+
}
10+
}
11+
}
12+
113
/**
214
* Circular linked list of recipes
15+
* @param {Array} recipes list of initial recipe values
316
*/
417
class Recipes {
518
constructor (recipes) {
619
this.head = null
720
this.tail = null
821
this.length = 0
9-
this.addFirst(recipes[0])
22+
this.elves = []
23+
this._addFirst(recipes[0])
1024
for (let x = 1; x < recipes.length; x++) {
1125
this.addRecipe(recipes[x])
1226
}
27+
this.addElf(this.tail)
28+
this.addElf(this.head)
1329
}
1430

15-
addFirst (recipe) {
31+
/**
32+
* @private
33+
*/
34+
_addFirst (recipe) {
1635
const newRecipe = { value: recipe }
1736
newRecipe.next = newRecipe
1837
newRecipe.prev = newRecipe
@@ -22,6 +41,14 @@ class Recipes {
2241
return this
2342
}
2443

44+
/**
45+
* Adds an elf (location marker) to the linked list for easier iterative tracking
46+
* @param {*} location Item on the linked list that the elf is positioned at
47+
*/
48+
addElf (location) {
49+
this.elves.push(new Elf(location))
50+
}
51+
2552
/**
2653
* Adds a recipe to the linked list
2754
* @param {Number} recipe value
@@ -60,22 +87,18 @@ const totalDigitsInArray = (arr) => {
6087

6188
/**
6289
* Loops the elves through the recipes list the specified number of times
63-
* @param {Array} elves list of elves
6490
* @param {LinkedList} recipes list of recipes
65-
* @param {Numbe} repeat count of desired iterations
91+
* @param {Number} repeat count of desired iterations
6692
*/
67-
const loopRecipesForElves = (elves, recipes, repeat) => {
93+
const loopRecipesForElves = (recipes, repeat) => {
6894
let result = ''
6995
for (let x = 1; x <= repeat; x++) {
70-
const score = totalDigitsInArray(elves.map((elf) => elf.value))
96+
const score = totalDigitsInArray(recipes.elves.map((elf) => elf.location.value))
7197
result += score.toString()
7298
recipes.scoreRecipes(score)
73-
elves.forEach((elf, idx) => {
74-
const distance = elf.value + 1
75-
for (let x = 0; x < distance; x++) {
76-
elf = elf.next
77-
}
78-
elves[idx] = elf
99+
recipes.elves.forEach((elf, idx) => {
100+
const distance = elf.location.value + 1
101+
elf.move(distance)
79102
})
80103
}
81104
return result
@@ -84,21 +107,24 @@ const loopRecipesForElves = (elves, recipes, repeat) => {
84107
/**
85108
* Determines the next X recipes after the elves have generated Y recipes
86109
*/
87-
const calculateXAfterY = (x, y, recipes, elves) => {
110+
const calculateXAfterY = (x, y, recipes) => {
88111
let iterator = recipes.head
89-
while (recipes.length <= y) {
90-
loopRecipesForElves(elves, recipes, 1)
112+
let counter = recipes.length
113+
while (counter < y) {
114+
loopRecipesForElves(recipes, 1)
115+
counter = recipes.length
91116
}
117+
console.log(`${y} matches ${recipes.length}`)
92118

93-
if (recipes.length === y + 1) {
119+
if (recipes.length === y) {
94120
iterator = recipes.head
95-
} else {
121+
} else if (recipes.length > y) {
96122
// In case multidigit recipe results created more than Y
97123
iterator = recipes.head.prev
98124
}
99125

100126
while (recipes.length < x + y) {
101-
loopRecipesForElves(elves, recipes, 1)
127+
loopRecipesForElves(recipes, 1)
102128
}
103129

104130
let result = ''
@@ -113,15 +139,14 @@ const calculateXAfterY = (x, y, recipes, elves) => {
113139
* Counts how many recipes are to the left of the specified pattern
114140
* @param {String} pattern to search for
115141
* @param {LinkedList} recipes recipe list
116-
* @param {Array} elves doing the work
117142
* @param {Number} bufferSize bucket size to search. Tuning bucket size can improve speed but may risk missing match if the match crosses buckets.
118143
*/
119-
const findPattern = (pattern, recipes, elves, bufferSize) => {
144+
const findPattern = (pattern, recipes, bufferSize) => {
120145
bufferSize = bufferSize || 101
121146
let matched = false
122147
let position = recipes.length
123148
while (matched !== true) {
124-
let haystack = loopRecipesForElves(elves, recipes, bufferSize)
149+
let haystack = loopRecipesForElves(recipes, bufferSize)
125150
let offset = haystack.indexOf(pattern)
126151
if (offset > -1) {
127152
position += offset

2018/day-14/recipes.test.js

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,9 @@ const {
1010

1111
describe('--- Day 14: Chocolate Charts ---', () => {
1212
let recipes
13-
let elves
1413
describe('Part 1:', () => {
1514
beforeEach(() => {
16-
elves = [3, 7]
17-
recipes = new Recipes(elves)
18-
elves[0] = recipes.tail
19-
elves[1] = recipes.head
15+
recipes = new Recipes([3, 7])
2016
})
2117
describe('new Recipes()', () => {
2218
it('builds a linked list', () => {
@@ -54,12 +50,10 @@ describe('--- Day 14: Chocolate Charts ---', () => {
5450
describe('loopRecipeForEleves()', () => {
5551
it('loops through the recipe object for the specified elves the specified number of times', () => {
5652
const expected = '37101012451589167792' // list of recipe values in the last iteration of the example
57-
let actual = ''
58-
59-
loopRecipesForElves(elves, recipes, 15)
6053

54+
loopRecipesForElves(recipes, 15)
55+
let actual = recipes.tail.value.toString()
6156
let iterator = recipes.tail.next
62-
actual += recipes.tail.value.toString()
6357
while (iterator !== recipes.tail) {
6458
actual += iterator.value.toString()
6559
iterator = iterator.next
@@ -68,45 +62,49 @@ describe('--- Day 14: Chocolate Charts ---', () => {
6862
expect(expected).to.equal(actual)
6963
})
7064
})
71-
describe('calculateXAfterY(x, y, recipe, elves)', () => {
65+
describe('calculateXAfterY(x, y, recipe)', () => {
7266
it('predicts the next X results after the elves have executed Y', () => {
73-
let actual = calculateXAfterY(10, 9, recipes, elves)
67+
let actual = calculateXAfterY(10, 9, recipes)
7468
expect(actual).to.equal('5158916779')
7569
})
7670
it('predicts the next X results after the elves have executed Y', () => {
77-
const actual = calculateXAfterY(10, 5, recipes, elves)
71+
const actual = calculateXAfterY(10, 5, recipes)
7872
expect(actual).to.equal('0124515891')
7973
})
8074
it('predicts the next X results after the elves have executed Y', () => {
81-
const actual = calculateXAfterY(10, 18, recipes, elves)
75+
const actual = calculateXAfterY(10, 18, recipes)
8276
expect(actual).to.equal('9251071085')
8377
})
8478
it('predicts the next X results after the elves have executed Y', () => {
85-
const actual = calculateXAfterY(10, 2018, recipes, elves)
79+
const actual = calculateXAfterY(10, 2018, recipes)
8680
expect(actual).to.equal('5941429882')
8781
})
82+
it('positions results correctly if X triggers 2 recipes being added', () => {
83+
let actual = calculateXAfterY(3, 15, recipes)
84+
expect(actual).to.equal('677')
85+
})
8886
})
8987
describe('findPattern()', () => {
9088
it('counts the number of recipes to the left of the specified pattern', () => {
91-
const actual = findPattern('51589', recipes, elves)
89+
const actual = findPattern('51589', recipes)
9290
expect(actual).to.equal(9)
9391
})
9492
})
9593
describe('findPattern()', () => {
9694
it('counts the number of recipes to the left of the specified pattern', () => {
97-
const actual = findPattern('01245', recipes, elves)
95+
const actual = findPattern('01245', recipes)
9896
expect(actual).to.equal(5)
9997
})
10098
})
10199
describe('findPattern()', () => {
102100
it('counts the number of recipes to the left of the specified pattern', () => {
103-
const actual = findPattern('92510', recipes, elves)
101+
const actual = findPattern('92510', recipes)
104102
expect(actual).to.equal(18)
105103
})
106104
})
107105
describe('findPattern()', () => {
108106
it('counts the number of recipes to the left of the specified pattern', () => {
109-
const actual = findPattern('59414', recipes, elves)
107+
const actual = findPattern('59414', recipes)
110108
expect(actual).to.equal(2018)
111109
})
112110
})

2018/day-14/solution.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,9 @@ const {
66

77
const input = 540561
88

9-
let elves = [3, 7]
10-
let recipes = new Recipes(elves)
11-
elves[0] = recipes.tail
12-
elves[1] = recipes.head
9+
let recipes = new Recipes([3, 7])
1310

14-
const answer = calculateXAfterY(10, input, recipes, elves)
11+
const answer = calculateXAfterY(10, input, recipes)
1512

1613
console.log(`-- Part 1 --`)
1714
console.log(`Answer: ${answer}`)

0 commit comments

Comments
 (0)
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