├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── day-1-chronal-calibration ├── README.md ├── calibrate-two.js ├── calibrate.js └── test.js ├── day-2-inventory-management-system ├── README.md ├── checksum-two.js ├── checksum.js └── test.js ├── day-3-no-matter-how-you-slice-it ├── README.md ├── non-overlap.js ├── overlap.js └── test.js ├── day-4-repose-record ├── README.md ├── sleepy-guard-two.js ├── sleepy-guard.js └── test.js ├── day-5-alchemical-reduction ├── README.md ├── polymer-two.js ├── polymer.js └── test.js ├── day-6-chronal-coordinates ├── README.md ├── manhattan-two.js ├── manhattan.js └── test.js ├── day-7-the-sum-of-its-parts ├── README.md ├── steps-two.js ├── steps.js └── test.js ├── day-8-memory-maneuver ├── README.md ├── metadata-two.js ├── metadata.js └── test.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | scratchpad.js -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "8" -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Adrienne Tacke 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # advent-of-code-2018 2 | [![Build Status](https://travis-ci.org/adriennetacke/advent-of-code-2018.svg?branch=master)](https://travis-ci.org/adriennetacke/advent-of-code-2018) [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT) 3 | 4 | Advent of Code 2018 Solutions - Adrienne Style 5 | 6 | ## What is Advent of Code? 7 | [Advent of Code](http://adventofcode.com) is an online event created by [Eric Wastl](https://twitter.com/ericwastl). Each year, starting on Dec 1st, an advent calendar of small programming puzzles are unlocked once a day at midnight (EST/UTC-5). Developers of all skill sets are encouraged to solve them in any programming language they choose! 8 | 9 | ## Advent of Code 2018 Story 10 | "We've detected some temporal anomalies," one of Santa's Elves at the Temporal Anomaly Research and Detection Instrument Station tells you. She sounded pretty worried when she called you down here. "At 500-year intervals into the past, someone has been changing Santa's history!" 11 | 12 | "The good news is that the changes won't propagate to our time stream for another 25 days, and we have a device" - she attaches something to your wrist - "that will let you fix the changes with no such propagation delay. It's configured to send you 500 years further into the past every few days; that was the best we could do on such short notice." 13 | 14 | "The bad news is that we are detecting roughly fifty anomalies throughout time; the device will indicate fixed anomalies with stars. The other bad news is that we only have one device and you're the best person for the job! Good lu--" She taps a button on the device and you suddenly feel like you're falling. To save Christmas, you need to get all fifty stars by December 25th. 15 | 16 | Collect stars by solving puzzles. Two puzzles will be made available on each day in the advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! 17 | 18 | ## Days 19 | 20 | | Day | Part One | Part Two | 21 | |---|:---:|:---:| 22 | |✔️ [Day 1: Chronal Calibration](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-1-chronal-calibration) | ⭐️ | ⭐️ | 23 | |✔️ [Day 2: Inventory Management System](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-2-inventory-management-system) | ⭐️ | ⭐️ | 24 | |✔️ [Day 3: Inventory Management System](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-3-no-matter-how-you-slice-it) | ⭐️ | ⭐ | 25 | |✔️ [Day 4: Repose Record](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-4-repose-record) | ⭐ | ⭐ | 26 | |✔️ [Day 5: Alchemical Reduction](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-5-alchemical-reduction) | ⭐ | ⭐ | 27 | |✔️ [Day 6: Chronal Coordinates](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-6-chronal-coordinates) | ⭐ | ⭐ | 28 | | [Day 7: The Sum of Its Parts](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-7-the-sum-of-its-parts) | ⭐ | 🕗 In progress | 29 | | [Day 8: Memory Maneuver ](https://github.com/adriennetacke/advent-of-code-2018/tree/master/day-8-memory-maneuver) | 🕗 In progress | 😅 Not Started | 30 | 31 | 32 | ## Running Tests 33 | 34 | Each day contains its own set of tests. To run them type `npm test`. 35 | 36 | ## Let's connect: 37 | `@adrienne.tacke` 38 | 39 | [Instagram](https://www.instagram.com/adrienne.tacke/) 40 | | 41 | [Medium](https://medium.com/@adrienne.tacke) 42 | | 43 | [Twitter](https://twitter.com/adriennetacke) 44 | -------------------------------------------------------------------------------- /day-1-chronal-calibration/README.md: -------------------------------------------------------------------------------- 1 | # Day 1 - Chronal Calibration: 2 | 3 | ## Part One 4 | "We've detected some temporal anomalies," one of Santa's Elves at the Temporal Anomaly Research and Detection Instrument Station tells you. She sounded pretty worried when she called you down here. "At 500-year intervals into the past, someone has been changing Santa's history!" 5 | 6 | "The good news is that the changes won't propagate to our time stream for another 25 days, and we have a device" - she attaches something to your wrist - "that will let you fix the changes with no such propagation delay. It's configured to send you 500 years further into the past every few days; that was the best we could do on such short notice." 7 | 8 | "The bad news is that we are detecting roughly fifty anomalies throughout time; the device will indicate fixed anomalies with stars. The other bad news is that we only have one device and you're the best person for the job! Good lu--" She taps a button on the device and you suddenly feel like you're falling. To save Christmas, you need to get all fifty stars by December 25th. 9 | 10 | Collect stars by solving puzzles. Two puzzles will be made available on each day in the advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck! 11 | 12 | After feeling like you've been falling for a few minutes, you look at the device's tiny screen. "Error: Device must be calibrated before first use. Frequency drift detected. Cannot maintain destination lock." Below the message, the device shows a sequence of changes in frequency (your puzzle input). A value like +6 means the current frequency increases by 6; a value like -3 means the current frequency decreases by 3. 13 | 14 | For example, if the device displays frequency changes of +1, -2, +3, +1, then starting from a frequency of zero, the following changes would occur: 15 | 16 | Current frequency 0, change of +1; resulting frequency 1. 17 | Current frequency 1, change of -2; resulting frequency -1. 18 | Current frequency -1, change of +3; resulting frequency 2. 19 | Current frequency 2, change of +1; resulting frequency 3. 20 | In this example, the resulting frequency is 3. 21 | 22 | Here are other example situations: 23 | 24 | +1, +1, +1 results in 3 25 | +1, +1, -2 results in 0 26 | -1, -2, -3 results in -6 27 | Starting with a frequency of zero, what is the resulting frequency after all of the changes in frequency have been applied? 28 | 29 | ## Part Two 30 | You notice that the device repeats the same frequency change list over and over. To calibrate the device, you need to find the first frequency it reaches twice. 31 | 32 | For example, using the same list of changes above, the device would loop as follows: 33 | 34 | Current frequency 0, change of +1; resulting frequency 1. 35 | Current frequency 1, change of -2; resulting frequency -1. 36 | Current frequency -1, change of +3; resulting frequency 2. 37 | Current frequency 2, change of +1; resulting frequency 3. 38 | (At this point, the device continues from the start of the list.) 39 | Current frequency 3, change of +1; resulting frequency 4. 40 | Current frequency 4, change of -2; resulting frequency 2, which has already been seen. 41 | In this example, the first frequency reached twice is 2. Note that your device might need to repeat its list of frequency changes many times before a duplicate frequency is found, and that duplicates might be found while in the middle of processing the list. 42 | 43 | Here are other examples: 44 | 45 | +1, -1 first reaches 0 twice. 46 | +3, +3, +4, -2, -4 first reaches 10 twice. 47 | -6, +3, +8, +5, -6 first reaches 5 twice. 48 | +7, +7, -2, -7, -4 first reaches 14 twice. 49 | What is the first frequency your device reaches twice? 50 | 51 | ## References 52 | https://adventofcode.com/2018/day/1 -------------------------------------------------------------------------------- /day-1-chronal-calibration/calibrate-two.js: -------------------------------------------------------------------------------- 1 | const calibrateDuplicates = (input) => { 2 | let breakdown = input 3 | .split('\n') 4 | .map(x => parseInt(x.trim(), 10)); 5 | 6 | let currentFrequency = 0, i = 0; 7 | let duplicateFound = false; 8 | let pastFrequencies = [currentFrequency]; 9 | 10 | while(!duplicateFound) { 11 | 12 | if (i === breakdown.length) { i = 0; }; 13 | 14 | currentFrequency += breakdown[i]; 15 | 16 | duplicateFound = pastFrequencies.includes(currentFrequency); 17 | 18 | pastFrequencies.push(currentFrequency); 19 | 20 | i++; 21 | } 22 | 23 | return currentFrequency; 24 | }; 25 | 26 | module.exports = calibrateDuplicates; -------------------------------------------------------------------------------- /day-1-chronal-calibration/calibrate.js: -------------------------------------------------------------------------------- 1 | const calibrate = (input) => { 2 | let breakdown = input 3 | .split('\n') 4 | .map(x => parseInt(x.trim(), 10)); 5 | let total = 0; 6 | 7 | for (let i = 0; i < breakdown.length; i++) { 8 | total += breakdown[i]; 9 | } 10 | 11 | return total; 12 | } 13 | 14 | module.exports = calibrate; -------------------------------------------------------------------------------- /day-1-chronal-calibration/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const calibrate = require('./calibrate'); 3 | const calibrateDuplicates = require('./calibrate-two'); 4 | 5 | // Day One - Part One Tests 6 | describe('Part One Calibrate', () => { 7 | it('should return 3 when input is +1, -2, +3, +1', () => { 8 | let input = 9 | `+1 10 | -2 11 | +3 12 | +1`; 13 | assert.strictEqual(calibrate(input), 3); 14 | }); 15 | }); 16 | 17 | describe('Part One Calibrate', () => { 18 | it('should return 3 when input is +1, +1, +1', () => { 19 | let input = 20 | `+1 21 | +1 22 | +1`; 23 | assert.strictEqual(calibrate(input), 3); 24 | }); 25 | }); 26 | 27 | describe('Part One Calibrate', () => { 28 | it('should return 0 when input is +1, +1, -2', () => { 29 | let input = 30 | `+1 31 | +1 32 | -2`; 33 | assert.strictEqual(calibrate(input), 0); 34 | }); 35 | }); 36 | 37 | describe('Part One Calibrate', () => { 38 | it('should return -6 when input is -1, -2, -3', () => { 39 | let input = 40 | `-1 41 | -2 42 | -3`; 43 | assert.strictEqual(calibrate(input), -6); 44 | }); 45 | }); 46 | 47 | // Day One - Part Two Tests 48 | describe('Part Two Calibrate Duplicates', () => { 49 | it('should return 2 when input is +1, -2, +3, +1', () => { 50 | let input = 51 | `+1 52 | -2 53 | +3 54 | +1`; 55 | assert.strictEqual(calibrateDuplicates(input), 2); 56 | }); 57 | }); 58 | 59 | describe('Part Two Calibrate Duplicates', () => { 60 | it('should return 0 when input is +1, -1', () => { 61 | let input = 62 | `+1 63 | -1`; 64 | assert.strictEqual(calibrateDuplicates(input), 0); 65 | }); 66 | }); 67 | 68 | describe('Part Two Calibrate Duplicates', () => { 69 | it('should return 10 when input is +3, +3, +4, -2, -4', () => { 70 | let input = 71 | `+3 72 | +3 73 | +4 74 | -2 75 | -4`; 76 | assert.strictEqual(calibrateDuplicates(input), 10); 77 | }); 78 | }); 79 | 80 | describe('Part Two Calibrate Duplicates', () => { 81 | it('should return 5 when input is -6, +3, +8, +5, -6', () => { 82 | let input = 83 | `-6 84 | +3 85 | +8 86 | +5 87 | -6`; 88 | assert.strictEqual(calibrateDuplicates(input), 5); 89 | }); 90 | }); 91 | 92 | describe('Part Two Calibrate Duplicates', () => { 93 | it('should return 14 when input is +7, +7, -2, -7, -4', () => { 94 | let input = 95 | `+7 96 | +7 97 | -2 98 | -7 99 | -4`; 100 | assert.strictEqual(calibrateDuplicates(input), 14); 101 | }); 102 | }); -------------------------------------------------------------------------------- /day-2-inventory-management-system/README.md: -------------------------------------------------------------------------------- 1 | # Day 2 - Inventory Management System: 2 | 3 | ## Part One 4 | You stop falling through time, catch your breath, and check the screen on the device. "Destination reached. Current Year: 1518. Current Location: North Pole Utility Closet 83N10." You made it! Now, to find those anomalies. 5 | 6 | Outside the utility closet, you hear footsteps and a voice. "...I'm not sure either. But now that so many people have chimneys, maybe he could sneak in that way?" Another voice responds, "Actually, we've been working on a new kind of suit that would let him fit through tight spaces like that. But, I heard that a few days ago, they lost the prototype fabric, the design plans, everything! Nobody on the team can even seem to remember important details of the project!" 7 | 8 | "Wouldn't they have had enough fabric to fill several boxes in the warehouse? They'd be stored together, so the box IDs should be similar. Too bad it would take forever to search the warehouse for two similar box IDs..." They walk too far away to hear any more. 9 | 10 | Late at night, you sneak to the warehouse - who knows what kinds of paradoxes you could cause if you were discovered - and use your fancy wrist device to quickly scan every box and produce a list of the likely candidates (your puzzle input). 11 | 12 | To make sure you didn't miss any, you scan the likely candidate boxes again, counting the number that have an ID containing exactly two of any letter and then separately counting those with exactly three of any letter. You can multiply those two counts together to get a rudimentary checksum and compare it to what your device predicts. 13 | 14 | For example, if you see the following box IDs: 15 | 16 | abcdef contains no letters that appear exactly two or three times. 17 | bababc contains two a and three b, so it counts for both. 18 | abbcde contains two b, but no letter appears exactly three times. 19 | abcccd contains three c, but no letter appears exactly two times. 20 | aabcdd contains two a and two d, but it only counts once. 21 | abcdee contains two e. 22 | ababab contains three a and three b, but it only counts once. 23 | Of these box IDs, four of them contain a letter which appears exactly twice, and three of them contain a letter which appears exactly three times. Multiplying these together produces a checksum of 4 * 3 = 12. 24 | 25 | What is the checksum for your list of box IDs? 26 | 27 | ## Part Two 28 | Confident that your list of box IDs is complete, you're ready to find the boxes full of prototype fabric. 29 | 30 | The boxes will have IDs which differ by exactly one character at the same position in both strings. For example, given the following box IDs: 31 | 32 | abcde 33 | fghij 34 | klmno 35 | pqrst 36 | fguij 37 | axcye 38 | wvxyz 39 | The IDs abcde and axcye are close, but they differ by two characters (the second and fourth). However, the IDs fghij and fguij differ by exactly one character, the third (h and u). Those must be the correct boxes. 40 | 41 | What letters are common between the two correct box IDs? (In the example above, this is found by removing the differing character from either ID, producing fgij.) 42 | 43 | ## References 44 | https://adventofcode.com/2018/day/2 -------------------------------------------------------------------------------- /day-2-inventory-management-system/checksum-two.js: -------------------------------------------------------------------------------- 1 | const checkDifference = (x, y) => { 2 | let totalDifferences = 0; 3 | 4 | for (let a = 0; a < x.length; a++) { 5 | let letter = x[a]; 6 | let secondLetter = y[a]; 7 | 8 | if (letter !== secondLetter) { 9 | totalDifferences++; 10 | } 11 | }; 12 | 13 | return totalDifferences; 14 | }; 15 | 16 | const findCommonLetters = (x, y) => { 17 | let commonLetters = []; 18 | 19 | for (let i = 0; i < x.length; i++) { 20 | let letter = x[i]; 21 | let comparisonLetter = y[i]; 22 | 23 | if(letter === comparisonLetter) { 24 | commonLetters.push(letter); 25 | } 26 | } 27 | 28 | return commonLetters; 29 | }; 30 | 31 | const checksumTwo = (input) => { 32 | let rows = input 33 | .split('\n') 34 | .map(x => x.trim()); 35 | 36 | for (let i = 0; i < rows.length; i++) { 37 | for (let j = 0; j < rows.length; j++) { 38 | if(checkDifference(rows[i], rows[j]) === 1) { 39 | return findCommonLetters(rows[i], rows[j]).join(''); 40 | } 41 | } 42 | } 43 | } 44 | 45 | module.exports = checksumTwo; -------------------------------------------------------------------------------- /day-2-inventory-management-system/checksum.js: -------------------------------------------------------------------------------- 1 | const checksum = (input) => { 2 | let rows = input.split('\n'); 3 | let totalTwos = 0; 4 | let totalThrees = 0; 5 | 6 | rows.forEach((item, i) => { 7 | let tally = {}; 8 | let currentBox = item.split(''); 9 | 10 | for (let i = 0; i < currentBox.length; i++) { 11 | let char = currentBox[i]; 12 | 13 | tally[char] = (tally[char] !== undefined) ? tally[char] + 1 : 1; 14 | } 15 | 16 | let tallies = new Set(Object.values(tally)); 17 | 18 | if (tallies.has(2)) { 19 | totalTwos++; 20 | }; 21 | 22 | if (tallies.has(3)) { 23 | totalThrees++; 24 | }; 25 | }); 26 | 27 | return totalTwos * totalThrees; 28 | } 29 | 30 | module.exports = checksum; -------------------------------------------------------------------------------- /day-2-inventory-management-system/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const checksum = require('./checksum'); 3 | const checksumTwo = require('./checksum-two'); 4 | 5 | // Day Two - Part One Tests 6 | describe('Part One Checksum', () => { 7 | it('should return 12 as checksum', () => { 8 | let input = 9 | `abcdef 10 | bababc 11 | abbcde 12 | abcccd 13 | aabcdd 14 | abcdee 15 | ababab 16 | `; 17 | 18 | assert.strictEqual(checksum(input), 12); 19 | }) 20 | }) 21 | 22 | // Day Two - Part Two Tests 23 | describe('Part Two', () => { 24 | it('should find common characters', () => { 25 | const boxIds = 26 | `abcde 27 | fghij 28 | klmno 29 | pqrst 30 | fguij 31 | axcye 32 | wvxyz`; 33 | 34 | assert.strictEqual(checksumTwo(boxIds), 'fgij'); 35 | }); 36 | }); -------------------------------------------------------------------------------- /day-3-no-matter-how-you-slice-it/README.md: -------------------------------------------------------------------------------- 1 | # Day 3 - No Matter How You Slice It 2 | 3 | ## Part One 4 | The Elves managed to locate the chimney-squeeze prototype fabric for Santa's suit (thanks to someone who helpfully wrote its box IDs on the wall of the warehouse in the middle of the night). Unfortunately, anomalies are still affecting them - nobody can even agree on how to cut the fabric. 5 | 6 | The whole piece of fabric they're working on is a very large square - at least 1000 inches on each side. 7 | 8 | Each Elf has made a claim about which area of fabric would be ideal for Santa's suit. All claims have an ID and consist of a single rectangle with edges parallel to the edges of the fabric. Each claim's rectangle is defined as follows: 9 | 10 | The number of inches between the left edge of the fabric and the left edge of the rectangle. 11 | The number of inches between the top edge of the fabric and the top edge of the rectangle. 12 | The width of the rectangle in inches. 13 | The height of the rectangle in inches. 14 | A claim like #123 @ 3,2: 5x4 means that claim ID 123 specifies a rectangle 3 inches from the left edge, 2 inches from the top edge, 5 inches wide, and 4 inches tall. Visually, it claims the square inches of fabric represented by # (and ignores the square inches of fabric represented by .) in the diagram below: 15 | 16 | ``` 17 | ........... 18 | ........... 19 | ...#####... 20 | ...#####... 21 | ...#####... 22 | ...#####... 23 | ........... 24 | ........... 25 | ........... 26 | ``` 27 | The problem is that many of the claims overlap, causing two or more claims to cover part of the same areas. For example, consider the following claims: 28 | 29 | ``` 30 | #1 @ 1,3: 4x4 31 | #2 @ 3,1: 4x4 32 | #3 @ 5,5: 2x2 33 | ``` 34 | 35 | Visually, these claim the following areas: 36 | 37 | ``` 38 | ........ 39 | ...2222. 40 | ...2222. 41 | .11XX22. 42 | .11XX22. 43 | .111133. 44 | .111133. 45 | ........ 46 | ``` 47 | 48 | The four square inches marked with X are claimed by both 1 and 2. (Claim 3, while adjacent to the others, does not overlap either of them.) 49 | 50 | If the Elves all proceed with their own plans, none of them will have enough fabric. How many square inches of fabric are within two or more claims? 51 | 52 | ## Part Two 53 | Amidst the chaos, you notice that exactly one claim doesn't overlap by even a single square inch of fabric with any other claim. If you can somehow draw attention to it, maybe the Elves will be able to make Santa's suit after all! 54 | 55 | For example, in the claims above, only claim 3 is intact after all claims are made. 56 | 57 | What is the ID of the only claim that doesn't overlap? -------------------------------------------------------------------------------- /day-3-no-matter-how-you-slice-it/non-overlap.js: -------------------------------------------------------------------------------- 1 | const nonOverlap = (input) => { 2 | let claims = input.split('\n').map(x => x.trim()); 3 | let grid = {}; 4 | 5 | for (let a = 0; a < claims.length; a++) { 6 | let item = claims[a]; 7 | let matchGroups = item.match(/#(\d+) @ (\d+),(\d+): (\d+)x(\d+)/); 8 | 9 | let offsetX = parseInt(matchGroups[2]); 10 | let offsetY = parseInt(matchGroups[3]); 11 | 12 | let width = parseInt(matchGroups[4]); 13 | let height = parseInt(matchGroups[5]); 14 | 15 | for (let i = 0; i < width; i++) { 16 | let x = offsetX + i; 17 | 18 | for (let j = 0; j < height; j++) { 19 | let y = offsetY + j; 20 | 21 | grid[`${x},${y}`] = (grid[`${x},${y}`] !== undefined) ? grid[`${x},${y}`] + 1 : 1; 22 | } 23 | } 24 | } 25 | 26 | for (let a = 0; a < claims.length; a++) { 27 | let item = claims[a]; 28 | let matchGroups = item.match(/#(\d+) @ (\d+),(\d+): (\d+)x(\d+)/); 29 | 30 | let claimId = parseInt(matchGroups[1]); 31 | let offsetX = parseInt(matchGroups[2]); 32 | let offsetY = parseInt(matchGroups[3]); 33 | 34 | let width = parseInt(matchGroups[4]); 35 | let height = parseInt(matchGroups[5]); 36 | 37 | let patches = new Set(); 38 | 39 | for (let i = 0; i < width; i++) { 40 | let x = offsetX + i; 41 | 42 | for (let j = 0; j < height; j++) { 43 | let y = offsetY + j; 44 | 45 | patches.add(grid[`${x},${y}`]); 46 | } 47 | } 48 | 49 | if (patches.size === 1 && patches.has(1)) { 50 | return claimId; 51 | } 52 | } 53 | } 54 | 55 | module.exports = nonOverlap; -------------------------------------------------------------------------------- /day-3-no-matter-how-you-slice-it/overlap.js: -------------------------------------------------------------------------------- 1 | const overlap = (input) => { 2 | let claims = input.split('\n').map(x => x.trim()); 3 | let grid = {}; 4 | 5 | for (let a = 0; a < claims.length; a++) { 6 | let item = claims[a]; 7 | let matchGroups = item.match(/#(\d+) @ (\d+),(\d+): (\d+)x(\d+)/); 8 | 9 | let offsetX = parseInt(matchGroups[2]); 10 | let offsetY = parseInt(matchGroups[3]); 11 | 12 | let width = parseInt(matchGroups[4]); 13 | let height = parseInt(matchGroups[5]); 14 | 15 | 16 | for (let i = 0; i < width; i++) { 17 | let x = offsetX + i; 18 | 19 | for (let j = 0; j < height; j++) { 20 | let y = offsetY + j; 21 | 22 | grid[`${x},${y}`] = (grid[`${x},${y}`] !== undefined) ? grid[`${x},${y}`] + 1 : 1; 23 | } 24 | } 25 | } 26 | 27 | let overlappedSpots = Object.values(grid); 28 | 29 | return overlappedSpots.filter(spot => spot >= 2).length; 30 | } 31 | 32 | module.exports = overlap; -------------------------------------------------------------------------------- /day-3-no-matter-how-you-slice-it/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const overlap = require('./overlap'); 3 | const nonOverlap = require('./non-overlap'); 4 | 5 | describe('Day Three Part One Overlap', () => { 6 | it('should return 4 overlapping inches', () => { 7 | let input = 8 | `#1 @ 1,3: 4x4 9 | #2 @ 3,1: 4x4 10 | #3 @ 5,5: 2x2`; 11 | assert.strictEqual(overlap(input), 4); 12 | }) 13 | }) 14 | 15 | describe('Day Three Part Two No Overlap', () => { 16 | it('should return claim id 3', () => { 17 | let input = 18 | `#1 @ 1,3: 4x4 19 | #2 @ 3,1: 4x4 20 | #3 @ 5,5: 2x2`; 21 | assert.strictEqual(nonOverlap(input), 3); 22 | }) 23 | }) -------------------------------------------------------------------------------- /day-4-repose-record/README.md: -------------------------------------------------------------------------------- 1 | # Day 4 - Repose Record 2 | 3 | ## Part One 4 | You've sneaked into another supply closet - this time, it's across from the prototype suit manufacturing lab. You need to sneak inside and fix the issues with the suit, but there's a guard stationed outside the lab, so this is as close as you can safely get. 5 | 6 | As you search the closet for anything that might help, you discover that you're not the first person to want to sneak in. Covering the walls, someone has spent an hour starting every midnight for the past few months secretly observing this guard post! They've been writing down the ID of the one guard on duty that night - the Elves seem to have decided that one guard was enough for the overnight shift - as well as when they fall asleep or wake up while at their post (your puzzle input). 7 | 8 | For example, consider the following records, which have already been organized into chronological order: 9 | 10 | ``` 11 | [1518-11-01 00:00] Guard #10 begins shift 12 | [1518-11-01 00:05] falls asleep 13 | [1518-11-01 00:25] wakes up 14 | [1518-11-01 00:30] falls asleep 15 | [1518-11-01 00:55] wakes up 16 | [1518-11-01 23:58] Guard #99 begins shift 17 | [1518-11-02 00:40] falls asleep 18 | [1518-11-02 00:50] wakes up 19 | [1518-11-03 00:05] Guard #10 begins shift 20 | [1518-11-03 00:24] falls asleep 21 | [1518-11-03 00:29] wakes up 22 | [1518-11-04 00:02] Guard #99 begins shift 23 | [1518-11-04 00:36] falls asleep 24 | [1518-11-04 00:46] wakes up 25 | [1518-11-05 00:03] Guard #99 begins shift 26 | [1518-11-05 00:45] falls asleep 27 | [1518-11-05 00:55] wakes up 28 | ``` 29 | Timestamps are written using year-month-day hour:minute format. The guard falling asleep or waking up is always the one whose shift most recently started. Because all asleep/awake times are during the midnight hour (00:00 - 00:59), only the minute portion (00 - 59) is relevant for those events. 30 | 31 | Visually, these records show that the guards are asleep at these times: 32 | 33 | ``` 34 | Date ID Minute 35 | 000000000011111111112222222222333333333344444444445555555555 36 | 012345678901234567890123456789012345678901234567890123456789 37 | 11-01 #10 .....####################.....#########################..... 38 | 11-02 #99 ........................................##########.......... 39 | 11-03 #10 ........................#####............................... 40 | 11-04 #99 ....................................##########.............. 41 | 11-05 #99 .............................................##########..... 42 | ``` 43 | The columns are Date, which shows the month-day portion of the relevant day; ID, which shows the guard on duty that day; and Minute, which shows the minutes during which the guard was asleep within the midnight hour. (The Minute column's header shows the minute's ten's digit in the first row and the one's digit in the second row.) Awake is shown as ., and asleep is shown as #. 44 | 45 | Note that guards count as asleep on the minute they fall asleep, and they count as awake on the minute they wake up. For example, because Guard #10 wakes up at 00:25 on 1518-11-01, minute 25 is marked as awake. 46 | 47 | If you can figure out the guard most likely to be asleep at a specific time, you might be able to trick that guard into working tonight so you can have the best chance of sneaking in. You have two strategies for choosing the best guard/minute combination. 48 | 49 | Strategy 1: Find the guard that has the most minutes asleep. What minute does that guard spend asleep the most? 50 | 51 | In the example above, Guard #10 spent the most minutes asleep, a total of 50 minutes (20+25+5), while Guard #99 only slept for a total of 30 minutes (10+10+10). Guard #10 was asleep most during minute 24 (on two days, whereas any other minute the guard was asleep was only seen on one day). 52 | 53 | While this example listed the entries in chronological order, your entries are in the order you found them. You'll need to organize them before they can be analyzed. 54 | 55 | What is the ID of the guard you chose multiplied by the minute you chose? (In the above example, the answer would be 10 * 24 = 240.) 56 | 57 | ## Part Two 58 | Strategy 2: Of all guards, which guard is most frequently asleep on the same minute? 59 | 60 | In the example above, Guard #99 spent minute 45 asleep more than any other guard or minute - three times in total. (In all other cases, any guard spent any minute asleep at most twice.) 61 | 62 | What is the ID of the guard you chose multiplied by the minute you chose? (In the above example, the answer would be 99 * 45 = 4455.) -------------------------------------------------------------------------------- /day-4-repose-record/sleepy-guard-two.js: -------------------------------------------------------------------------------- 1 | const findConsistentLaziestGuard = (input) => { 2 | let nightShifts = input.split('\n') 3 | .map(x => x.trim()) 4 | .sort(); 5 | 6 | let sleepMinutes = {}; 7 | 8 | let guardId = 0; 9 | let minuteAdrift = 0; 10 | let minuteAwaken = 0; 11 | 12 | for (let i = 0; i < nightShifts.length; i++) { 13 | let shift = nightShifts[i]; 14 | let matchGroups = shift.match(/\[(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})\] (\w+) #?(\d+\d+|\w+)/); 15 | let minute = parseInt(matchGroups[5]); 16 | 17 | const action = matchGroups[6]; 18 | 19 | if (action.toLowerCase() === 'guard') { 20 | guardId = matchGroups[7]; 21 | 22 | if (sleepMinutes[guardId] == undefined) { 23 | sleepMinutes[guardId] = {}; 24 | 25 | for (let i = 0; i < 60; i++) { 26 | sleepMinutes[guardId][i] = 0; 27 | } 28 | } 29 | }; 30 | 31 | if (action.toLowerCase() === "falls") { 32 | minuteAdrift = minute; 33 | }; 34 | 35 | if (action.toLowerCase() === "wakes") { 36 | minuteAwaken = minute; 37 | 38 | for (let m = minuteAdrift; m < minuteAwaken; m++) { 39 | sleepMinutes[guardId][m] += 1; 40 | }; 41 | }; 42 | }; 43 | 44 | let mostMinutesSlept = Object 45 | .keys(sleepMinutes) 46 | .map(x => Object 47 | .values(sleepMinutes[x]) 48 | .sort((a, b) => b - a)[0]) 49 | .sort((a, b) => b - a)[0]; 50 | 51 | let laziestGuardId = Object 52 | .keys(sleepMinutes) 53 | .find(x => Object 54 | .keys(sleepMinutes[x]) 55 | .find(y => sleepMinutes[x][y] === mostMinutesSlept)); 56 | 57 | let sleepiestMinuteId = Object 58 | .keys(sleepMinutes[laziestGuardId]) 59 | .filter(x => sleepMinutes[laziestGuardId][x] === mostMinutesSlept)[0]; 60 | 61 | return +laziestGuardId * sleepiestMinuteId; 62 | }; 63 | 64 | module.exports = findConsistentLaziestGuard; -------------------------------------------------------------------------------- /day-4-repose-record/sleepy-guard.js: -------------------------------------------------------------------------------- 1 | const findLaziestGuard = (input) => { 2 | let nightShifts = input.split('\n') 3 | .map(x => x.trim()) 4 | .sort(); 5 | 6 | let sleepMinutes = {}; 7 | 8 | let guardId = 0; 9 | let minuteAdrift = 0; 10 | let minuteAwaken = 0; 11 | 12 | for (let i = 0; i < nightShifts.length; i++) { 13 | let shift = nightShifts[i]; 14 | let matchGroups = shift.match(/\[(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})\] (\w+) #?(\d+\d+|\w+)/); 15 | let minute = parseInt(matchGroups[5]); 16 | 17 | const action = matchGroups[6]; 18 | 19 | if (action.toLowerCase() === 'guard') { 20 | guardId = matchGroups[7]; 21 | 22 | if (sleepMinutes[guardId] == undefined) { 23 | sleepMinutes[guardId] = {}; 24 | 25 | for (let i = 0; i < 60; i++) { 26 | sleepMinutes[guardId][i] = 0; 27 | } 28 | } 29 | }; 30 | 31 | if (action.toLowerCase() === "falls") { 32 | minuteAdrift = minute; 33 | }; 34 | 35 | if (action.toLowerCase() === "wakes") { 36 | minuteAwaken = minute; 37 | 38 | for (let m = minuteAdrift; m < minuteAwaken; m++) { 39 | sleepMinutes[guardId][m] += 1; 40 | }; 41 | }; 42 | }; 43 | 44 | let mostMinutesSlept = Object 45 | .keys(sleepMinutes) 46 | .map(x => Object 47 | .values(sleepMinutes[x]) 48 | .reduce((a, b) => a + b, 0)) 49 | .sort((a, b) => b - a)[0]; 50 | 51 | let laziestGuardId = Object 52 | .keys(sleepMinutes) 53 | .find(x => Object 54 | .values(sleepMinutes[x]) 55 | .reduce((a, b) => a + b, 0) === mostMinutesSlept); 56 | 57 | let sleepiestMinute = Object 58 | .values(sleepMinutes[laziestGuardId]) 59 | .sort((a, b) => b - a)[0]; 60 | 61 | let sleepiestMinuteId = Object 62 | .keys(sleepMinutes[laziestGuardId]) 63 | .filter(x => sleepMinutes[laziestGuardId][x] === sleepiestMinute)[0]; 64 | 65 | return +laziestGuardId * sleepiestMinuteId; 66 | }; 67 | 68 | module.exports = findLaziestGuard; -------------------------------------------------------------------------------- /day-4-repose-record/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const findLaziestGuard = require('./sleepy-guard'); 3 | const findConsistentLaziestGuard = require('./sleepy-guard-two'); 4 | 5 | describe('Day Four Part One Lazy Guard', () => { 6 | it('should return 240 with chosen guard', () => { 7 | let input = 8 | `[1518-11-01 00:00] Guard #10 begins shift 9 | [1518-11-01 00:05] falls asleep 10 | [1518-11-01 00:25] wakes up 11 | [1518-11-01 00:30] falls asleep 12 | [1518-11-01 00:55] wakes up 13 | [1518-11-01 23:58] Guard #99 begins shift 14 | [1518-11-02 00:40] falls asleep 15 | [1518-11-02 00:50] wakes up 16 | [1518-11-03 00:05] Guard #10 begins shift 17 | [1518-11-03 00:24] falls asleep 18 | [1518-11-03 00:29] wakes up 19 | [1518-11-04 00:02] Guard #99 begins shift 20 | [1518-11-04 00:36] falls asleep 21 | [1518-11-04 00:46] wakes up 22 | [1518-11-05 00:03] Guard #99 begins shift 23 | [1518-11-05 00:45] falls asleep 24 | [1518-11-05 00:55] wakes up`; 25 | 26 | assert.strictEqual(findLaziestGuard(input), 240); 27 | }) 28 | }); 29 | 30 | describe('Day Four Part Two Most Consistent Lazy Guard', () => { 31 | it('should return 4455 with chosen guard', () => { 32 | let input = 33 | `[1518-11-01 00:00] Guard #10 begins shift 34 | [1518-11-01 00:05] falls asleep 35 | [1518-11-01 00:25] wakes up 36 | [1518-11-01 00:30] falls asleep 37 | [1518-11-01 00:55] wakes up 38 | [1518-11-01 23:58] Guard #99 begins shift 39 | [1518-11-02 00:40] falls asleep 40 | [1518-11-02 00:50] wakes up 41 | [1518-11-03 00:05] Guard #10 begins shift 42 | [1518-11-03 00:24] falls asleep 43 | [1518-11-03 00:29] wakes up 44 | [1518-11-04 00:02] Guard #99 begins shift 45 | [1518-11-04 00:36] falls asleep 46 | [1518-11-04 00:46] wakes up 47 | [1518-11-05 00:03] Guard #99 begins shift 48 | [1518-11-05 00:45] falls asleep 49 | [1518-11-05 00:55] wakes up`; 50 | 51 | assert.strictEqual(findConsistentLaziestGuard(input), 4455); 52 | }) 53 | }); -------------------------------------------------------------------------------- /day-5-alchemical-reduction/README.md: -------------------------------------------------------------------------------- 1 | # Day 5 - Alchemical Reduction 2 | 3 | ## Part One 4 | You've managed to sneak in to the prototype suit manufacturing lab. The Elves are making decent progress, but are still struggling with the suit's size reduction capabilities. 5 | 6 | While the very latest in 1518 alchemical technology might have solved their problem eventually, you can do better. You scan the chemical composition of the suit's material and discover that it is formed by extremely long polymers (one of which is available as your puzzle input). 7 | 8 | The polymer is formed by smaller units which, when triggered, react with each other such that two adjacent units of the same type and opposite polarity are destroyed. Units' types are represented by letters; units' polarity is represented by capitalization. For instance, r and R are units with the same type but opposite polarity, whereas r and s are entirely different types and do not react. 9 | 10 | For example: 11 | 12 | In `aA`, `a` and `A` react, leaving nothing behind. 13 | In `abBA`, `bB` destroys itself, leaving `aA`. As above, this then destroys itself, leaving nothing. 14 | In `abAB`, no two adjacent units are of the same type, and so nothing happens. 15 | In `aabAAB`, even though `aa` and `AA` are of the same type, their polarities match, and so nothing happens. 16 | Now, consider a larger example, `dabAcCaCBAcCcaDA`: 17 | 18 | ``` 19 | dabAcCaCBAcCcaDA The first 'cC' is removed. 20 | dabAaCBAcCcaDA This creates 'Aa', which is removed. 21 | dabCBAcCcaDA Either 'cC' or 'Cc' are removed (the result is the same). 22 | dabCBAcaDA No further actions can be taken. 23 | ``` 24 | After all possible reactions, the resulting polymer contains 10 units. 25 | 26 | How many units remain after fully reacting the polymer you scanned? (Note: in this puzzle and others, the input is large; if you copy/paste your input, make sure you get the whole thing.) 27 | 28 | ## Part Two 29 | Time to improve the polymer. 30 | 31 | One of the unit types is causing problems; it's preventing the polymer from collapsing as much as it should. Your goal is to figure out which unit type is causing the most problems, remove all instances of it (regardless of polarity), fully react the remaining polymer, and measure its length. 32 | 33 | For example, again using the polymer dabAcCaCBAcCcaDA from above: 34 | 35 | Removing all `A/a` units produces `dbcCCBcCcD`. Fully reacting this polymer produces `dbCBcD`, which has length 6. 36 | Removing all `B/b` units produces `daAcCaCAcCcaDA`. Fully reacting this polymer produces `daCAcaDA`, which has length 8. 37 | Removing all `C/`c units produces `dabAaBAaDA`. Fully reacting this polymer produces `daDA`, which has length 4. 38 | Removing all `D/d` units produces `abAcCaCBAcCcaA`. Fully reacting this polymer produces `abCBAc`, which has length 6. 39 | In this example, removing all `C/c` units was best, producing the answer 4. 40 | 41 | What is the length of the shortest polymer you can produce by removing all units of exactly one type and fully reacting the result? -------------------------------------------------------------------------------- /day-5-alchemical-reduction/polymer-two.js: -------------------------------------------------------------------------------- 1 | const checkForReaction = (x, y) => { 2 | if (x.toLowerCase() === y.toLowerCase()) { 3 | if (x !== y) { 4 | return true; 5 | }; 6 | }; 7 | return false; 8 | } 9 | 10 | const findUniqueUnits = (units) => { 11 | let uniques = new Set() 12 | for (let i = 0; i < units.length; i++) { 13 | uniques.add(units[i].toLowerCase()); 14 | } 15 | 16 | return uniques; 17 | } 18 | 19 | const shortestPolymer = (input) => { 20 | let units = input.split(''); 21 | let uniqueUnits = findUniqueUnits(units); 22 | 23 | let mutatedPolymers = []; 24 | 25 | uniqueUnits.forEach(uniqueUnit => { 26 | let mutation = units.filter(y => y.toLowerCase() !== uniqueUnit); 27 | let firstPosition = 0; 28 | let scanning = true; 29 | 30 | while (scanning) { 31 | let reaction = checkForReaction(mutation[firstPosition], mutation[firstPosition + 1]); 32 | 33 | if (reaction) { 34 | mutation.splice(firstPosition, 2); 35 | firstPosition = 0; 36 | } else { 37 | firstPosition++; 38 | 39 | if (!mutation[firstPosition + 1]) { 40 | scanning = false; 41 | }; 42 | }; 43 | 44 | if (firstPosition >= mutation.length) { 45 | scanning = false; 46 | } 47 | }; 48 | 49 | mutatedPolymers.push(mutation.length); 50 | }); 51 | 52 | return mutatedPolymers.sort((x, y) => x - y)[0]; 53 | } 54 | 55 | module.exports = shortestPolymer; -------------------------------------------------------------------------------- /day-5-alchemical-reduction/polymer.js: -------------------------------------------------------------------------------- 1 | const checkForReaction = (x, y) => { 2 | if (x.toLowerCase() === y.toLowerCase()) { 3 | if (x !== y) { 4 | return true; 5 | }; 6 | }; 7 | return false; 8 | } 9 | 10 | const remainingPolymer = (input) => { 11 | let units = input.split(''); 12 | 13 | let firstPosition = 0; 14 | let scanning = true; 15 | 16 | while (scanning) { 17 | let reaction = checkForReaction(units[firstPosition], units[firstPosition + 1]); 18 | 19 | if (reaction) { 20 | units.splice(firstPosition, 2); 21 | firstPosition = 0; 22 | } else { 23 | firstPosition++; 24 | 25 | if (!units[firstPosition + 1]) { 26 | scanning = false; 27 | }; 28 | }; 29 | 30 | if (firstPosition >= units.length) { 31 | scanning = false; 32 | } 33 | } 34 | 35 | return units.length; 36 | } 37 | 38 | module.exports = remainingPolymer; -------------------------------------------------------------------------------- /day-5-alchemical-reduction/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const remainingPolymer = require('./polymer'); 3 | const shortestPolymer = require('./polymer-two'); 4 | 5 | describe('Day Five Part One Remaining Polymer', () => { 6 | it('should return 0 when input is aA', () => { 7 | let input = `aA`; 8 | 9 | assert.strictEqual(remainingPolymer(input), 0); 10 | }); 11 | }); 12 | 13 | describe('Day Five Part One Remaining Polymer', () => { 14 | it('should return 0 when input is abBA', () => { 15 | let input = `abBA`; 16 | 17 | assert.strictEqual(remainingPolymer(input), 0); 18 | }); 19 | }); 20 | 21 | describe('Day Five Part One Remaining Polymer', () => { 22 | it('should return 4 when input is abAB', () => { 23 | let input = `abAB`; 24 | 25 | assert.strictEqual(remainingPolymer(input), 4); 26 | }); 27 | }); 28 | 29 | describe('Day Five Part One Remaining Polymer', () => { 30 | it('should return 6 when input is aabAAB', () => { 31 | let input = `aabAAB`; 32 | 33 | assert.strictEqual(remainingPolymer(input), 6); 34 | }); 35 | }); 36 | 37 | describe('Day Five Part One Remaining Polymer', () => { 38 | it('should return 10 when input is dabAcCaCBAcCcaDA', () => { 39 | let input = `dabAcCaCBAcCcaDA`; 40 | 41 | assert.strictEqual(remainingPolymer(input), 10); 42 | }); 43 | }); 44 | 45 | // Part Two Tests 46 | describe('Day Five Part Two Shortest Polymer', () => { 47 | it('should return 4 when input is dabAcCaCBAcCcaDA', () => { 48 | let input = `dabAcCaCBAcCcaDA`; 49 | 50 | assert.strictEqual(shortestPolymer(input), 4); 51 | }); 52 | }); 53 | -------------------------------------------------------------------------------- /day-6-chronal-coordinates/README.md: -------------------------------------------------------------------------------- 1 | # Day 6 - Chronal Coordinates 2 | 3 | ## Part One 4 | The device on your wrist beeps several times, and once again you feel like you're falling. 5 | 6 | "Situation critical," the device announces. "Destination indeterminate. Chronal interference detected. Please specify new target coordinates." 7 | 8 | The device then produces a list of coordinates (your puzzle input). Are they places it thinks are safe or dangerous? It recommends you check manual page 729. The Elves did not give you a manual. 9 | 10 | If they're dangerous, maybe you can minimize the danger by finding the coordinate that gives the largest distance from the other points. 11 | 12 | Using only the Manhattan distance, determine the area around each coordinate by counting the number of integer X,Y locations that are closest to that coordinate (and aren't tied in distance to any other coordinate). 13 | 14 | Your goal is to find the size of the largest area that isn't infinite. For example, consider the following list of coordinates: 15 | 16 | ``` 17 | 1, 1 18 | 1, 6 19 | 8, 3 20 | 3, 4 21 | 5, 5 22 | 8, 9 23 | ``` 24 | 25 | If we name these coordinates A through F, we can draw them on a grid, putting 0,0 at the top left: 26 | 27 | ``` 28 | .......... 29 | .A........ 30 | .......... 31 | ........C. 32 | ...D...... 33 | .....E.... 34 | .B........ 35 | .......... 36 | .......... 37 | ........F. 38 | ``` 39 | 40 | This view is partial - the actual grid extends infinitely in all directions. Using the Manhattan distance, each location's closest coordinate can be determined, shown here in lowercase: 41 | 42 | ``` 43 | aaaaa.cccc 44 | aAaaa.cccc 45 | aaaddecccc 46 | aadddeccCc 47 | ..dDdeeccc 48 | bb.deEeecc 49 | bBb.eeee.. 50 | bbb.eeefff 51 | bbb.eeffff 52 | bbb.ffffFf 53 | ``` 54 | 55 | Locations shown as . are equally far from two or more coordinates, and so they don't count as being closest to any. 56 | 57 | In this example, the areas of coordinates A, B, C, and F are infinite - while not shown here, their areas extend forever outside the visible grid. However, the areas of coordinates D and E are finite: D is closest to 9 locations, and E is closest to 17 (both including the coordinate's location itself). Therefore, in this example, the size of the largest area is 17. 58 | 59 | What is the size of the largest area that isn't infinite? 60 | 61 | ## Part Two 62 | On the other hand, if the coordinates are safe, maybe the best you can do is try to find a region near as many coordinates as possible. 63 | 64 | For example, suppose you want the sum of the Manhattan distance to all of the coordinates to be less than 32. For each location, add up the distances to all of the given coordinates; if the total of those distances is less than 32, that location is within the desired region. Using the same coordinates as above, the resulting region looks like this: 65 | 66 | ``` 67 | .......... 68 | .A........ 69 | .......... 70 | ...###..C. 71 | ..#D###... 72 | ..###E#... 73 | .B.###.... 74 | .......... 75 | .......... 76 | ........F. 77 | ``` 78 | 79 | In particular, consider the highlighted location 4,3 located at the top middle of the region. Its calculation is as follows, where abs() is the absolute value function: 80 | 81 | Distance to coordinate A: abs(4-1) + abs(3-1) = 5 82 | Distance to coordinate B: abs(4-1) + abs(3-6) = 6 83 | Distance to coordinate C: abs(4-8) + abs(3-3) = 4 84 | Distance to coordinate D: abs(4-3) + abs(3-4) = 2 85 | Distance to coordinate E: abs(4-5) + abs(3-5) = 3 86 | Distance to coordinate F: abs(4-8) + abs(3-9) = 10 87 | Total distance: 5 + 6 + 4 + 2 + 3 + 10 = 30 88 | Because the total distance to all coordinates (30) is less than 32, the location is within the region. 89 | 90 | This region, which also includes coordinates D and E, has a total size of 16. 91 | 92 | Your actual region will need to be much larger than this example, though, instead including all locations with a total distance of less than 10000. 93 | 94 | What is the size of the region containing all locations which have a total distance to all given coordinates of less than 10000? -------------------------------------------------------------------------------- /day-6-chronal-coordinates/manhattan-two.js: -------------------------------------------------------------------------------- 1 | const findManhattanDistance = (xOne, yOne, xTwo, yTwo) => { 2 | return Math.abs(xOne - xTwo) + Math.abs(yOne - yTwo); 3 | } 4 | 5 | const findMaxCoordinate = (coordinateSet, coordinate) => { 6 | let coordinates = []; 7 | 8 | for (let i = 0; i < coordinateSet.length; i++) { 9 | let coordinatePair = coordinateSet[i]; 10 | let matchGroups = coordinatePair.match(/(\d+), (\d+)/); 11 | 12 | if (coordinate === 'x') { 13 | let xCoordinate = matchGroups[1]; 14 | coordinates.push(parseInt(xCoordinate)); 15 | } else { 16 | let yCoordinate = matchGroups[2]; 17 | coordinates.push(parseInt(yCoordinate)); 18 | } 19 | }; 20 | 21 | return coordinates.sort((a, b) => b - a)[0]; 22 | } 23 | 24 | const findComprehensiveArea = (input, threshold) => { 25 | let coordinates = input.split('\n').map(x => x.trim()); 26 | 27 | let maxXCoordinate = findMaxCoordinate(coordinates, 'x'); 28 | let maxYCoordinate = findMaxCoordinate(coordinates, 'y'); 29 | 30 | let areas = []; 31 | 32 | for (let y = 0; y <= maxYCoordinate; y++) { 33 | for (let x = 0; x <= maxXCoordinate; x++) { 34 | let mappedAreas = []; 35 | 36 | for (let c = 0; c < coordinates.length; c++) { 37 | let coordinatePair = coordinates[c]; 38 | let matchGroups = coordinatePair.match(/(\d+), (\d+)/); 39 | 40 | mappedAreas.push({ coordinate: coordinates[c], distance: findManhattanDistance(x, y, matchGroups[1], matchGroups[2])}); 41 | } 42 | 43 | let totalDistance = mappedAreas.reduce((a, area) => { 44 | return a + area.distance; 45 | }, 0); 46 | 47 | 48 | if (totalDistance < threshold) { 49 | areas.push(`${x}, ${y}`); 50 | } 51 | } 52 | } 53 | 54 | return areas.length; 55 | } 56 | 57 | module.exports = findComprehensiveArea; -------------------------------------------------------------------------------- /day-6-chronal-coordinates/manhattan.js: -------------------------------------------------------------------------------- 1 | const findManhattanDistance = (xOne, yOne, xTwo, yTwo) => { 2 | return Math.abs(xOne - xTwo) + Math.abs(yOne - yTwo); 3 | } 4 | 5 | const findSpecialCoordinate = (coordinateSet, coordinate, type) => { 6 | let coordinates = []; 7 | 8 | for (let i = 0; i < coordinateSet.length; i++) { 9 | let coordinatePair = coordinateSet[i]; 10 | let matchGroups = coordinatePair.match(/(\d+), (\d+)/); 11 | 12 | if (coordinate === 'x') { 13 | let xCoordinate = matchGroups[1]; 14 | coordinates.push(parseInt(xCoordinate)); 15 | } else { 16 | let yCoordinate = matchGroups[2]; 17 | coordinates.push(parseInt(yCoordinate)); 18 | } 19 | }; 20 | 21 | if (type === "max") { 22 | return coordinates.sort((a, b) => b - a)[0]; 23 | } 24 | 25 | return coordinates.sort((a, b) => a - b)[0]; 26 | } 27 | 28 | const findLargestArea = (input) => { 29 | let coordinates = input.split('\n').map(x => x.trim()); 30 | 31 | let maxXCoordinate = findSpecialCoordinate(coordinates, 'x', 'max'); 32 | let maxYCoordinate = findSpecialCoordinate(coordinates, 'y', 'max'); 33 | let minXCoordinate = findSpecialCoordinate(coordinates, 'x', 'min'); 34 | let minYCoordinate = findSpecialCoordinate(coordinates, 'y', 'min'); 35 | 36 | let areas = {}; 37 | 38 | for (let i = 0; i < coordinates.length; i++) { 39 | areas[coordinates[i]] = []; 40 | } 41 | 42 | for (let y = 0; y <= maxYCoordinate; y++) { 43 | for (let x = 0; x <= maxXCoordinate; x++) { 44 | 45 | let distances = []; 46 | 47 | for (let c = 0; c < coordinates.length; c++) { 48 | 49 | let coordinatePair = coordinates[c]; 50 | let matchGroups = coordinatePair.match(/(\d+), (\d+)/); 51 | 52 | distances.push({ coordinate: coordinates[c], distance: findManhattanDistance(x, y, matchGroups[1], matchGroups[2])}); 53 | } 54 | 55 | distances.sort((a, b) => a.distance - b.distance); 56 | 57 | if (distances[0].distance < distances[1].distance) { 58 | areas[distances[0].coordinate].push(`${x}, ${y}`); 59 | } 60 | } 61 | } 62 | 63 | return Object 64 | .keys(areas) 65 | .filter(key => { 66 | let coordinates = areas[key]; 67 | 68 | return coordinates.every(point => { 69 | let matchGroups = point.match(/(\d+), (\d+)/); 70 | 71 | let xCoordinate = parseInt(matchGroups[1]); 72 | let yCoordinate = parseInt(matchGroups[2]); 73 | 74 | let validX = xCoordinate < maxXCoordinate && xCoordinate > minXCoordinate; 75 | let validY = yCoordinate < maxYCoordinate && yCoordinate > minYCoordinate; 76 | 77 | return validX && validY; 78 | }); 79 | }) 80 | .map(key => areas[key].length) 81 | .sort((a, b) => b - a)[0]; 82 | } 83 | 84 | module.exports = findLargestArea; -------------------------------------------------------------------------------- /day-6-chronal-coordinates/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const findLargestArea = require('./manhattan'); 3 | const findComprehensiveArea = require('./manhattan-two'); 4 | 5 | 6 | describe('Day Six Part One Find Largest Finite Area', () => { 7 | it('should return 17 with given coordinates', () => { 8 | let input = 9 | `1, 1 10 | 1, 6 11 | 8, 3 12 | 3, 4 13 | 5, 5 14 | 8, 9`; 15 | assert.strictEqual(findLargestArea(input), 17); 16 | }); 17 | }); 18 | 19 | describe('Day Six Part Two Find Largest Comprehensive Area', () => { 20 | it('should return 16 with given coordinates', () => { 21 | let input = 22 | `1, 1 23 | 1, 6 24 | 8, 3 25 | 3, 4 26 | 5, 5 27 | 8, 9`; 28 | assert.strictEqual(findComprehensiveArea(input, 32), 16); 29 | }); 30 | }); 31 | -------------------------------------------------------------------------------- /day-7-the-sum-of-its-parts/README.md: -------------------------------------------------------------------------------- 1 | # Day 7 - The Sum of Its Parts 2 | 3 | ## Part One 4 | You find yourself standing on a snow-covered coastline; apparently, you landed a little off course. The region is too hilly to see the North Pole from here, but you do spot some Elves that seem to be trying to unpack something that washed ashore. It's quite cold out, so you decide to risk creating a paradox by asking them for directions. 5 | 6 | "Oh, are you the search party?" Somehow, you can understand whatever Elves from the year 1018 speak; you assume it's Ancient Nordic Elvish. Could the device on your wrist also be a translator? "Those clothes don't look very warm; take this." They hand you a heavy coat. 7 | 8 | "We do need to find our way back to the North Pole, but we have higher priorities at the moment. You see, believe it or not, this box contains something that will solve all of Santa's transportation problems - at least, that's what it looks like from the pictures in the instructions." It doesn't seem like they can read whatever language it's in, but you can: "Sleigh kit. Some assembly required." 9 | 10 | "'Sleigh'? What a wonderful name! You must help us assemble this 'sleigh' at once!" They start excitedly pulling more parts out of the box. 11 | 12 | The instructions specify a series of steps and requirements about which steps must be finished before others can begin (your puzzle input). Each step is designated by a single letter. For example, suppose you have the following instructions: 13 | 14 | ``` 15 | Step C must be finished before step A can begin. 16 | Step C must be finished before step F can begin. 17 | Step A must be finished before step B can begin. 18 | Step A must be finished before step D can begin. 19 | Step B must be finished before step E can begin. 20 | Step D must be finished before step E can begin. 21 | Step F must be finished before step E can begin. 22 | ``` 23 | 24 | Visually, these requirements look like this: 25 | 26 | ``` 27 | -->A--->B-- 28 | / \ \ 29 | C -->D----->E 30 | \ / 31 | ---->F----- 32 | ``` 33 | Your first goal is to determine the order in which the steps should be completed. If more than one step is ready, choose the step which is first alphabetically. In this example, the steps would be completed as follows: 34 | 35 | Only C is available, and so it is done first. 36 | Next, both A and F are available. A is first alphabetically, so it is done next. 37 | Then, even though F was available earlier, steps B and D are now also available, and B is the first alphabetically of the three. 38 | After that, only D and F are available. E is not available because only some of its prerequisites are complete. Therefore, D is completed next. 39 | F is the only choice, so it is done next. 40 | Finally, E is completed. 41 | So, in this example, the correct order is CABDFE. 42 | 43 | In what order should the steps in your instructions be completed? 44 | 45 | ## Part Two 46 | As you're about to begin construction, four of the Elves offer to help. "The sun will set soon; it'll go faster if we work together." Now, you need to account for multiple people working on steps simultaneously. If multiple steps are available, workers should still begin them in alphabetical order. 47 | 48 | Each step takes 60 seconds plus an amount corresponding to its letter: A=1, B=2, C=3, and so on. So, step A takes 60+1=61 seconds, while step Z takes 60+26=86 seconds. No time is required between steps. 49 | 50 | To simplify things for the example, however, suppose you only have help from one Elf (a total of two workers) and that each step takes 60 fewer seconds (so that step A takes 1 second and step Z takes 26 seconds). Then, using the same instructions as above, this is how each second would be spent: 51 | 52 | ``` 53 | Second Worker 1 Worker 2 Done 54 | 0 C . 55 | 1 C . 56 | 2 C . 57 | 3 A F C 58 | 4 B F CA 59 | 5 B F CA 60 | 6 D F CAB 61 | 7 D F CAB 62 | 8 D F CAB 63 | 9 D . CABF 64 | 10 E . CABFD 65 | 11 E . CABFD 66 | 12 E . CABFD 67 | 13 E . CABFD 68 | 14 E . CABFD 69 | 15 . . CABFDE 70 | ``` 71 | 72 | Each row represents one second of time. The Second column identifies how many seconds have passed as of the beginning of that second. Each worker column shows the step that worker is currently doing (or . if they are idle). The Done column shows completed steps. 73 | 74 | Note that the order of the steps has changed; this is because steps now take time to finish and multiple workers can begin multiple steps simultaneously. 75 | 76 | In this example, it would take 15 seconds for two workers to complete these steps. 77 | 78 | With 5 workers and the 60+ second step durations described above, how long will it take to complete all of the steps? 79 | -------------------------------------------------------------------------------- /day-7-the-sum-of-its-parts/steps-two.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adriennetacke/advent-of-code-2018/af78cd4e98499dfdd8c1933ba367c31bdcd2fb3a/day-7-the-sum-of-its-parts/steps-two.js -------------------------------------------------------------------------------- /day-7-the-sum-of-its-parts/steps.js: -------------------------------------------------------------------------------- 1 | const steps = (input) => { 2 | let steps = input.split('\n'); 3 | 4 | let finalOrder = []; 5 | let allSteps = []; 6 | 7 | // Prepare parent-child relationships 8 | for (let i = 0; i < steps.length; i++) { 9 | const step = steps[i]; 10 | const matchGroups = step.match(/(\w+) (.) (\w+) (\w+) (\w+) (\w+) (\w+) (.)/); 11 | 12 | const parent = matchGroups[2]; 13 | const child = matchGroups[8]; 14 | 15 | if (!allSteps.find(x => x.step === parent)) { 16 | allSteps.push({ 17 | step: parent, 18 | children: [], 19 | parents: [] 20 | }); 21 | }; 22 | 23 | if (!allSteps.find(x => x.step === child)) { 24 | allSteps.push({ 25 | step: child, 26 | children: [], 27 | parents: [] 28 | }); 29 | }; 30 | 31 | const parentRelationship = allSteps.find(x => x.step === parent); 32 | 33 | if (!parentRelationship.children.includes(child)) { 34 | parentRelationship.children.push(child); 35 | }; 36 | 37 | const childRelationship = allSteps.find(x => x.step === child); 38 | 39 | if(!childRelationship.parents.includes(parent)) { 40 | childRelationship.parents.push(parent); 41 | } 42 | } 43 | 44 | while (allSteps.length) { 45 | let potentialStep = allSteps 46 | .filter(x => !x.parents.length) 47 | .map(y => y.step) 48 | .sort()[0]; 49 | 50 | finalOrder.push(potentialStep); 51 | allSteps.splice(allSteps.indexOf(allSteps.find(x => x.step === potentialStep)), 1); 52 | 53 | allSteps 54 | .filter(a => a.parents.includes(potentialStep)) 55 | .forEach(y => y.parents.splice(y.parents.indexOf(potentialStep), 1)); 56 | } 57 | 58 | return finalOrder.join(''); 59 | }; 60 | 61 | module.exports = steps; -------------------------------------------------------------------------------- /day-7-the-sum-of-its-parts/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | const steps = require('./steps'); 3 | 4 | describe('Day Seven Part One Steps', () => { 5 | it('should return CABDFE', () => { 6 | let input = 7 | `Step C must be finished before step A can begin. 8 | Step C must be finished before step F can begin. 9 | Step A must be finished before step B can begin. 10 | Step A must be finished before step D can begin. 11 | Step B must be finished before step E can begin. 12 | Step D must be finished before step E can begin. 13 | Step F must be finished before step E can begin.`; 14 | 15 | assert.strictEqual(steps(input), 'CABDFE'); 16 | }); 17 | 18 | }); -------------------------------------------------------------------------------- /day-8-memory-maneuver/README.md: -------------------------------------------------------------------------------- 1 | # Day 8 - Memory Maneuver 2 | 3 | ## Part One 4 | The sleigh is much easier to pull than you'd expect for something its weight. Unfortunately, neither you nor the Elves know which way the North Pole is from here. 5 | 6 | You check your wrist device for anything that might help. It seems to have some kind of navigation system! Activating the navigation system produces more bad news: "Failed to start navigation system. Could not read software license file." 7 | 8 | The navigation system's license file consists of a list of numbers (your puzzle input). The numbers define a data structure which, when processed, produces some kind of tree that can be used to calculate the license number. 9 | 10 | The tree is made up of nodes; a single, outermost node forms the tree's root, and it contains all other nodes in the tree (or contains nodes that contain nodes, and so on). 11 | 12 | Specifically, a node consists of: 13 | 14 | A header, which is always exactly two numbers: 15 | The quantity of child nodes. 16 | The quantity of metadata entries. 17 | Zero or more child nodes (as specified in the header). 18 | One or more metadata entries (as specified in the header). 19 | Each child node is itself a node that has its own header, child nodes, and metadata. For example: 20 | 21 | ``` 22 | 2 3 0 3 10 11 12 1 1 0 1 99 2 1 1 2 23 | A---------------------------------- 24 | B----------- C----------- 25 | D----- 26 | ``` 27 | 28 | In this example, each node of the tree is also marked with an underline starting with a letter for easier identification. In it, there are four nodes: 29 | 30 | A, which has 2 child nodes (B, C) and 3 metadata entries (1, 1, 2). 31 | B, which has 0 child nodes and 3 metadata entries (10, 11, 12). 32 | C, which has 1 child node (D) and 1 metadata entry (2). 33 | D, which has 0 child nodes and 1 metadata entry (99). 34 | The first check done on the license file is to simply add up all of the metadata entries. In this example, that sum is 1+1+2+10+11+12+2+99=138. 35 | 36 | What is the sum of all metadata entries? -------------------------------------------------------------------------------- /day-8-memory-maneuver/metadata-two.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adriennetacke/advent-of-code-2018/af78cd4e98499dfdd8c1933ba367c31bdcd2fb3a/day-8-memory-maneuver/metadata-two.js -------------------------------------------------------------------------------- /day-8-memory-maneuver/metadata.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/adriennetacke/advent-of-code-2018/af78cd4e98499dfdd8c1933ba367c31bdcd2fb3a/day-8-memory-maneuver/metadata.js -------------------------------------------------------------------------------- /day-8-memory-maneuver/test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "advent-of-code-2018", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "balanced-match": { 8 | "version": "1.0.0", 9 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 10 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 11 | "dev": true 12 | }, 13 | "brace-expansion": { 14 | "version": "1.1.11", 15 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 16 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 17 | "dev": true, 18 | "requires": { 19 | "balanced-match": "1.0.0", 20 | "concat-map": "0.0.1" 21 | } 22 | }, 23 | "browser-stdout": { 24 | "version": "1.3.1", 25 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 26 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 27 | "dev": true 28 | }, 29 | "commander": { 30 | "version": "2.15.1", 31 | "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 32 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", 33 | "dev": true 34 | }, 35 | "concat-map": { 36 | "version": "0.0.1", 37 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 38 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 39 | "dev": true 40 | }, 41 | "debug": { 42 | "version": "3.1.0", 43 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 44 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 45 | "dev": true, 46 | "requires": { 47 | "ms": "2.0.0" 48 | } 49 | }, 50 | "diff": { 51 | "version": "3.5.0", 52 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 53 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 54 | "dev": true 55 | }, 56 | "escape-string-regexp": { 57 | "version": "1.0.5", 58 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 59 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 60 | "dev": true 61 | }, 62 | "fs.realpath": { 63 | "version": "1.0.0", 64 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 65 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 66 | "dev": true 67 | }, 68 | "glob": { 69 | "version": "7.1.2", 70 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 71 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 72 | "dev": true, 73 | "requires": { 74 | "fs.realpath": "1.0.0", 75 | "inflight": "1.0.6", 76 | "inherits": "2.0.3", 77 | "minimatch": "3.0.4", 78 | "once": "1.4.0", 79 | "path-is-absolute": "1.0.1" 80 | } 81 | }, 82 | "growl": { 83 | "version": "1.10.5", 84 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 85 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 86 | "dev": true 87 | }, 88 | "has-flag": { 89 | "version": "3.0.0", 90 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 91 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 92 | "dev": true 93 | }, 94 | "he": { 95 | "version": "1.1.1", 96 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 97 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 98 | "dev": true 99 | }, 100 | "inflight": { 101 | "version": "1.0.6", 102 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 103 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 104 | "dev": true, 105 | "requires": { 106 | "once": "1.4.0", 107 | "wrappy": "1.0.2" 108 | } 109 | }, 110 | "inherits": { 111 | "version": "2.0.3", 112 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 113 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 114 | "dev": true 115 | }, 116 | "minimatch": { 117 | "version": "3.0.4", 118 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 119 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 120 | "dev": true, 121 | "requires": { 122 | "brace-expansion": "1.1.11" 123 | } 124 | }, 125 | "minimist": { 126 | "version": "0.0.8", 127 | "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 128 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 129 | "dev": true 130 | }, 131 | "mkdirp": { 132 | "version": "0.5.1", 133 | "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 134 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 135 | "dev": true, 136 | "requires": { 137 | "minimist": "0.0.8" 138 | } 139 | }, 140 | "mocha": { 141 | "version": "5.2.0", 142 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", 143 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", 144 | "dev": true, 145 | "requires": { 146 | "browser-stdout": "1.3.1", 147 | "commander": "2.15.1", 148 | "debug": "3.1.0", 149 | "diff": "3.5.0", 150 | "escape-string-regexp": "1.0.5", 151 | "glob": "7.1.2", 152 | "growl": "1.10.5", 153 | "he": "1.1.1", 154 | "minimatch": "3.0.4", 155 | "mkdirp": "0.5.1", 156 | "supports-color": "5.4.0" 157 | } 158 | }, 159 | "ms": { 160 | "version": "2.0.0", 161 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 162 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 163 | "dev": true 164 | }, 165 | "once": { 166 | "version": "1.4.0", 167 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 168 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 169 | "dev": true, 170 | "requires": { 171 | "wrappy": "1.0.2" 172 | } 173 | }, 174 | "path-is-absolute": { 175 | "version": "1.0.1", 176 | "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 177 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 178 | "dev": true 179 | }, 180 | "supports-color": { 181 | "version": "5.4.0", 182 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 183 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 184 | "dev": true, 185 | "requires": { 186 | "has-flag": "3.0.0" 187 | } 188 | }, 189 | "wrappy": { 190 | "version": "1.0.2", 191 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 192 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 193 | "dev": true 194 | } 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "advent-of-code-2018", 3 | "version": "1.0.0", 4 | "description": "Advent of Code 2018", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha day-**/test.js" 8 | }, 9 | "author": "Adrienne Tacke ", 10 | "license": "MIT", 11 | "dependencies": {}, 12 | "devDependencies": { 13 | "mocha": "^5.2.0" 14 | } 15 | } 16 | --------------------------------------------------------------------------------