From 2218819573270e21bb4082834f156599b92d72a0 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sat, 22 Dec 2018 14:24:20 -0800 Subject: [PATCH 1/3] chore: add index.js so it's easier to deubg with VSCode --- index.js | 1 + 1 file changed, 1 insertion(+) create mode 100644 index.js diff --git a/index.js b/index.js new file mode 100644 index 0000000..dcb17cf --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +require('./2018/day-14/solution') From 513eac0f568e47915ebd9baac0891bd21ded1120 Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sat, 22 Dec 2018 16:34:59 -0800 Subject: [PATCH 2/3] feat(2018 day-13): recipe list and iterators of elves --- 2018/day-14/recipes.js | 84 +++++++++++++++++++++++++++++++++++++ 2018/day-14/recipes.test.js | 73 ++++++++++++++++++++++++++++++++ 2 files changed, 157 insertions(+) create mode 100644 2018/day-14/recipes.js create mode 100644 2018/day-14/recipes.test.js diff --git a/2018/day-14/recipes.js b/2018/day-14/recipes.js new file mode 100644 index 0000000..5d90d67 --- /dev/null +++ b/2018/day-14/recipes.js @@ -0,0 +1,84 @@ +/** + * Circular linked list of recipes + */ +class Recipes { + constructor (recipe) { + this.head = null + this.tail = null + this.length = 0 + this.addFirst(recipe) + } + + addFirst (recipe) { + const newRecipe = { value: recipe } + newRecipe.next = newRecipe + newRecipe.prev = newRecipe + this.head = newRecipe + this.tail = newRecipe + this.length++ + return this + } + + /** + * Adds a recipe to the linked list + * @param {Number} recipe value + */ + addRecipe (recipe) { + const newRecipe = { value: recipe } + newRecipe.next = this.tail // link new recipe to tail + this.tail.prev = newRecipe + newRecipe.prev = this.head // link new recipe to old head + this.head.next = newRecipe + this.head = newRecipe // make new recipe the new head + this.length++ + return this.head + } + + /** + * Scoring the current recipes means adding new recipies base on the score value + * @param {Number} score of current recipe + */ + scoreRecipes (score) { + score.toString().split('').forEach((recipe) => { + this.addRecipe(parseInt(recipe)) + }) + } +} + +/** + * Takes an array of numbers and totals the digits + * @param + */ +const totalDigitsInArray = (arr) => { + return arr.reduce( + (acc, num) => acc + num.toString().split('') + .reduce((sub, digit) => sub + parseInt(digit), 0), 0) +} + +/** + * Loops the elves through the recipes list the specified number of times + * @param {Array} elves list of elves + * @param {LinkedList} recipes list of recipes + * @param {Numbe} repeat count of desired iterations + */ +const loopRecipesForElves = (elves, recipes, repeat) => { + for (let x = 1; x <= repeat; x++) { + const score = totalDigitsInArray(elves.map((elf) => elf.value)) + recipes.scoreRecipes(score) + elves.forEach((elf, idx) => { + const distance = elf.value + 1 + for (let x = 0; x < distance; x++) { + elf = elf.next + } + elves[idx] = elf + }) + + console.log(recipes.head.value) + } +} + +module.exports = { + loopRecipesForElves, + Recipes, + totalDigitsInArray +} diff --git a/2018/day-14/recipes.test.js b/2018/day-14/recipes.test.js new file mode 100644 index 0000000..8d903e4 --- /dev/null +++ b/2018/day-14/recipes.test.js @@ -0,0 +1,73 @@ +/* eslint-env mocha */ +const expect = require('chai').expect +const { + loopRecipesForElves, + Recipes, + totalDigitsInArray +} = require('./recipes') + +describe('--- Day 14: Chocolate Charts ---', () => { + describe('Part 1:', () => { + describe('new Recipes()', () => { + it('builds a linked list', () => { + const recipes = new Recipes(0) + for (let x = 1; x <= 5; x++) { + recipes.addRecipe(x) + } + expect(recipes.length).to.equal(6) + expect(recipes.head.value).to.equal(5) + expect(recipes.tail.value).to.equal(0) + expect(recipes.tail.prev).to.equal(recipes.head) // circular linked list for prev + expect(recipes.head.next).to.equal(recipes.tail) // circular linked list for next + }) + describe('scoreRecipes()', () => { + it('adds new recipes based on the provided score', () => { + const recipes = new Recipes(0) + for (let x = 1; x <= 5; x++) { + recipes.addRecipe(x) + } + recipes.scoreRecipes(37) + expect(recipes.head.value).to.equal(7) + expect(recipes.head.prev.value).to.equal(3) + expect(recipes.head.prev.prev.value).to.equal(5) + expect(recipes.head.next).to.equal(recipes.tail) + }) + }) + }) + describe('totalDigitsInArray()', () => { + it('calculates the total value of all the digits of all the numbers in the provided array', () => { + const expected = 34 + const test = [1, 5, 13, 22, 3, 0, 971] + const actual = totalDigitsInArray(test) + expect(actual).to.equal(expected) + }) + }) + describe('loopRecipeForEleves()', () => { + it('loops through the recipe object for the specified elves the specified number of times', () => { + const expected = '37101012451589167792' // list of recipe values in the last iteration of the example + const elves = [3, 7] + const recipes = new Recipes(elves[0]) + let actual = '' + + elves.forEach((elf, idx) => { + if (idx === 0) { + elves[0] = recipes.head + } else { + elves[idx] = recipes.addRecipe(elf) + } + }) + + loopRecipesForElves(elves, recipes, 15) + + let iterator = recipes.tail.next + actual += recipes.tail.value.toString() + while (iterator !== recipes.tail) { + actual += iterator.value.toString() + iterator = iterator.next + } + + expect(expected).to.equal(actual) + }) + }) + }) +}) From 59f02c9f76cabc56ef0c52ea4d69bf136500d56c Mon Sep 17 00:00:00 2001 From: Anthony McLin Date: Sat, 22 Dec 2018 17:44:18 -0800 Subject: [PATCH 3/3] feat(2013 day-14): solution to part 1, calculate X recipes after Y recipes --- 2018/day-14/recipes.js | 29 +++++++++++++++- 2018/day-14/recipes.test.js | 67 +++++++++++++++++++++++++++++++++++++ 2018/day-14/solution.js | 25 ++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 2018/day-14/solution.js diff --git a/2018/day-14/recipes.js b/2018/day-14/recipes.js index 5d90d67..230880b 100644 --- a/2018/day-14/recipes.js +++ b/2018/day-14/recipes.js @@ -72,12 +72,39 @@ const loopRecipesForElves = (elves, recipes, repeat) => { } elves[idx] = elf }) + } +} + +/** + * Determines the next X recipes after the elves have generated Y recipes + */ +const calculateXAfterY = (x, y, recipes, elves) => { + let iterator = recipes.head + while (recipes.length <= y) { + loopRecipesForElves(elves, recipes, 1) + } + + if (recipes.length === y + 1) { + iterator = recipes.head + } else { + // In case multidigit recipe results created more than Y + iterator = recipes.head.prev + } + + while (recipes.length < x + y) { + loopRecipesForElves(elves, recipes, 1) + } - console.log(recipes.head.value) + let result = '' + while (result.length < x) { + result += iterator.value.toString() + iterator = iterator.next } + return result } module.exports = { + calculateXAfterY, loopRecipesForElves, Recipes, totalDigitsInArray diff --git a/2018/day-14/recipes.test.js b/2018/day-14/recipes.test.js index 8d903e4..4b09598 100644 --- a/2018/day-14/recipes.test.js +++ b/2018/day-14/recipes.test.js @@ -1,6 +1,7 @@ /* eslint-env mocha */ const expect = require('chai').expect const { + calculateXAfterY, loopRecipesForElves, Recipes, totalDigitsInArray @@ -69,5 +70,71 @@ describe('--- Day 14: Chocolate Charts ---', () => { expect(expected).to.equal(actual) }) }) + describe('calculateXAfterY(x, y, recipe, elves)', () => { + it('predicts the next X results after the elves have executed Y', () => { + const elves = [3, 7] + const recipes = new Recipes(elves[0]) + let actual = '' + + elves.forEach((elf, idx) => { + if (idx === 0) { + elves[0] = recipes.head + } else { + elves[idx] = recipes.addRecipe(elf) + } + }) + + actual = calculateXAfterY(10, 9, recipes, elves) + expect(actual).to.equal('5158916779') + }) + it('predicts the next X results after the elves have executed Y', () => { + const elves = [3, 7] + const recipes = new Recipes(elves[0]) + let actual = '' + + elves.forEach((elf, idx) => { + if (idx === 0) { + elves[0] = recipes.head + } else { + elves[idx] = recipes.addRecipe(elf) + } + }) + + actual = calculateXAfterY(10, 5, recipes, elves) + expect(actual).to.equal('0124515891') + }) + it('predicts the next X results after the elves have executed Y', () => { + const elves = [3, 7] + const recipes = new Recipes(elves[0]) + let actual = '' + + elves.forEach((elf, idx) => { + if (idx === 0) { + elves[0] = recipes.head + } else { + elves[idx] = recipes.addRecipe(elf) + } + }) + + actual = calculateXAfterY(10, 18, recipes, elves) + expect(actual).to.equal('9251071085') + }) + it('predicts the next X results after the elves have executed Y', () => { + const elves = [3, 7] + const recipes = new Recipes(elves[0]) + let actual = '' + + elves.forEach((elf, idx) => { + if (idx === 0) { + elves[0] = recipes.head + } else { + elves[idx] = recipes.addRecipe(elf) + } + }) + + actual = calculateXAfterY(10, 2018, recipes, elves) + expect(actual).to.equal('5941429882') + }) + }) }) }) diff --git a/2018/day-14/solution.js b/2018/day-14/solution.js new file mode 100644 index 0000000..467d69e --- /dev/null +++ b/2018/day-14/solution.js @@ -0,0 +1,25 @@ +const { + calculateXAfterY, + Recipes +} = require('./recipes') + +const input = 540561 + +const elves = [3, 7] +const recipes = new Recipes(elves[0]) + +elves.forEach((elf, idx) => { + if (idx === 0) { + elves[0] = recipes.head + } else { + elves[idx] = recipes.addRecipe(elf) + } +}) + +const answer = calculateXAfterY(10, input, recipes, elves) +const answer2 = '' + +console.log(`-- Part 1 --`) +console.log(`Answer: ${answer}`) +console.log(`-- Part 2 --`) +console.log(`Answer: ${answer2}`) 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