Skip to content

Commit 513eac0

Browse files
feat(2018 day-13): recipe list and iterators of elves
1 parent 2218819 commit 513eac0

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

2018/day-14/recipes.js

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* Circular linked list of recipes
3+
*/
4+
class Recipes {
5+
constructor (recipe) {
6+
this.head = null
7+
this.tail = null
8+
this.length = 0
9+
this.addFirst(recipe)
10+
}
11+
12+
addFirst (recipe) {
13+
const newRecipe = { value: recipe }
14+
newRecipe.next = newRecipe
15+
newRecipe.prev = newRecipe
16+
this.head = newRecipe
17+
this.tail = newRecipe
18+
this.length++
19+
return this
20+
}
21+
22+
/**
23+
* Adds a recipe to the linked list
24+
* @param {Number} recipe value
25+
*/
26+
addRecipe (recipe) {
27+
const newRecipe = { value: recipe }
28+
newRecipe.next = this.tail // link new recipe to tail
29+
this.tail.prev = newRecipe
30+
newRecipe.prev = this.head // link new recipe to old head
31+
this.head.next = newRecipe
32+
this.head = newRecipe // make new recipe the new head
33+
this.length++
34+
return this.head
35+
}
36+
37+
/**
38+
* Scoring the current recipes means adding new recipies base on the score value
39+
* @param {Number} score of current recipe
40+
*/
41+
scoreRecipes (score) {
42+
score.toString().split('').forEach((recipe) => {
43+
this.addRecipe(parseInt(recipe))
44+
})
45+
}
46+
}
47+
48+
/**
49+
* Takes an array of numbers and totals the digits
50+
* @param
51+
*/
52+
const totalDigitsInArray = (arr) => {
53+
return arr.reduce(
54+
(acc, num) => acc + num.toString().split('')
55+
.reduce((sub, digit) => sub + parseInt(digit), 0), 0)
56+
}
57+
58+
/**
59+
* Loops the elves through the recipes list the specified number of times
60+
* @param {Array} elves list of elves
61+
* @param {LinkedList} recipes list of recipes
62+
* @param {Numbe} repeat count of desired iterations
63+
*/
64+
const loopRecipesForElves = (elves, recipes, repeat) => {
65+
for (let x = 1; x <= repeat; x++) {
66+
const score = totalDigitsInArray(elves.map((elf) => elf.value))
67+
recipes.scoreRecipes(score)
68+
elves.forEach((elf, idx) => {
69+
const distance = elf.value + 1
70+
for (let x = 0; x < distance; x++) {
71+
elf = elf.next
72+
}
73+
elves[idx] = elf
74+
})
75+
76+
console.log(recipes.head.value)
77+
}
78+
}
79+
80+
module.exports = {
81+
loopRecipesForElves,
82+
Recipes,
83+
totalDigitsInArray
84+
}

2018/day-14/recipes.test.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* eslint-env mocha */
2+
const expect = require('chai').expect
3+
const {
4+
loopRecipesForElves,
5+
Recipes,
6+
totalDigitsInArray
7+
} = require('./recipes')
8+
9+
describe('--- Day 14: Chocolate Charts ---', () => {
10+
describe('Part 1:', () => {
11+
describe('new Recipes()', () => {
12+
it('builds a linked list', () => {
13+
const recipes = new Recipes(0)
14+
for (let x = 1; x <= 5; x++) {
15+
recipes.addRecipe(x)
16+
}
17+
expect(recipes.length).to.equal(6)
18+
expect(recipes.head.value).to.equal(5)
19+
expect(recipes.tail.value).to.equal(0)
20+
expect(recipes.tail.prev).to.equal(recipes.head) // circular linked list for prev
21+
expect(recipes.head.next).to.equal(recipes.tail) // circular linked list for next
22+
})
23+
describe('scoreRecipes()', () => {
24+
it('adds new recipes based on the provided score', () => {
25+
const recipes = new Recipes(0)
26+
for (let x = 1; x <= 5; x++) {
27+
recipes.addRecipe(x)
28+
}
29+
recipes.scoreRecipes(37)
30+
expect(recipes.head.value).to.equal(7)
31+
expect(recipes.head.prev.value).to.equal(3)
32+
expect(recipes.head.prev.prev.value).to.equal(5)
33+
expect(recipes.head.next).to.equal(recipes.tail)
34+
})
35+
})
36+
})
37+
describe('totalDigitsInArray()', () => {
38+
it('calculates the total value of all the digits of all the numbers in the provided array', () => {
39+
const expected = 34
40+
const test = [1, 5, 13, 22, 3, 0, 971]
41+
const actual = totalDigitsInArray(test)
42+
expect(actual).to.equal(expected)
43+
})
44+
})
45+
describe('loopRecipeForEleves()', () => {
46+
it('loops through the recipe object for the specified elves the specified number of times', () => {
47+
const expected = '37101012451589167792' // list of recipe values in the last iteration of the example
48+
const elves = [3, 7]
49+
const recipes = new Recipes(elves[0])
50+
let actual = ''
51+
52+
elves.forEach((elf, idx) => {
53+
if (idx === 0) {
54+
elves[0] = recipes.head
55+
} else {
56+
elves[idx] = recipes.addRecipe(elf)
57+
}
58+
})
59+
60+
loopRecipesForElves(elves, recipes, 15)
61+
62+
let iterator = recipes.tail.next
63+
actual += recipes.tail.value.toString()
64+
while (iterator !== recipes.tail) {
65+
actual += iterator.value.toString()
66+
iterator = iterator.next
67+
}
68+
69+
expect(expected).to.equal(actual)
70+
})
71+
})
72+
})
73+
})

0 commit comments

Comments
 (0)