├── .gitignore ├── README.md ├── day-01 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-02 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-03 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-04 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-05 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-06 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-07 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-08 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-09 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-10 ├── README.md ├── __snapshots__ │ └── index.test.js.snap ├── index.js ├── index.test.js └── input.txt ├── day-11 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── day-13 ├── README.md ├── index.js ├── index.test.js └── input.txt ├── package-lock.json ├── package.json └── utils ├── index.js └── index.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ✨🎄 Advent of Code 2022 🎄✨ 2 | 3 | Here are my solutions to the [Advent of Code 2022](https://adventofcode.com/2022) puzzles. The solutions are written in JavaScript using Node.js. 4 | 5 | ## Usage 6 | 7 | In this repository you can find my solutions for the puzzles. Each day's solution is located in its own directory. 8 | 9 | In these directories you will find: 10 | 11 | - `README.md`: the puzzle description 12 | - `input.txt`: my puzzle input; to use your own input text from the puzzle, you can copy/paste it in this file 13 | - `index.js`: my solution 14 | - `index.test.js`: tests for part 1 and part 2 of the puzzle, using the example in the description 15 | 16 | You can use `npm start ` to get the solutions for that day; e.g. `npm start 01` to get the first day. 17 | -------------------------------------------------------------------------------- /day-01/README.md: -------------------------------------------------------------------------------- 1 | # Day 1: Calorie Counting 2 | 3 | Santa's reindeer typically eat regular reindeer food, but they need a lot of [magical energy](https://adventofcode.com/2018/day/25) to deliver presents on Christmas. For that, their favorite snack is a special type of star fruit that only grows deep in the jungle. The Elves have brought you on their annual expedition to the grove where the fruit grows. 4 | 5 | To supply enough magical energy, the expedition needs to retrieve a minimum of fifty stars by December 25th. Although the Elves assure you that the grove has plenty of fruit, you decide to grab any fruit you see along the way, just in case. 6 | 7 | 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! 8 | 9 | The jungle must be too overgrown and difficult to navigate in vehicles or access from the air; the Elves' expedition traditionally goes on foot. As your boats approach land, the Elves begin taking inventory of their supplies. One important consideration is food - in particular, the number of _Calories_ each Elf is carrying (your puzzle input). 10 | 11 | The Elves take turns writing down the number of Calories contained by the various meals, snacks, rations, etc. that they've brought with them, one item per line. Each Elf separates their own inventory from the previous Elf's inventory (if any) by a blank line. 12 | 13 | For example, suppose the Elves finish writing their items' Calories and end up with the following list: 14 | 15 | ``` 16 | 1000 17 | 2000 18 | 3000 19 | 20 | 4000 21 | 22 | 5000 23 | 6000 24 | 25 | 7000 26 | 8000 27 | 9000 28 | 29 | 10000 30 | ``` 31 | 32 | This list represents the Calories of the food carried by five Elves: 33 | 34 | - The first Elf is carrying food with `1000`, `2000`, and `3000` Calories, a total of `6000` Calories. 35 | - The second Elf is carrying one food item with `4000` Calories. 36 | - The third Elf is carrying food with `5000` and `6000` Calories, a total of `11000` Calories. 37 | - The fourth Elf is carrying food with `7000`, `8000`, and `9000` Calories, a total of `24000` Calories. 38 | - The fifth Elf is carrying one food item with `10000` Calories. 39 | 40 | In case the Elves get hungry and need extra snacks, they need to know which Elf to ask: they'd like to know how many Calories are being carried by the Elf carrying the _most_ Calories. In the example above, this is `24000` (carried by the fourth Elf). 41 | 42 | Find the Elf carrying the most Calories. **How many total Calories is that Elf carrying?** 43 | 44 | ## Part Two 45 | 46 | By the time you calculate the answer to the Elves' question, they've already realized that the Elf carrying the most Calories of food might eventually run out of snacks. 47 | 48 | To avoid this unacceptable situation, the Elves would instead like to know the total Calories carried by the _top three_ Elves carrying the most Calories. That way, even if one of those Elves runs out of snacks, they still have two backups. 49 | 50 | In the example above, the top three Elves are the fourth Elf (with `24000` Calories), then the third Elf (with `11000` Calories), then the fifth Elf (with `10000` Calories). The sum of the Calories carried by these three elves is `45000`. 51 | 52 | Find the top three Elves carrying the most Calories. **How many Calories are those Elves carrying in total?** 53 | -------------------------------------------------------------------------------- /day-01/index.js: -------------------------------------------------------------------------------- 1 | import { getInput } from '../utils/index.js'; 2 | 3 | const sum = (nums) => nums.reduce((a, b) => a + b, 0); 4 | 5 | function getCaloriesByElves(input) { 6 | return input 7 | .split('\n\n') 8 | .map((line) => line.split('\n').map(Number)) 9 | .map(sum); 10 | } 11 | 12 | export function getMaxCalories(input) { 13 | return Math.max(...getCaloriesByElves(input)); 14 | } 15 | 16 | export function getTopThreeCalories(input) { 17 | const top3 = getCaloriesByElves(input) 18 | .sort((a, b) => b - a) 19 | .slice(0, 3); 20 | 21 | return sum(top3); 22 | } 23 | 24 | if (process.env.NODE_ENV !== 'test') { 25 | const input = getInput(import.meta.url); 26 | const answer1 = getMaxCalories(input); 27 | const answer2 = getTopThreeCalories(input); 28 | 29 | console.log(` 30 | #1 Find the Elf carrying the most Calories. 31 | How many total Calories is that Elf carrying? 32 | ${answer1} 33 | 34 | #2 Find the top three Elves carrying the most Calories. 35 | How many Calories are those Elves carrying in total? 36 | ${answer2} 37 | `); 38 | } 39 | -------------------------------------------------------------------------------- /day-01/index.test.js: -------------------------------------------------------------------------------- 1 | import { getMaxCalories, getTopThreeCalories } from './index.js'; 2 | 3 | const input = `1000 4 | 2000 5 | 3000 6 | 7 | 4000 8 | 9 | 5000 10 | 6000 11 | 12 | 7000 13 | 8000 14 | 9000 15 | 16 | 10000`; 17 | 18 | describe('getMaxCalories', () => { 19 | it('should return the total calories carried by the Elf carrying the most Calories', () => { 20 | expect(getMaxCalories(input)).toEqual(24000); 21 | }); 22 | }); 23 | 24 | describe('getTopThreeCalories', () => { 25 | it('should return the calories the top 3 Elves carrying in total', () => { 26 | expect(getTopThreeCalories(input)).toEqual(45000); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /day-02/README.md: -------------------------------------------------------------------------------- 1 | # Day 2: Rock Paper Scissors 2 | 3 | The Elves begin to set up camp on the beach. To decide whose tent gets to be closest to the snack storage, a giant [Rock Paper Scissors](https://en.wikipedia.org/wiki/Rock_paper_scissors) tournament is already in progress. 4 | 5 | Rock Paper Scissors is a game between two players. Each game contains many rounds; in each round, the players each simultaneously choose one of Rock, Paper, or Scissors using a hand shape. Then, a winner for that round is selected: Rock defeats Scissors, Scissors defeats Paper, and Paper defeats Rock. If both players choose the same shape, the round instead ends in a draw. 6 | 7 | Appreciative of your help yesterday, one Elf gives you an encrypted strategy guide (your puzzle input) that they say will be sure to help you win. "The first column is what your opponent is going to play: `A` for Rock, `B` for Paper, and `C` for Scissors. The second column--" Suddenly, the Elf is called away to help with someone's tent. 8 | 9 | The second column, you reason, must be what you should play in response: `X` for Rock, `Y` for Paper, and `Z` for Scissors. Winning every time would be suspicious, so the responses must have been carefully chosen. 10 | 11 | The winner of the whole tournament is the player with the highest score. Your _total score_ is the sum of your scores for each round. The score for a single round is the score for the _shape you selected_ (1 for Rock, 2 for Paper, and 3 for Scissors) plus the score for the _outcome of the round_ (0 if you lost, 3 if the round was a draw, and 6 if you won). 12 | 13 | Since you can't be sure if the Elf is trying to help you or trick you, you should calculate the score you would get if you were to follow the strategy guide. 14 | 15 | For example, suppose you were given the following strategy guide: 16 | 17 | ``` 18 | A Y 19 | B X 20 | C Z 21 | ``` 22 | 23 | This strategy guide predicts and recommends the following: 24 | 25 | - In the first round, your opponent will choose Rock (`A`), and you should choose Paper (Y). This ends in a win for you with a score of **8** (2 because you chose Paper + 6 because you won). 26 | - In the second round, your opponent will choose Paper (`B`), and you should choose Rock (`X`). This ends in a loss for you with a score of **1** (1 + 0). 27 | - The third round is a draw with both players choosing Scissors, giving you a score of 3 + 3 = **6**. 28 | 29 | In this example, if you were to follow the strategy guide, you would get a total score of **15** (8 + 1 + 6). 30 | 31 | **What would your total score be if everything goes exactly according to your strategy guide?** 32 | 33 | ## Part Two 34 | 35 | The Elf finishes helping with the tent and sneaks back over to you. "Anyway, the second column says how the round needs to end: `X` means you need to lose, `Y` means you need to end the round in a draw, and `Z` means you need to win. Good luck!" 36 | 37 | The total score is still calculated in the same way, but now you need to figure out what shape to choose so the round ends as indicated. The example above now goes like this: 38 | 39 | - In the first round, your opponent will choose Rock (`A`), and you need the round to end in a draw (`Y`), so you also choose Rock. This gives you a score of 1 + 3 = **4**. 40 | - In the second round, your opponent will choose Paper (`B`), and you choose Rock so you lose (`X`) with a score of 1 + 0 = **1**. 41 | - In the third round, you will defeat your opponent's Scissors with Rock for a score of 1 + 6 = **7**. 42 | 43 | Now that you're correctly decrypting the ultra top secret strategy guide, you would get a total score of `12`. 44 | 45 | Following the Elf's instructions for the second column, **what would your total score be if everything goes exactly according to your strategy guide?** 46 | -------------------------------------------------------------------------------- /day-02/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines } from '../utils/index.js'; 2 | 3 | // A: Rock 4 | // B: Paper 5 | // C: Scissors 6 | 7 | // X: Rock 8 | // Y: Paper 9 | // Z: Scissors 10 | 11 | function getScore([opponent, player]) { 12 | const scoreForShape = { X: 1, Y: 2, Z: 3 }; 13 | const scoreForOutcome = { 14 | A: { X: 3, Y: 6, Z: 0 }, 15 | B: { X: 0, Y: 3, Z: 6 }, 16 | C: { X: 6, Y: 0, Z: 3 }, 17 | }; 18 | const shapeScore = scoreForShape[player]; 19 | const outcomeScore = scoreForOutcome[opponent][player]; 20 | 21 | return shapeScore + outcomeScore; 22 | } 23 | 24 | function getPairs(input) { 25 | return splitLines(input).map((line) => line.split(' ')); 26 | } 27 | 28 | export function getTotalScore(input) { 29 | return getPairs(input).reduce((total, pair) => total + getScore(pair), 0); 30 | } 31 | 32 | // X: lose 33 | // Y: draw 34 | // Z: win 35 | 36 | function getPlayerByOutcome([opponent, desiredOutcome]) { 37 | const shapeForOutcome = { 38 | A: { X: 'Z', Y: 'X', Z: 'Y' }, 39 | B: { X: 'X', Y: 'Y', Z: 'Z' }, 40 | C: { X: 'Y', Y: 'Z', Z: 'X' }, 41 | }; 42 | const player = shapeForOutcome[opponent][desiredOutcome]; 43 | 44 | return player; 45 | } 46 | 47 | export function getCorrectTotalScore(input) { 48 | return getPairs(input) 49 | .map((pair) => [pair[0], getPlayerByOutcome(pair)]) 50 | .reduce((total, pair) => total + getScore(pair), 0); 51 | } 52 | 53 | if (process.env.NODE_ENV !== 'test') { 54 | const input = getInput(import.meta.url); 55 | const answer1 = getTotalScore(input); 56 | const answer2 = getCorrectTotalScore(input); 57 | 58 | console.log(` 59 | #1 What would your total score be if everything goes 60 | exactly according to your strategy guide? 61 | ${answer1} 62 | 63 | #2 Following the Elf's instructions for the second column, 64 | what would your total score be if everything goes exactly 65 | according to your strategy guide? 66 | ${answer2} 67 | `); 68 | } 69 | -------------------------------------------------------------------------------- /day-02/index.test.js: -------------------------------------------------------------------------------- 1 | import { getCorrectTotalScore, getTotalScore } from './index'; 2 | 3 | const input = `A Y 4 | B X 5 | C Z 6 | `; 7 | 8 | describe('getTotalScore', () => { 9 | it('should return the total score following the strategy guide', () => { 10 | expect(getTotalScore(input)).toEqual(15); 11 | }); 12 | }); 13 | 14 | describe('getCorrectTotalScore', () => { 15 | it('should return the total score following the instructions', () => { 16 | expect(getCorrectTotalScore(input)).toEqual(12); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /day-03/README.md: -------------------------------------------------------------------------------- 1 | # Day 3: Rucksack Reorganization 2 | 3 | One Elf has the important job of loading all of the [rucksacks](https://en.wikipedia.org/wiki/Rucksack) with supplies for the jungle journey. Unfortunately, that Elf didn't quite follow the packing instructions, and so a few items now need to be rearranged. 4 | 5 | Each rucksack has two large _compartments_. All items of a given type are meant to go into exactly one of the two compartments. The Elf that did the packing failed to follow this rule for exactly one item type per rucksack. 6 | 7 | The Elves have made a list of all of the items currently in each rucksack (your puzzle input), but they need your help finding the errors. Every item type is identified by a single lowercase or uppercase letter (that is, `a` and `A` refer to different types of items). 8 | 9 | The list of items for each rucksack is given as characters all on a single line. A given rucksack always has the same number of items in each of its two compartments, so the first half of the characters represent items in the first compartment, while the second half of the characters represent items in the second compartment. 10 | 11 | For example, suppose you have the following list of contents from six rucksacks: 12 | 13 | ``` 14 | vJrwpWtwJgWrhcsFMMfFFhFp 15 | jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL 16 | PmmdzqPrVvPwwTWBwg 17 | wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn 18 | ttgJtRGJQctTZtZT 19 | CrZsJsPPZsGzwwsLwLmpwMDw 20 | ``` 21 | 22 | - The first rucksack contains the items `vJrwpWtwJgWrhcsFMMfFFhFp`, which means its first compartment contains the items `vJrwpWtwJgWr`, while the second compartment contains the items `hcsFMMfFFhFp`. The only item type that appears in both compartments is lowercase `p`. 23 | - The second rucksack's compartments contain `jqHRNqRjqzjGDLGL` and `rsFMfFZSrLrFZsSL`. The only item type that appears in both compartments is uppercase `L`. 24 | - The third rucksack's compartments contain `PmmdzqPrV` and `vPwwTWBwg`; the only common item type is uppercase `P`. 25 | - The fourth rucksack's compartments only share item type `v`. 26 | - The fifth rucksack's compartments only share item type `t`. 27 | - The sixth rucksack's compartments only share item type `s`. 28 | 29 | To help prioritize item rearrangement, every item type can be converted to a _priority_: 30 | 31 | Lowercase item types `a` through `z` have priorities 1 through 26. 32 | Uppercase item types `A` through `Z` have priorities 27 through 52. 33 | In the above example, the priority of the item type that appears in both compartments of each rucksack is 16 (`p`), 38 (`L`), 42 (`P`), 22 (`v`), 20 (`t`), and 19 (`s`); the sum of these is `157`. 34 | 35 | Find the item type that appears in both compartments of each rucksack. _What is the sum of the priorities of those item types?_ 36 | 37 | ## Part Two 38 | 39 | As you finish identifying the misplaced items, the Elves come to you with another issue. 40 | 41 | For safety, the Elves are divided into groups of three. Every Elf carries a badge that identifies their group. For efficiency, within each group of three Elves, the badge is the _only item type carried by all three Elves_. That is, if a group's badge is item type `B`, then all three Elves will have item type `B` somewhere in their rucksack, and at most two of the Elves will be carrying any other item type. 42 | 43 | The problem is that someone forgot to put this year's updated authenticity sticker on the badges. All of the badges need to be pulled out of the rucksacks so the new authenticity stickers can be attached. 44 | 45 | Additionally, nobody wrote down which item type corresponds to each group's badges. The only way to tell which item type is the right one is by finding the one item type that is _common between all three Elves_ in each group. 46 | 47 | Every set of three lines in your list corresponds to a single group, but each group can have a different badge item type. So, in the above example, the first group's rucksacks are the first three lines: 48 | 49 | ``` 50 | vJrwpWtwJgWrhcsFMMfFFhFp 51 | jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL 52 | PmmdzqPrVvPwwTWBwg 53 | ``` 54 | 55 | And the second group's rucksacks are the next three lines: 56 | 57 | ``` 58 | wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn 59 | ttgJtRGJQctTZtZT 60 | CrZsJsPPZsGzwwsLwLmpwMDw 61 | ``` 62 | 63 | In the first group, the only item type that appears in all three rucksacks is lowercase `r`; this must be their badges. In the second group, their badge item type must be `Z`. 64 | 65 | Priorities for these items must still be found to organize the sticker attachment efforts: here, they are 18 (`r`) for the first group and 52 (`Z`) for the second group. The sum of these is `70`. 66 | 67 | Find the item type that corresponds to the badges of each three-Elf group. **What is the sum of the priorities of those item types?** 68 | -------------------------------------------------------------------------------- /day-03/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines } from '../utils/index.js'; 2 | 3 | function splitItems(input) { 4 | return [input.slice(0, input.length / 2), input.slice(input.length / 2)]; 5 | } 6 | 7 | function findFirstCommonItem(strings) { 8 | const sets = strings.map((str) => new Set(str.split(''))); 9 | const commonLetters = [...sets[0]].filter((ch) => 10 | sets.every((set) => set.has(ch)), 11 | ); 12 | 13 | return commonLetters[0]; 14 | } 15 | 16 | function letterToPriority(ch) { 17 | const letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; 18 | 19 | return letters.indexOf(ch) + 1; 20 | } 21 | 22 | export function getSumOfPriorities(input) { 23 | return splitLines(input) 24 | .map(splitItems) 25 | .map(findFirstCommonItem) 26 | .map(letterToPriority) 27 | .reduce((a, b) => a + b, 0); 28 | } 29 | 30 | function groupItems(arr) { 31 | const groups = []; 32 | 33 | for (let i = 0; i < arr.length; i += 3) { 34 | groups.push(arr.slice(i, i + 3)); 35 | } 36 | 37 | return groups; 38 | } 39 | 40 | export function getSumOfGroupedPriorities(input) { 41 | return groupItems(splitLines(input)) 42 | .map(findFirstCommonItem) 43 | .map(letterToPriority) 44 | .reduce((a, b) => a + b, 0); 45 | } 46 | 47 | if (process.env.NODE_ENV !== 'test') { 48 | const input = getInput(import.meta.url); 49 | const answer1 = getSumOfPriorities(input); 50 | const answer2 = getSumOfGroupedPriorities(input); 51 | 52 | console.log(` 53 | #1 Find the item type that appears in both compartments 54 | of each rucksack. What is the sum of the priorities of 55 | those item types? 56 | ${answer1} 57 | 58 | #2 Find the item type that corresponds to the badges of 59 | each three-Elf group. What is the sum of the priorities 60 | of those item types? 61 | ${answer2} 62 | `); 63 | } 64 | -------------------------------------------------------------------------------- /day-03/index.test.js: -------------------------------------------------------------------------------- 1 | import { getSumOfPriorities, getSumOfGroupedPriorities } from './index'; 2 | 3 | const input = `vJrwpWtwJgWrhcsFMMfFFhFp 4 | jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL 5 | PmmdzqPrVvPwwTWBwg 6 | wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn 7 | ttgJtRGJQctTZtZT 8 | CrZsJsPPZsGzwwsLwLmpwMDw 9 | `; 10 | 11 | describe('getSumOfPriorities', () => { 12 | it('should return the sum of the priorities', () => { 13 | expect(getSumOfPriorities(input)).toEqual(157); 14 | }); 15 | }); 16 | 17 | describe('getSumOfGroupedPriorities', () => { 18 | it('should return the sum of the grouped priorities', () => { 19 | expect(getSumOfGroupedPriorities(input)).toEqual(70); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /day-03/input.txt: -------------------------------------------------------------------------------- 1 | BzRmmzZHzVBzgVQmZLPtqqffPqWqJmPLlL 2 | hpvvTDcrCjhpcrvcGGhfLHMlLtMCqflNlWPJlJ 3 | hGjhncHhGnhbTHczBBZVVSbRwgSgRV 4 | rWVQjPQQjGRWNSrWrPjcptwBpqqJBtJBBcZgMdtq 5 | zzmmpzfTCFpTlMlJJwBgMlqMBt 6 | TvLszpbhhTLmsnRQPDQGWDWRvQSR 7 | zGzvLlGlQHLGBQZlhBWhdjRdmdWRcjPj 8 | fTJNfTfNSRWPhjdjfj 9 | pbsbVVnpSnbVTprnbqqrzvLLgQlGLPLHll 10 | ZCCCsWvNvmsCsCmZLZmgMLRpQMhwQRpQRfphfprpTfpM 11 | tlncPjzlndctbzcPPBcjwDphwrfGGDffbDRpDTGG 12 | cdqnddwzqjNVWVLZZLZq 13 | DTLbDbRrlQbwhhNrmmfwdt 14 | zzMJMzjCjJJjvLjMPJpcgPpzfhHdfqWcqddwtwfqdttcNtdN 15 | pJCzVpCvDZBLsVRQ 16 | STzBBbJzRRBZBRTqCCsfZLtNNLClCsfh 17 | jsQnnQjjHcvQFrcPwCmtLCNlvDfftfff 18 | sGFscMQQMMpqzqbMbd 19 | QlNDWGsjQjgQllWQsbtzqTJczTJcbFmmFJJP 20 | MhLrhgLVndRmzJFzVqqJqP 21 | pSLnMdwhwdRZRSwhLZwLhdGWQjlsgWjNQWWSvgBsWDlj 22 | THjSRFSddTjdBTcPLcVVvVBw 23 | GzWnWfndWfznDfsnsBsPVwVwPPLL 24 | zNflzJWqqzQDdSStHNZNpFFtbj 25 | FSzDmsFSFlDlBzqVjqHHjHHpVgHLbp 26 | rTrTtTQQntRQnQJQgggHZttVgHLBLhZL 27 | WTJJRRQCRRJTRdBCRdvRNDFSWFMPmDlPPSsNPSzS 28 | WQldlMtMVQgVMQHnDGbHGGnRnQmD 29 | rqcZPrCFjmHlbGjZ 30 | zSScchqwchBzTzFzhhSlcCwNtdVWWJgsVdMtWNgNVWTJTd 31 | lMZqjMWllrTTspjprWWSSwgWNSVNDmWGVwFwgN 32 | cdCCdLHcnndHJnmCRntLBnRzDvFNtNDVzgSgwDgFNVzFVv 33 | BRLcCCJCmJdcRhfjPPZphrlrPqlZ 34 | GdGqcrrZGDrvDJJqJHcBvmFFgmFMMgMgBtMLTssLmF 35 | NbPVPDlljPmTmsTj 36 | VfQDhflCCRWdcrQwJvvnJv 37 | RLcWgLCqqPQLcqZwzHgwmmrmmtgwTw 38 | DhbhNrMpnJSDJwVTHmmTVnTTVj 39 | lrsvblMDlcWcfQPQ 40 | PVldlphHwGwJJGdjZZWsRbbsGsNWrWQbNbQR 41 | SqcDvTmDLtfmSmtqppfqzTgTQBrRQsbCFWbNNFQFBBrRbLNb 42 | MgtmTgtfpqVlnVddZMwV 43 | BdmfmPBPSbSNdGSdvWrwcZrccZPPcZnH 44 | jzzLsjsMRlQQVHwswvvZrCHrrT 45 | VqhzVFzplFlpLwpMphLRQQVRmSqgbdGtNJBmNSmgGbtggSgt 46 | DHVpNZjdZjFZWVFHpvFvzmlRzPnlfznFRz 47 | lrTBTsBwwMbrrwLPPfwGmGzvRf 48 | scrtMhMCtJBBBclbHdHttWZWDSqDSjHj 49 | wzqsPmqsbsfqBwPMNRMMZcZmFFNtZM 50 | CgCnhlvvLJgcRFNNBdCpWM 51 | QnQrVgHSvVHjbjTGBbbTHb 52 | HdrVrdqFDdZVmHgRmDRFHMnTdTssMGnLnPJLbPTbCs 53 | SczlScjwcNzplNzQSSfjwQSrTGGsbTsnTCnGTMCMLMGGbN 54 | wQlfjrhfhQFHqZhRZRtD 55 | RsfJDGJvzPNcjpddSWJWMd 56 | LLCbBCwCrCmVVnrmhQFmbVhdcdlWpjZzSpMdWSpcWczSBj 57 | rrLCbTwnHTvzvNGT 58 | wPhPhbCqqSCrtJDlqvlrJr 59 | RVVZddLFRZZcQLvJJtzptlgPJp 60 | TVQRZGVncFdTGWZdCNShHhfPNwwsWPwb 61 | dzLVzPSgrgDDDCMSMLLPwFmdTTcsvmwNwjNsHcFF 62 | nWBGntQfGNGBflWBBqlpRQGbWFvjwsbsFswbvTHjjbmHTc 63 | tBNJBnGBflQnDPJrPhDgrPVg 64 | VtWztWtqpqzWpWzqjNRjNpWTmrrmrSbnmJwSJwnMPrCSJVwM 65 | sDHsBDhBdsBZGcHvLHDLhhCSnRSwCJMZrPbmnMbJSCSR 66 | ccLRhgsLBdRsdHNTFFNNgqTglqzF 67 | hztlmDhPhgPlPNNgmZMCbmwwQjcwjjwMjVCd 68 | RSJRrRqnqQJFqvnTGrHCcHHCCHHbHHMcMvdM 69 | qGJsnQTRsStsftPlhPNl 70 | BFFBLPRCwsLwhlPlRmhcGGrbmmGjfNTTnp 71 | VJMVpzgqggJnrjmjNcMjmT 72 | VqdSZtQgZvtdzqHqHtVZdVQpCDWWFdwlRPDpWPPBCswlWD 73 | fCWCsjPzcbzwRSzVTzhhDLqvdg 74 | TmJtrNJrBLSLJqgS 75 | ptNTQFHrZlnpFPwsWMbRjCpcjR 76 | nJmQNCmbmlllmbClbfMLjMFqbGBsdLFq 77 | ZcgTWcTnMqqMTBqF 78 | tPgctSnPctZZgDWzZgQHwNmHlhlmzlQhlJlw 79 | ZpTCwpffdslvgShCBhqhRz 80 | FDMPnNFNmBPzvRPRBg 81 | nNgMrnnDGjDmJMmnFdZTTsdsrZrslcwcQr 82 | pTmczpCldcdDDnPttpvWSqbpJf 83 | jgjRZMGHhGLgQrjvPWzPJgJvzStbbq 84 | LGNLLNBBzcDFCBwwFC 85 | nJTTqnrNvTzNMzzNfqrTPrJnwpwPpZpsHccZVsBRpcVHwpcp 86 | bgDhgbghLWmFmStctVpZtBCVCCpfZp 87 | LLSgLGSjggFGbSSbmMnrvqvzjfzTNrJrqM 88 | RRpDmmPMTjwfGmJQgQ 89 | WsNscdnvvdVZFVnnrZbjjflwljlbzfGFjQjq 90 | NnLZsNnrrVVVcvdBLTPCPCRMwhPMBMPhCt 91 | lbVvzngGJnVbJHpHtHNPpdSQvc 92 | TsMBswFZsWMWBZMNwPtNNtRNHcNpSQ 93 | CcZCTrZDsjZTsTsshWhrWrTnfgbLDfJzVVLVVlgfnzfVGV 94 | JzTTRtJRZWmWjrMHCT 95 | DDFGlLGcGlSSSLsFGBspPBmNMBHMghmWNmWjWCmWtH 96 | nSSpnbsGlLDnpPsSSspFtVvffRQdVzqvvbqdfVQwRz 97 | sMhzszlHHDsWbthHDqsbJjpLNtmjVJmVLLVLVLBp 98 | nrTPrGwfPLdprzJzdL 99 | wgPQcTGGzgccwCgnRwgRChFhlWSDqWWQMWhssSsMQl 100 | NSNmwtpSpCpvMphCsr 101 | PHcRGPLJMrsvzsqG 102 | QHjbnRMcfbPbQZmlZgZlgBBQ 103 | cPRPbhQjbQRdtPQdLqLHqzFZjCFCqLjC 104 | mmfsnnwrfvwrfSNZFzHHLDCFNlLlqDlN 105 | wsmrwswwGTffMrBnmQttJtcMZQQtPJPbZc 106 | MvBPDDRRdnnvHPCHZLHZsFLL 107 | rmJcbVqbcjWwWjQHLzTZFTHSzFrpsz 108 | cmwllVqqGJbVVVmmqbQcmgRnRvGhGfgDRDZBBBvRdd 109 | nMvMhMnvhnbTZWSSZgHmGJDFmmNDzBmbNmdGBN 110 | rCsPLRCssRjrLLsrLlwRVrcNJQfDQfdBmmfNBGJNzmDPfB 111 | CRjCpLltgtJgJJWq 112 | jshCzJpjzTPpmCWvSlpfwHfSWglf 113 | LQMMNMnHtDtLVRvwwgRWlldgWD 114 | qHVrQNHVMFQtrrBBQMBcrrZsZbzCZhbbJZJsmmsmFPTC 115 | JZQZnsQNMqTngZqJBVfBfPPVBNrwvfPw 116 | SSmDstFjpDpCszDjcLLhrPVlGlrGGVBwrvwVPt 117 | FSssFcLjFjbmFFCzjLcFLRDnMJnTHRnZZTdWqZZWnMnRnZ 118 | GbHRHpldwGMpWhHpCMBlCbRdVSLhnqJLSrDPLPPLPDqVDrhh 119 | gvjWWQvgZFtQFFNqLnVnDnSJzzztDD 120 | ZccccfTsffHdWWdRWwsw 121 | ClCtbHMlnnPPlszV 122 | gSDWSLgWQWQJJNWqgtQjPsnfcdVcLVdVdzfzVzff 123 | WQgqtFQgDgQSFqJhqhSJvNDRrZMZHwHMCbZhTpZbGHMTMG 124 | pZJZlCQtHFhPfdNfCh 125 | zcmLSVczwcMcLDNFHdLPhPWH 126 | szvVVnBmnTGQtHTQ 127 | RVVCNDlNGzlGZqHGHWqWhGqQwH 128 | ZFLFTmpLvvmSqsbb 129 | TrfpBfJpJMlnnNfNZD 130 | qHHlDClHhltMqQsHDhHslGznwdTnzzwDGSdfnwGnwG 131 | mZRNcNcLLPNPBFFbbPmLmbZFSCVfJJTVndVfSwnRzznfTwCS 132 | CcCWFbbBLCWtgWgHjghqvv 133 | TjbzlnlFmfqCFFVVCRWr 134 | PhMcLpPDtMLpwPDvLPJbMhSgVCGqggVqQgCqCgCgSWvv 135 | btbZbNZhJDJJhDtwtsTTTmBzzBBmlNlmHj 136 | FqhjWtqlqmmsnFPTCvMCQMTTCjQd 137 | pfffRfLpgrgGgzrNVzzpGVzRCdMCPJbwwcVMbQPCJVMVdbww 138 | DGGDZRGrHggzSsFQnnWShmtH 139 | vtHVVMMrvVMVrSHvLgvlHcZFCnRCZcccZtRRZfJFCJ 140 | rdDjGsdTQDcNZfdncCRR 141 | rBDsTwBbjbmbbQswswPhqVmmSvpVhlvvqMhHhh 142 | vGBLrqMNvqSLBvvrNbllLHfwStWWtFttccjtRtjtcj 143 | MhCDJmhMDzmcRRcjzWfztH 144 | ZQDmDhVVCQbBVdVNMvvv 145 | ptCtCzhWPWptnhVzzpGZbZTjTjVjFGjVFgVl 146 | fQswRRffmRqZlgrqqFjjSgGg 147 | HwsQDNNsDsmRLLHmffsfvHptBnhtzCvhWpZWBdhnMdCh 148 | RlHzzTqczBPfbnvcpB 149 | wVtNwpSZstppwwMsZhsdnLvnbtBBmbnLFFdnmF 150 | WNQJMVWsZWwGJWhhSNrQzlgHrDCgQRHpCHrl 151 | RrZWpJZRrZpdTGstlchLGGlLMd 152 | NqjDPCQPnQCSvtMzSLhhjM 153 | nQVQDDDDfwBwNCVCNVFNpWpgJgrRTmLTmTmgRTWF 154 | SHMcrMHpcjGcjSrMMbvSvvSvwFTLJwJNtFGFWJNtDLFTLfWN 155 | zqRnPfzQCRzqsmRPzznhszzLtLwQwwFTgWWLDLgWFTwTNQ 156 | qVPZmRZhsCZPhZlRCqRRRCbfpccMBjvMVjdHjjMjSvdf 157 | VVQdHwBZLVltlddtBczhrzvGcWWFRwgsFG 158 | TDTTTqqTSSqjqnmTmPqPPmTmGhRszvsrzsjRsccgzrRzgWGF 159 | DpJPqpWqHbZpllpt 160 | cCSCFsnnZFnscDtNdJFJtJtdmb 161 | VgBqBsqRrHtNdzmNrt 162 | BGLLVVjRBsqPBfsGwPsMfSSZCSfTZTZQpSphfS 163 | plCHCHlgglHHGpNbtngNrDvBDpfQDBQfZDfWZVrr 164 | mTmMLhRfwhsLPQvQZDMZQBQWMB 165 | cwsssmqRTFFfFgtbCtGl 166 | LQPPrCPnMZwqtRMn 167 | cWTSlJWlcplJdDTdGdpDlGcGgqmtwwZtqRrNRRmRdNZqmgNq 168 | GSJcJSjsjTpsvWGWBHLLvVVBBBrFrzVz 169 | NVPCSPMNDSNFVSWCsJJJmpGmZZGLLcpZLHGGtsHt 170 | fwzlBBqghqvzqqlDrHbpHjZHmGZbLZrHLb 171 | dnBgnDqQvwRnSnnFMFMP 172 | BCbPsFFwCRHmDSBmWnvDDj 173 | phhZVzdpVfQZphhZpRhSVnjmrcvvnrWtDrvWDS 174 | TfQJMfLphMhJdfdzpQJRTPbwHHNlgbGwsTGgCP 175 | ttWLlnnvnNnBBtlTqWlpvpndQdZsQQFssFDdsRFdVdRNFQ 176 | jSgrScrbGZSGrrCGsFVMssFsPPFcDDMV 177 | bzSmJbfCZCbzLwllflwqtvvw 178 | zmFTJwFLPmzLztmjDzTJwfNrdFNrFppBSNRGNGdbrpBR 179 | gqlhWQgsZMsvqMlMMvsvqsNlLbcdppbrRpdbbcSrrbbr 180 | vssCgVgCsggZQZCgsnsqWgWvfJPDLwffwTPPmzTnjTPmPmwJ 181 | SpcRTPQLBLWpNNzjmmwwwRrR 182 | tGlfvGhfnbDlbqlChnfFMrwsmwNssTMHMHjFwv 183 | ZlhtCtffCdWcZWZVVT 184 | jTTCcWHWJNgCGTzTmnzrmnGn 185 | BwRRbFvtvvQmJJFMpMJr 186 | ZBBwLvqbBZsRsbVsZSqbcZdJjHHjhfPCJfJfHhgc 187 | VrnDSvvrLrfTdTLGfdRp 188 | zcJzmcFcHGfdGmWTVd 189 | tHsMhwPVctccHFHFcbSDbbPjnNbBnbvBQB 190 | QttWQwLTnLnWTtnffnLQSBFVjNvBjBFNgMdCsVWsjv 191 | pDqcmmRPHqgVBddjvN 192 | DcclzbcbPbJLnNTfnw 193 | plRcpsZDGlGZvWvMCNcLtttq 194 | SrfrwSjSVrSjwbmSrHzmHJCQQPQzqttNNQJMzJtqMW 195 | wSHVnfHfWwwHWFVfSnfgmmRsslFZZDBBGZsZsDTdGRTp 196 | qSFQSgQNgQBrBHHcrW 197 | VTmjVJLTwlTmwTVmsMJMVlJmPvcbvvbCBbGBPjGvBbBGWcbb 198 | DnJTZwmnZRhnpqNdWt 199 | dTVHjZLLZDVCfVHtLDDjQbscjWbSJMJPjsbWWb 200 | FnqrnmzzFllmsWwtsFtQMMFc 201 | lmqzzzngGmlNNBqGllzlBNRvptHHpTCHpDLpgDZdgvHvDD 202 | sdRZQbCfZTSTdlfTZCffccWPHPPcPPwLwctRnLWn 203 | BBJDzFVgCDrCJrqDJJhqJVVMLPHwcctFwcWHHGLcwGwGHnWc 204 | ghpJgqqjCZbQdZpd 205 | tbcpzbHSszcHBgqHGZgJJJhhww 206 | jfvdvRTffQQrrFCRFTnGwJRqNRZVpJGZLZggLh 207 | nQTjTnMndlTdQFMvnrClCnpzmzDtbbmBbcPSzzlmmtzP 208 | BqBqTCSTcqHsJHHM 209 | WWPGVPLtzVgWtjWPGzVjzVGcbDhPsRbDcsbJwNRswRDRss 210 | VQfWjfLFGWLjdFfVzTZZpJTpnmlTrSQlBl 211 | jLNsZjqSHCsGdsmpsm 212 | MvnVFzWMwMVWzfnVDwfBMfnnrCtdtPmPlRrdrJCJrtPDrrPD 213 | zznfFWwMfMfFMwVTMQFnQjhjgjSZhCNbLSTcHHgbbC 214 | GGtssttVmvnnGNMQrrVzgwVrCWMz 215 | FdhfhhcCDhHLfzclZMcrwcQMZM 216 | HHqqCBhHSSpdmjGqmGjtjtjj 217 | bbQLtGMQQtQRQtrDtGprrrbCqwplZhhqSqmdwvdzqqqhSmpS 218 | FsJjJBfnsJcFcFfjVPjWBzldqhqnlZZZzzhmnSvSnm 219 | JPcFfFWjFHJVVsVjPVscsDlLNRHGDbLRMRCDNrCGbG 220 | JdMdlMRJnTwdvcjv 221 | CDLHbNSzzLFgHvnTjrswBNBTNT 222 | QgbvzSFQmZQPQQRW 223 | NTBrNzrpjjjCwGbB 224 | FRbQlcvFvcRQQlRsMlRRRZjwCqMwjmjwJZdLJmjCZC 225 | cVPPQcvlWDNhrbPz 226 | VdbVtbbZJdtJVVdDVZmTLqqTSQvNLjjDShhvSG 227 | zplpnBnFpnrrlghGNpLNqHvqvjNj 228 | cWncllnlPFWzcMwtWWtsVLVRmJWCds 229 | ShLSTnZnTSttTSbLQdfSZTMwcDHwwcHnJvDHnlnlclMM 230 | NmPMsssRrVwjDclHJwwR 231 | gNNMWGzNmqGdtfZTbGGb 232 | sWNNlRHnmJtmntJt 233 | brbbBTbbFbCbqqGgBTrCfmQVVZfSSQQSVtJZSrVZ 234 | bbFqvbDvvGGLGbCCtBGDLbLlcPNHhhccPNcdPPchlsdR 235 | DCFvDvnCnNfMBmMMslDZML 236 | SQQQJHwpSgJSJHQWSWHqJWWbmcBBBLLTsmhhTcZbMhmlshcb 237 | RJRgpJHssgwSQHRqsQPGGjjtNCrrFvvnFjjPrP 238 | mThmsgjzTPjMpcvtWP 239 | GNNBVqVGNZbbNbNqqZQVNVNbWcpdtMCcpCtMWCdCPpQccmpp 240 | VSmNrmmbBfZVlsrssrLTRhRhTn 241 | TdmCvLDCpTRNTdFbbWnnSWCfhjbbzn 242 | GrrMsPVGcQHBGMbhjjSgWfHHDbjb 243 | BPBVqqrQPsQqwrrmmmJdRLDDqFRplT 244 | fpDDJljDlCfDTjprjrfbddWthCSCtdPPQFhSSSWW 245 | HsLZgMGbgBBsNzMvGbdVtVQzFRQSthhFPdtP 246 | sMBmGBmbNvLHGMnrDppTcJmcjpqljf 247 | ptSpSJQqpbNGGDDhcMWrlNHcZZWWls 248 | zRLRRRjvvgjHMMsMpWpc 249 | vmCPLCgwvwdnCzmvLbpTbVQqJJPbJPpTVq 250 | TJCfhhJVFffrJJQQllNWcvWhwvWD 251 | GPSGjjpLslBbpLpLqqqPDvdwvwvNzQWGzDDNdzGN 252 | msbRjbpPqsRpHnlZrmJlnVHT 253 | GGfFsCCTvGDsfTTrhsCMMzptZJMdpdgtrpdMcV 254 | LBlwBHPSqjwwlVggHpnMZcVHMt 255 | ZlZZlBbRPGGTGfmRsD 256 | CtCjbVvzQQZTWVdd 257 | MlSqWlmsmGBSHJHTDFHZ 258 | pcqsmsplwsqclwRtRWgtRnPPvb 259 | zCrzCrsdjrhGDCFqGDjRRPtpWfQQcpfQZcCZPp 260 | VSVwVMgLHHLTwMDTMMVnbWPRZQRcRQPptWnpbZcb 261 | MNBBBlSMvLVwTlVTFdNdhNhFsqsGDrzm 262 | rBLWTwTThWwVVDTwHBsZZWppvpGtpptppmRvFFFMFMfL 263 | qPPNCCbqcbcNqbqQjjJQqzjRpptmlpMGmMlJtftmtFHpMt 264 | QnCgzzQbbQqPcPQnncbdQdnVTwDssZgrShBTVgZZsBSDHT 265 | PFGJFqnfqmPgFJQPWdbLdpDRhbphWjDm 266 | rclNHvcrzCNwrWRprjdMMMph 267 | wsZHwZNvRRQsQqBV 268 | LqlGCPlPLTCPqqQlpqLlWfBfWgcHNRJRfWNsncGH 269 | VVtdwVtDDdVmhrdwSBmjbdzNHgfgJnNnsSnHsNffHgRsgR 270 | wVzhbjmDbDrwjdbztFDDthMCvqPppZQBQLZQTqTvFTvZ 271 | BnQnQFwRmRwmwdBSFDFnmSDVLCJTCTppVVmGLVTCLcgVpC 272 | ZlWvhvZjNrbNvqjNhlfPfqjCGHrsspggTpVLpsJCpcJVgg 273 | vPzNvqjWhqFzGSnRGMDG 274 | wZnMZzzZZchDRtVsqtCtwV 275 | WmWpWWmPPWrmrmBmWrTlTFPNVqVCRSDCQHcqVTtTqsSDSTSD 276 | PrppdFlWWlfrWmpWFffrdcGjJJGggnnhZGdLLgGGndvz 277 | FShHNmNhRhNJmBnQBQJrmP 278 | VTgzDTjwfffwzDvwlcczzVSJbQlBQSWBWCnPJPbJWWbC 279 | tzSVtzvSvGSRZqqFMNtpRR 280 | hPZhGDZpnCGtDhznjmLmdJffdNzJ 281 | glwsSrQwBvLdgLzdcj 282 | QsRbHllzzlHwHlBszWlTBFbpDPMhbPDVGpGFpPtFPp 283 | SRjStRDctgDSBzLvPvNrDhmPLr 284 | QqTHGTPJmmHmhNmH 285 | TGQZsTqFnQZCJTPsnJnZQMjVRBVtcVRSVRBlwccSCtBS 286 | bbsNsvsvnNPTRRllbblLqhtQCqQSLCGGHSqHNC 287 | wFpzFgqVzqVJWFDwqJDmSBBmHBHhShLQhCGSBCGH 288 | MJVpFMqgwMqRRbZsMbZMrP 289 | PPdDhvNDQdmgQPZmQVHHtHGGWVGbffWGvs 290 | MMLCTRRLlLclTLRMRLCwMLHWVctbVVHWWWFfVjVGsFWW 291 | MRSMMlpTJRqClBCRqBDnzqgQPnqgznZPZqbP 292 | MrMNPNNpjvdprWtrpMsthqBfqlnfqcGhVBqFRcnqFG 293 | QbDgSSQbgSDDmDVmlqSCRllRcFqnqfBl 294 | QVJbVmwwDQbzVTgbppNJNMWNjNNPrdpM 295 | WwJJNbtHfpLpVgZZPVFhZh 296 | vmmqlDvRvRfqBSrlzmmMjRBhcVhQVZhVghCQQQQTcTrPTP 297 | jSqMmqRzMDDjvqlBqsBMBmmwGNJwJnwLNfbGwddswnJtJH 298 | RLgRmRggbvbzzPmmRNmzsQWFtSGNtwSNQnntFwnnCw 299 | pDBrBHpHhlldphHBHhJVFSLnWWFJttCtQSttSS 300 | hfHrpphHBppfTvmzgMmbLbgf 301 | -------------------------------------------------------------------------------- /day-04/README.md: -------------------------------------------------------------------------------- 1 | # Day 4: Camp Cleanup 2 | 3 | Space needs to be cleared before the last supplies can be unloaded from the ships, and so several Elves have been assigned the job of cleaning up sections of the camp. Every section has a unique _ID number_, and each Elf is assigned a range of section IDs. 4 | 5 | However, as some of the Elves compare their section assignments with each other, they've noticed that many of the assignments _overlap_. To try to quickly find overlaps and reduce duplicated effort, the Elves pair up and make a _big list of the section assignments for each pair_ (your puzzle input). 6 | 7 | For example, consider the following list of section assignment pairs: 8 | 9 | ``` 10 | 2-4,6-8 11 | 2-3,4-5 12 | 5-7,7-9 13 | 2-8,3-7 14 | 6-6,4-6 15 | 2-6,4-8 16 | ``` 17 | 18 | For the first few pairs, this list means: 19 | 20 | - Within the first pair of Elves, the first Elf was assigned sections `2-4` (sections `2`, `3`, and `4`), while the second Elf was assigned sections `6-8` (sections `6`, `7`, `8`). 21 | - The Elves in the second pair were each assigned two sections. 22 | - The Elves in the third pair were each assigned three sections: one got sections `5`, `6`, and `7`, while the other also got `7`, plus `8` and `9`. 23 | 24 | This example list uses single-digit section IDs to make it easier to draw; your actual list might contain larger numbers. Visually, these pairs of section assignments look like this: 25 | 26 | ``` 27 | .234..... 2-4 28 | .....678. 6-8 29 | 30 | .23...... 2-3 31 | ...45.... 4-5 32 | 33 | ....567.. 5-7 34 | ......789 7-9 35 | 36 | .2345678. 2-8 37 | ..34567.. 3-7 38 | 39 | .....6... 6-6 40 | ...456... 4-6 41 | 42 | .23456... 2-6 43 | ...45678. 4-8 44 | ``` 45 | 46 | Some of the pairs have noticed that one of their assignments _fully contains_ the other. For example, `2-8` fully contains `3-7`, and `6-6` is fully contained by `4-6`. In pairs where one assignment fully contains the other, one Elf in the pair would be exclusively cleaning sections their partner will already be cleaning, so these seem like the most in need of reconsideration. In this example, there are `2` such pairs. 47 | 48 | **In how many assignment pairs does one range fully contain the other?** 49 | 50 | ## Part Two 51 | 52 | It seems like there is still quite a bit of duplicate work planned. Instead, the Elves would like to know the number of pairs that _overlap at all_. 53 | 54 | In the above example, the first two pairs (`2-4,6-8` and `2-3,4-5`) don't overlap, while the remaining four pairs `(5-7,7-9`, `2-8,3-7`, `6-6,4-6`, and `2-6,4-8`) do overlap: 55 | 56 | `5-7,7-9` overlaps in a single section, `7`. 57 | `2-8,3-7` overlaps all of the sections `3` through `7`. 58 | `6-6,4-6` overlaps in a single section, `6`. 59 | `2-6,4-8` overlaps in sections `4`, `5`, and `6`. 60 | 61 | So, in this example, the number of overlapping assignment pairs is `4`. 62 | 63 | **In how many assignment pairs do the ranges overlap?** 64 | -------------------------------------------------------------------------------- /day-04/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines } from '../utils/index.js'; 2 | 3 | function getRanges(line) { 4 | return line.split(',').map((line) => line.split('-').map(Number)); 5 | } 6 | 7 | function isFullyContained([a, b]) { 8 | return (a[0] <= b[0] && a[1] >= b[1]) || (b[0] <= a[0] && b[1] >= a[1]); 9 | } 10 | 11 | function isPartiallyContained([a, b]) { 12 | return a[0] <= b[1] && a[1] >= b[0]; 13 | } 14 | 15 | export function getFullyContained(input) { 16 | return splitLines(input) 17 | .map(getRanges) 18 | .map(isFullyContained) 19 | .filter(Boolean).length; 20 | } 21 | 22 | export function getPartiallyContained(input) { 23 | return splitLines(input) 24 | .map(getRanges) 25 | .map(isPartiallyContained) 26 | .filter(Boolean).length; 27 | } 28 | 29 | if (process.env.NODE_ENV !== 'test') { 30 | const input = getInput(import.meta.url); 31 | const answer1 = getFullyContained(input); 32 | const answer2 = getPartiallyContained(input); 33 | 34 | console.log(` 35 | #1 In how many assignment pairs does one range fully 36 | contain the other? 37 | ${answer1} 38 | 39 | #2 In how many assignment pairs do the ranges overlap? 40 | ${answer2} 41 | `); 42 | } 43 | -------------------------------------------------------------------------------- /day-04/index.test.js: -------------------------------------------------------------------------------- 1 | import { getFullyContained, getPartiallyContained } from './index'; 2 | 3 | const input = ` 4 | 2-4,6-8 5 | 2-3,4-5 6 | 5-7,7-9 7 | 2-8,3-7 8 | 6-6,4-6 9 | 2-6,4-8 10 | 5-5,5-8 11 | `; 12 | 13 | describe('getFullyContained', () => { 14 | it('should return the number of pairs where one range fully contains the other', () => { 15 | expect(getFullyContained(input)).toEqual(3); 16 | }); 17 | }); 18 | 19 | describe('getPartiallyContained', () => { 20 | it('should return the number of pairs where the ranges overlap', () => { 21 | expect(getPartiallyContained(input)).toEqual(5); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /day-04/input.txt: -------------------------------------------------------------------------------- 1 | 2-88,13-89 2 | 12-94,12-94 3 | 34-69,34-61 4 | 9-76,9-9 5 | 35-82,34-52 6 | 9-10,10-88 7 | 57-71,71-75 8 | 50-71,71-91 9 | 44-67,43-43 10 | 68-69,67-68 11 | 6-47,6-48 12 | 6-52,7-67 13 | 43-51,40-44 14 | 56-67,57-69 15 | 94-94,68-94 16 | 10-97,9-9 17 | 40-95,40-98 18 | 22-81,22-22 19 | 7-58,7-59 20 | 8-82,82-82 21 | 22-27,23-44 22 | 5-27,7-28 23 | 11-75,11-75 24 | 7-90,99-99 25 | 65-89,65-66 26 | 24-52,29-53 27 | 41-57,27-58 28 | 14-95,13-26 29 | 27-34,26-75 30 | 18-33,33-56 31 | 21-95,21-95 32 | 20-29,69-71 33 | 81-81,23-90 34 | 47-83,47-82 35 | 28-50,86-98 36 | 50-76,21-50 37 | 3-69,64-79 38 | 17-97,10-16 39 | 54-92,10-93 40 | 7-75,45-77 41 | 72-72,42-73 42 | 13-80,81-87 43 | 25-26,25-64 44 | 38-48,38-38 45 | 2-99,2-99 46 | 48-93,67-92 47 | 12-85,2-94 48 | 14-75,7-82 49 | 29-46,23-29 50 | 50-94,4-51 51 | 3-37,37-91 52 | 24-91,91-91 53 | 25-48,44-47 54 | 2-77,1-26 55 | 1-58,1-21 56 | 16-93,16-93 57 | 3-99,8-98 58 | 23-23,6-23 59 | 17-67,68-68 60 | 4-15,1-4 61 | 35-41,35-40 62 | 6-88,52-89 63 | 11-48,11-61 64 | 4-64,12-65 65 | 7-90,7-8 66 | 1-89,6-73 67 | 64-69,38-70 68 | 26-67,59-66 69 | 41-54,16-42 70 | 2-99,9-96 71 | 2-8,7-88 72 | 12-95,97-97 73 | 17-92,12-93 74 | 27-56,27-28 75 | 19-66,65-77 76 | 1-95,94-94 77 | 24-48,23-95 78 | 40-74,74-74 79 | 20-99,20-97 80 | 60-73,61-74 81 | 23-85,23-86 82 | 37-69,69-69 83 | 37-64,27-37 84 | 7-53,7-27 85 | 84-97,93-94 86 | 26-51,50-52 87 | 12-93,13-93 88 | 28-86,29-29 89 | 11-25,18-46 90 | 97-99,91-98 91 | 27-73,53-58 92 | 25-77,6-26 93 | 26-29,29-68 94 | 11-17,11-28 95 | 99-99,13-99 96 | 70-92,48-92 97 | 50-61,50-62 98 | 2-95,77-94 99 | 17-17,17-90 100 | 95-95,16-95 101 | 12-96,13-97 102 | 28-98,28-28 103 | 18-91,3-80 104 | 1-95,1-19 105 | 86-89,22-89 106 | 37-96,3-96 107 | 2-18,18-56 108 | 8-72,71-73 109 | 46-48,32-47 110 | 57-69,57-78 111 | 10-22,9-9 112 | 6-96,6-6 113 | 44-58,5-59 114 | 6-8,7-93 115 | 76-95,77-99 116 | 97-99,3-98 117 | 69-69,64-69 118 | 38-68,67-96 119 | 68-74,67-95 120 | 20-68,69-69 121 | 6-88,9-85 122 | 47-66,47-55 123 | 9-94,93-95 124 | 19-29,28-89 125 | 4-83,90-90 126 | 2-95,1-95 127 | 36-37,36-36 128 | 12-90,45-68 129 | 1-80,89-94 130 | 95-99,6-96 131 | 1-1,2-95 132 | 47-81,46-80 133 | 1-57,38-47 134 | 5-7,7-98 135 | 18-75,18-94 136 | 39-70,39-70 137 | 62-93,62-62 138 | 30-32,31-54 139 | 22-82,82-84 140 | 83-92,84-98 141 | 54-93,6-94 142 | 74-91,73-90 143 | 11-90,11-90 144 | 92-98,96-97 145 | 13-73,55-69 146 | 47-95,46-95 147 | 11-97,11-99 148 | 53-68,53-53 149 | 45-89,45-46 150 | 99-99,38-89 151 | 14-88,96-96 152 | 6-78,6-7 153 | 31-67,67-67 154 | 96-96,48-96 155 | 40-69,25-39 156 | 10-60,9-61 157 | 38-97,78-93 158 | 52-69,51-60 159 | 21-72,21-33 160 | 24-90,89-90 161 | 36-83,84-84 162 | 44-58,44-68 163 | 95-95,82-94 164 | 13-91,91-95 165 | 27-95,94-96 166 | 60-82,61-83 167 | 11-77,12-12 168 | 7-91,6-90 169 | 15-94,14-48 170 | 5-73,5-74 171 | 10-40,10-40 172 | 59-94,59-93 173 | 84-84,84-84 174 | 8-8,7-75 175 | 20-81,20-81 176 | 5-96,96-99 177 | 5-63,5-6 178 | 2-93,2-93 179 | 72-74,31-73 180 | 6-54,5-47 181 | 8-36,9-86 182 | 1-95,94-94 183 | 11-66,10-73 184 | 45-52,52-99 185 | 1-92,1-95 186 | 76-90,76-77 187 | 6-53,54-55 188 | 44-52,45-95 189 | 5-70,27-70 190 | 3-56,6-55 191 | 28-37,36-37 192 | 54-97,54-98 193 | 4-63,1-4 194 | 5-64,65-65 195 | 19-74,17-18 196 | 12-26,12-12 197 | 34-78,35-99 198 | 42-42,3-42 199 | 69-70,69-77 200 | 49-75,50-95 201 | 30-52,1-28 202 | 25-80,25-25 203 | 97-99,10-98 204 | 36-55,36-54 205 | 6-55,8-55 206 | 60-80,61-81 207 | 76-81,37-77 208 | 19-20,20-20 209 | 11-33,33-85 210 | 31-60,7-32 211 | 3-9,1-2 212 | 40-87,22-40 213 | 9-35,8-35 214 | 9-75,35-75 215 | 19-86,18-85 216 | 33-52,45-53 217 | 15-49,49-66 218 | 40-83,1-41 219 | 10-54,23-88 220 | 83-94,43-83 221 | 7-74,3-75 222 | 18-79,17-18 223 | 6-63,1-6 224 | 19-39,39-77 225 | 69-78,69-79 226 | 14-26,1-23 227 | 3-49,1-58 228 | 39-40,38-39 229 | 16-58,54-57 230 | 34-83,17-34 231 | 79-88,10-80 232 | 73-86,73-86 233 | 4-15,13-14 234 | 6-94,6-6 235 | 84-93,35-84 236 | 56-81,55-81 237 | 3-30,3-4 238 | 5-94,4-96 239 | 5-87,42-87 240 | 98-99,63-79 241 | 20-95,10-21 242 | 40-87,39-41 243 | 39-90,40-97 244 | 20-54,24-88 245 | 1-40,2-65 246 | 57-97,63-96 247 | 1-42,1-1 248 | 5-11,11-66 249 | 39-96,38-95 250 | 5-72,6-73 251 | 7-7,10-96 252 | 97-97,13-97 253 | 71-97,2-4 254 | 79-79,76-79 255 | 20-56,56-74 256 | 57-76,62-68 257 | 20-63,20-57 258 | 19-68,69-69 259 | 41-70,41-70 260 | 37-42,27-44 261 | 77-98,57-99 262 | 18-92,91-96 263 | 10-85,10-96 264 | 43-61,6-44 265 | 25-65,66-95 266 | 12-29,12-80 267 | 22-70,69-71 268 | 77-78,6-77 269 | 20-89,22-88 270 | 79-88,20-88 271 | 98-98,3-99 272 | 58-80,58-66 273 | 27-32,25-47 274 | 80-91,80-95 275 | 24-70,24-86 276 | 52-60,52-62 277 | 80-80,16-80 278 | 3-43,10-88 279 | 2-80,1-99 280 | 34-87,34-88 281 | 28-30,28-32 282 | 13-55,7-55 283 | 16-38,7-16 284 | 25-33,32-77 285 | 58-90,57-57 286 | 7-94,6-7 287 | 5-97,32-96 288 | 71-71,51-71 289 | 10-21,10-11 290 | 3-9,8-98 291 | 26-34,1-81 292 | 35-49,35-50 293 | 11-70,10-71 294 | 25-72,24-99 295 | 27-84,71-72 296 | 50-72,50-71 297 | 11-62,11-34 298 | 93-97,92-96 299 | 71-71,28-71 300 | 72-80,65-81 301 | 27-32,23-28 302 | 31-79,32-79 303 | 12-80,12-81 304 | 38-63,6-39 305 | 27-98,60-97 306 | 45-83,35-45 307 | 52-52,30-52 308 | 11-97,12-14 309 | 3-94,1-99 310 | 4-23,16-22 311 | 1-12,13-91 312 | 14-80,14-78 313 | 3-89,1-3 314 | 28-99,27-87 315 | 14-50,11-66 316 | 40-88,39-39 317 | 38-98,98-99 318 | 5-91,4-91 319 | 4-22,23-23 320 | 20-90,24-91 321 | 2-63,1-62 322 | 14-81,13-80 323 | 52-52,1-51 324 | 8-11,11-93 325 | 9-66,1-9 326 | 44-86,43-68 327 | 13-13,13-94 328 | 40-67,40-68 329 | 70-73,34-68 330 | 5-83,2-11 331 | 37-49,36-49 332 | 11-97,99-99 333 | 44-99,43-98 334 | 50-98,50-97 335 | 38-39,38-80 336 | 83-83,2-84 337 | 14-40,3-23 338 | 41-94,41-96 339 | 61-83,59-62 340 | 22-95,22-96 341 | 32-77,32-77 342 | 22-97,23-96 343 | 39-85,70-84 344 | 4-95,3-95 345 | 14-39,14-38 346 | 9-68,68-96 347 | 62-63,3-48 348 | 21-25,22-90 349 | 4-4,3-98 350 | 85-89,85-99 351 | 7-42,7-43 352 | 31-82,82-84 353 | 45-53,41-54 354 | 38-66,37-66 355 | 5-80,4-72 356 | 1-1,2-97 357 | 3-3,2-3 358 | 47-61,42-61 359 | 70-94,94-98 360 | 1-51,1-51 361 | 53-70,93-99 362 | 43-72,72-82 363 | 3-7,6-77 364 | 71-95,82-92 365 | 82-89,6-82 366 | 3-43,4-76 367 | 45-91,46-91 368 | 12-87,13-87 369 | 11-92,11-46 370 | 3-73,3-72 371 | 91-91,47-92 372 | 12-93,14-94 373 | 43-45,9-44 374 | 10-87,11-87 375 | 20-34,33-88 376 | 48-71,15-97 377 | 20-64,19-64 378 | 3-57,57-57 379 | 6-7,7-99 380 | 4-19,19-96 381 | 68-72,69-72 382 | 14-45,14-14 383 | 22-93,22-23 384 | 8-34,8-15 385 | 83-93,92-96 386 | 11-94,12-94 387 | 54-84,38-85 388 | 93-98,3-55 389 | 32-77,39-40 390 | 3-15,15-93 391 | 16-28,11-29 392 | 1-95,94-96 393 | 6-25,25-26 394 | 32-96,99-99 395 | 1-35,2-5 396 | 73-91,65-74 397 | 62-77,41-63 398 | 72-72,72-93 399 | 5-81,5-81 400 | 81-83,32-81 401 | 68-89,68-89 402 | 30-35,30-61 403 | 48-97,8-49 404 | 85-94,12-94 405 | 15-95,15-96 406 | 4-98,3-4 407 | 33-84,33-92 408 | 28-58,29-59 409 | 44-80,44-80 410 | 11-84,83-83 411 | 95-98,1-96 412 | 3-44,21-43 413 | 91-91,46-69 414 | 91-98,1-90 415 | 3-20,19-72 416 | 3-92,4-55 417 | 23-68,98-98 418 | 26-97,80-83 419 | 98-98,2-97 420 | 30-92,74-92 421 | 6-44,7-60 422 | 18-23,36-47 423 | 9-94,98-99 424 | 11-20,11-75 425 | 50-95,5-51 426 | 13-83,20-84 427 | 27-27,27-47 428 | 95-96,56-95 429 | 27-28,27-29 430 | 31-95,31-31 431 | 19-50,21-23 432 | 19-48,30-55 433 | 7-36,22-80 434 | 3-5,6-99 435 | 21-22,23-52 436 | 3-70,3-70 437 | 4-8,7-90 438 | 28-60,60-98 439 | 81-93,58-82 440 | 2-6,3-16 441 | 15-75,16-76 442 | 8-86,6-6 443 | 1-78,78-95 444 | 37-91,37-99 445 | 94-94,17-94 446 | 53-80,80-81 447 | 1-90,89-89 448 | 21-32,21-73 449 | 65-74,65-74 450 | 24-54,89-92 451 | 8-47,9-47 452 | 8-36,12-41 453 | 6-79,1-23 454 | 79-83,24-84 455 | 91-91,16-92 456 | 14-84,14-15 457 | 51-67,50-50 458 | 6-93,96-96 459 | 29-55,29-43 460 | 36-37,36-77 461 | 36-36,19-35 462 | 84-84,60-89 463 | 66-88,14-89 464 | 14-69,28-93 465 | 79-94,39-62 466 | 85-89,89-89 467 | 1-78,2-78 468 | 44-52,42-53 469 | 55-97,55-97 470 | 32-81,74-80 471 | 90-90,16-89 472 | 3-96,2-37 473 | 15-58,16-71 474 | 5-93,6-93 475 | 1-4,4-13 476 | 61-96,61-99 477 | 17-87,17-86 478 | 34-48,35-49 479 | 17-58,10-17 480 | 1-11,12-68 481 | 56-86,27-64 482 | 73-80,73-77 483 | 96-96,76-97 484 | 23-32,23-31 485 | 3-94,5-95 486 | 67-98,66-72 487 | 87-93,56-92 488 | 4-15,5-15 489 | 24-76,25-75 490 | 43-59,33-60 491 | 66-74,66-68 492 | 18-90,17-57 493 | 68-72,72-93 494 | 6-19,19-29 495 | 94-99,6-95 496 | 20-85,10-21 497 | 45-66,45-67 498 | 73-74,12-73 499 | 35-75,34-59 500 | 67-88,80-88 501 | 99-99,2-97 502 | 15-90,14-14 503 | 9-59,9-86 504 | 18-52,52-79 505 | 65-73,27-74 506 | 89-96,88-96 507 | 97-97,5-78 508 | 92-94,48-93 509 | 27-40,27-57 510 | 7-95,1-8 511 | 7-17,7-49 512 | 66-66,65-89 513 | 7-46,12-78 514 | 15-29,15-38 515 | 7-7,8-64 516 | 13-22,13-21 517 | 11-11,10-45 518 | 84-84,30-84 519 | 42-91,91-91 520 | 65-87,29-87 521 | 87-87,18-86 522 | 17-66,17-65 523 | 87-88,78-86 524 | 57-57,58-87 525 | 22-53,22-54 526 | 8-62,7-62 527 | 37-90,37-91 528 | 50-86,49-86 529 | 6-58,6-67 530 | 32-60,32-63 531 | 91-96,91-91 532 | 13-94,13-14 533 | 4-95,4-95 534 | 1-86,4-87 535 | 30-96,59-95 536 | 10-28,8-59 537 | 2-49,66-71 538 | 96-99,4-97 539 | 3-74,2-2 540 | 29-76,75-75 541 | 4-92,4-91 542 | 16-94,14-16 543 | 35-35,36-96 544 | 39-67,66-66 545 | 17-97,16-67 546 | 1-99,46-98 547 | 41-74,40-74 548 | 45-68,45-69 549 | 68-95,94-99 550 | 14-51,13-31 551 | 91-91,4-91 552 | 46-66,2-67 553 | 61-66,6-71 554 | 66-69,55-89 555 | 11-11,6-10 556 | 72-91,73-94 557 | 1-92,1-16 558 | 25-98,35-74 559 | 56-87,73-87 560 | 57-59,1-58 561 | 4-5,4-91 562 | 27-31,30-68 563 | 98-98,22-98 564 | 28-95,84-94 565 | 9-24,8-24 566 | 21-30,22-38 567 | 79-81,6-83 568 | 34-96,34-83 569 | 31-33,26-32 570 | 36-59,50-52 571 | 25-95,19-25 572 | 97-97,75-90 573 | 97-99,27-98 574 | 7-48,32-52 575 | 12-72,11-33 576 | 3-41,3-41 577 | 2-95,3-95 578 | 71-71,52-72 579 | 92-98,20-92 580 | 14-90,15-99 581 | 86-97,85-87 582 | 44-71,44-71 583 | 10-68,1-10 584 | 47-77,11-46 585 | 8-25,25-47 586 | 22-34,25-34 587 | 17-90,18-48 588 | 31-94,30-94 589 | 10-97,10-96 590 | 21-44,22-97 591 | 42-97,2-98 592 | 84-91,50-85 593 | 60-96,78-82 594 | 81-85,73-80 595 | 41-73,40-73 596 | 48-65,47-56 597 | 5-42,6-79 598 | 33-33,33-83 599 | 46-79,47-79 600 | 61-91,23-92 601 | 93-95,3-94 602 | 32-43,31-51 603 | 83-97,70-83 604 | 24-93,94-94 605 | 2-94,8-91 606 | 45-61,46-65 607 | 46-50,48-75 608 | 23-95,57-84 609 | 3-99,92-95 610 | 85-85,2-61 611 | 42-87,87-93 612 | 95-99,2-96 613 | 3-4,3-98 614 | 1-87,7-87 615 | 34-72,72-73 616 | 11-84,8-12 617 | 80-99,63-98 618 | 96-99,7-97 619 | 73-75,30-73 620 | 60-87,7-61 621 | 21-41,19-40 622 | 14-77,76-86 623 | 53-97,36-98 624 | 34-54,33-54 625 | 4-36,11-66 626 | 6-10,10-94 627 | 1-57,3-87 628 | 15-39,16-39 629 | 34-72,14-33 630 | 1-3,3-93 631 | 23-53,22-53 632 | 24-44,23-34 633 | 9-28,3-9 634 | 12-99,99-99 635 | 87-98,87-98 636 | 11-11,11-73 637 | 96-96,4-91 638 | 91-91,8-92 639 | 18-47,18-94 640 | 57-59,27-59 641 | 12-96,13-75 642 | 1-27,26-61 643 | 21-60,60-61 644 | 30-67,31-67 645 | 22-78,22-78 646 | 6-77,7-52 647 | 28-45,44-78 648 | 34-87,90-94 649 | 65-76,77-77 650 | 11-76,57-58 651 | 83-84,14-83 652 | 70-97,11-70 653 | 97-98,11-97 654 | 29-29,16-29 655 | 87-94,18-87 656 | 53-71,70-70 657 | 3-96,2-90 658 | 11-80,13-99 659 | 68-68,69-83 660 | 64-97,1-98 661 | 39-42,40-58 662 | 35-49,35-49 663 | 58-88,58-87 664 | 67-67,13-66 665 | 20-20,6-19 666 | 16-67,16-17 667 | 3-46,2-4 668 | 41-96,41-88 669 | 20-89,18-21 670 | 4-84,4-84 671 | 81-82,20-81 672 | 94-94,28-93 673 | 64-74,8-65 674 | 3-73,5-36 675 | 15-67,6-86 676 | 33-33,32-91 677 | 23-97,57-97 678 | 8-58,8-46 679 | 9-10,9-99 680 | 67-93,69-92 681 | 93-99,5-93 682 | 95-96,95-98 683 | 15-22,35-53 684 | 55-97,38-98 685 | 95-99,3-96 686 | 12-12,12-62 687 | 89-89,41-88 688 | 9-10,9-92 689 | 41-85,67-84 690 | 10-97,2-11 691 | 19-73,61-72 692 | 38-79,78-80 693 | 49-61,50-72 694 | 70-71,71-72 695 | 25-32,26-31 696 | 2-5,3-62 697 | 12-94,11-93 698 | 26-95,27-98 699 | 40-81,40-80 700 | 34-71,34-95 701 | 99-99,16-89 702 | 14-93,93-96 703 | 19-70,4-20 704 | 7-28,1-29 705 | 13-59,12-59 706 | 44-97,11-45 707 | 8-36,36-37 708 | 94-95,7-94 709 | 43-43,9-42 710 | 16-98,3-13 711 | 89-96,59-82 712 | 9-50,9-51 713 | 70-98,69-97 714 | 84-87,84-87 715 | 25-83,13-70 716 | 63-71,62-71 717 | 3-31,3-96 718 | 53-67,13-76 719 | 98-98,59-99 720 | 4-39,5-40 721 | 19-91,17-90 722 | 28-50,36-45 723 | 34-86,33-38 724 | 58-80,57-80 725 | 90-90,9-90 726 | 98-98,37-72 727 | 2-39,3-53 728 | 85-97,28-84 729 | 96-97,86-98 730 | 38-78,30-39 731 | 1-42,2-41 732 | 7-28,8-27 733 | 6-74,7-75 734 | 85-87,49-86 735 | 98-98,16-46 736 | 42-90,41-70 737 | 5-70,6-70 738 | 13-75,75-75 739 | 25-69,5-51 740 | 13-43,2-14 741 | 77-91,78-78 742 | 17-97,16-18 743 | 3-94,1-3 744 | 33-86,32-92 745 | 13-57,57-68 746 | 18-88,19-95 747 | 11-97,11-96 748 | 17-67,17-67 749 | 44-95,44-94 750 | 21-85,20-85 751 | 30-64,41-64 752 | 34-68,35-68 753 | 37-77,77-79 754 | 96-97,9-96 755 | 78-85,9-79 756 | 80-80,35-79 757 | 16-50,16-36 758 | 65-85,7-85 759 | 52-92,2-52 760 | 77-77,30-78 761 | 4-61,2-5 762 | 41-91,30-90 763 | 93-96,20-90 764 | 9-11,10-73 765 | 39-42,38-42 766 | 46-72,45-76 767 | 57-63,56-66 768 | 9-68,5-46 769 | 5-92,98-98 770 | 39-46,39-46 771 | 10-48,10-65 772 | 3-22,7-91 773 | 43-82,2-94 774 | 21-69,20-69 775 | 70-70,2-71 776 | 9-94,8-91 777 | 23-99,23-80 778 | 6-98,6-97 779 | 45-45,22-44 780 | 31-79,32-32 781 | 47-67,47-48 782 | 5-80,80-81 783 | 34-54,29-55 784 | 16-97,16-96 785 | 6-71,71-74 786 | 17-47,17-46 787 | 74-85,85-86 788 | 7-10,9-82 789 | 30-30,30-90 790 | 51-54,55-55 791 | 20-28,21-98 792 | 67-67,64-66 793 | 50-51,35-50 794 | 4-68,5-5 795 | 1-4,4-40 796 | 20-20,20-84 797 | 29-31,26-73 798 | 12-12,11-12 799 | 45-94,44-93 800 | 36-45,18-37 801 | 14-41,13-98 802 | 38-42,42-84 803 | 32-63,31-62 804 | 32-79,1-79 805 | 32-32,32-88 806 | 83-95,83-96 807 | 50-84,49-83 808 | 30-56,30-74 809 | 7-67,67-82 810 | 5-39,40-94 811 | 3-7,7-82 812 | 42-45,42-67 813 | 1-97,96-99 814 | 30-87,30-64 815 | 3-97,3-98 816 | 52-81,52-81 817 | 65-80,65-80 818 | 46-55,54-91 819 | 17-88,87-92 820 | 7-97,97-97 821 | 57-81,57-81 822 | 54-97,54-54 823 | 13-13,13-86 824 | 30-35,36-36 825 | 77-77,68-76 826 | 11-82,12-91 827 | 7-72,2-48 828 | 85-94,28-86 829 | 17-88,88-99 830 | 9-56,7-9 831 | 56-96,33-96 832 | 85-89,85-89 833 | 13-13,13-99 834 | 76-93,62-76 835 | 86-86,31-86 836 | 31-95,31-96 837 | 68-70,44-69 838 | 9-54,9-10 839 | 66-97,25-98 840 | 44-93,93-93 841 | 63-63,17-62 842 | 3-98,2-10 843 | 18-96,19-97 844 | 19-80,2-81 845 | 44-45,4-44 846 | 1-37,7-36 847 | 59-61,39-62 848 | 33-98,33-57 849 | 38-77,37-76 850 | 13-96,11-14 851 | 28-98,29-99 852 | 4-44,2-45 853 | 37-95,37-95 854 | 53-68,54-68 855 | 3-72,4-88 856 | 14-21,21-82 857 | 43-65,42-47 858 | 21-52,51-93 859 | 65-79,56-65 860 | 22-65,36-77 861 | 42-54,53-99 862 | 10-95,9-95 863 | 1-78,2-76 864 | 81-81,16-81 865 | 26-49,29-70 866 | 45-87,44-87 867 | 14-15,14-67 868 | 14-15,14-84 869 | 2-42,41-79 870 | 1-93,93-94 871 | 61-98,60-97 872 | 3-9,12-99 873 | 48-62,49-56 874 | 64-65,41-64 875 | 27-52,27-51 876 | 88-91,30-89 877 | 17-46,46-46 878 | 10-80,11-81 879 | 3-7,1-6 880 | 80-81,80-96 881 | 67-96,67-96 882 | 96-98,2-96 883 | 89-90,60-89 884 | 16-83,16-82 885 | 67-77,68-70 886 | 33-68,33-37 887 | 8-29,1-7 888 | 28-71,28-70 889 | 64-89,79-89 890 | 18-35,18-36 891 | 20-86,20-88 892 | 68-69,40-68 893 | 24-74,23-82 894 | 79-88,79-88 895 | 5-56,4-55 896 | 1-98,2-2 897 | 10-99,4-24 898 | 12-15,13-15 899 | 30-93,99-99 900 | 6-14,6-97 901 | 3-86,4-52 902 | 15-52,13-52 903 | 28-78,78-79 904 | 27-28,27-95 905 | 40-88,29-96 906 | 1-3,2-52 907 | 27-43,27-33 908 | 23-65,54-99 909 | 4-49,48-50 910 | 46-67,47-68 911 | 94-94,2-94 912 | 24-31,30-66 913 | 14-87,6-58 914 | 2-5,4-98 915 | 40-92,39-91 916 | 2-87,87-88 917 | 7-74,19-73 918 | 58-91,58-92 919 | 11-82,5-97 920 | 62-65,4-62 921 | 95-96,8-95 922 | 6-68,6-68 923 | 5-98,4-10 924 | 46-72,89-96 925 | 24-58,58-92 926 | 33-36,37-94 927 | 47-48,48-76 928 | 18-20,3-32 929 | 11-65,10-58 930 | 32-97,32-95 931 | 27-53,19-75 932 | 10-60,45-59 933 | 32-62,63-65 934 | 1-88,2-88 935 | 48-93,63-92 936 | 46-79,78-96 937 | 18-47,4-17 938 | 6-63,6-7 939 | 39-80,36-69 940 | 20-78,20-78 941 | 26-81,26-27 942 | 23-96,20-79 943 | 45-59,45-60 944 | 37-47,36-64 945 | 33-45,5-42 946 | 3-98,4-98 947 | 18-75,4-19 948 | 10-93,10-10 949 | 24-70,7-24 950 | 20-53,40-49 951 | 56-81,72-80 952 | 1-70,4-71 953 | 15-18,19-92 954 | 84-98,83-95 955 | 35-48,47-49 956 | 27-63,62-78 957 | 9-79,14-95 958 | 5-77,4-77 959 | 20-39,20-40 960 | 26-67,72-92 961 | 69-80,55-80 962 | 68-83,68-92 963 | 87-87,6-86 964 | 1-92,1-94 965 | 14-81,14-99 966 | 49-51,49-52 967 | 71-71,49-70 968 | 69-70,69-72 969 | 18-54,3-50 970 | 97-99,1-97 971 | 4-34,33-33 972 | 67-84,11-84 973 | 31-52,47-51 974 | 81-97,97-98 975 | 27-62,54-61 976 | 1-83,1-99 977 | 30-78,30-78 978 | 12-38,12-37 979 | 37-76,24-74 980 | 1-96,1-95 981 | 96-96,12-96 982 | 41-61,40-60 983 | 81-87,81-99 984 | 1-19,9-19 985 | 2-8,7-42 986 | 35-36,36-71 987 | 67-79,67-78 988 | 69-69,65-68 989 | 8-8,9-64 990 | 4-12,6-78 991 | 14-47,47-64 992 | 9-93,9-93 993 | 95-98,15-29 994 | 30-87,88-88 995 | 12-77,78-78 996 | 8-15,18-50 997 | 10-98,11-97 998 | 1-2,1-97 999 | 2-92,2-86 1000 | 50-50,50-87 1001 | -------------------------------------------------------------------------------- /day-05/README.md: -------------------------------------------------------------------------------- 1 | # Day 5: Supply Stacks 2 | 3 | The expedition can depart as soon as the final supplies have been unloaded from the ships. Supplies are stored in stacks of marked _crates_, but because the needed supplies are buried under many other crates, the crates need to be rearranged. 4 | 5 | The ship has a _giant cargo crane_ capable of moving crates between stacks. To ensure none of the crates get crushed or fall over, the crane operator will rearrange them in a series of carefully-planned steps. After the crates are rearranged, the desired crates will be at the top of each stack. 6 | 7 | The Elves don't want to interrupt the crane operator during this delicate procedure, but they forgot to ask her _which_ crate will end up where, and they want to be ready to unload them as soon as possible so they can embark. 8 | 9 | They do, however, have a drawing of the starting stacks of crates _and_ the rearrangement procedure (your puzzle input). For example: 10 | 11 | ``` 12 | [D] 13 | [N] [C] 14 | [Z] [M] [P] 15 | 1 2 3 16 | 17 | move 1 from 2 to 1 18 | move 3 from 1 to 3 19 | move 2 from 2 to 1 20 | move 1 from 1 to 2 21 | ``` 22 | 23 | In this example, there are three stacks of crates. Stack 1 contains two crates: crate `Z` is on the bottom, and crate `N` is on top. Stack 2 contains three crates; from bottom to top, they are crates `M`, `C`, and `D`. Finally, stack 3 contains a single crate, `P`. 24 | 25 | Then, the rearrangement procedure is given. In each step of the procedure, a quantity of crates is moved from one stack to a different stack. In the first step of the above rearrangement procedure, one crate is moved from stack 2 to stack 1, resulting in this configuration: 26 | 27 | ``` 28 | [D] 29 | [N] [C] 30 | [Z] [M] [P] 31 | 1 2 3 32 | ``` 33 | 34 | In the second step, three crates are moved from stack 1 to stack 3. Crates are moved _one at a time_, so the first crate to be moved (`D`) ends up below the second and third crates: 35 | 36 | ``` 37 | [Z] 38 | [N] 39 | [C] [D] 40 | [M] [P] 41 | 1 2 3 42 | ``` 43 | 44 | Then, both crates are moved from stack 2 to stack 1. Again, because crates are moved _one at a time_, crate `C` ends up below crate `M`: 45 | 46 | ``` 47 | [Z] 48 | [N] 49 | [M] [D] 50 | [C] [P] 51 | 1 2 3 52 | ``` 53 | 54 | Finally, one crate is moved from stack 1 to stack 2: 55 | 56 | ``` 57 | [Z] 58 | [N] 59 | [D] 60 | [C] [M] [P] 61 | 1 2 3 62 | ``` 63 | 64 | The Elves just need to know _which crate will end up on top of each stack_; in this example, the top crates are `C` in stack 1, `M` in stack 2, and `Z` in stack 3, so you should combine these together and give the Elves the message `CMZ`. 65 | 66 | **After the rearrangement procedure completes, what crate ends up on top of each stack?** 67 | 68 | ## Part Two 69 | 70 | As you watch the crane operator expertly rearrange the crates, you notice the process isn't following your prediction. 71 | 72 | Some mud was covering the writing on the side of the crane, and you quickly wipe it away. The crane isn't a CrateMover 9000 - it's a _CrateMover 9001_. 73 | 74 | The CrateMover 9001 is notable for many new and exciting features: air conditioning, leather seats, an extra cup holder, and _the ability to pick up and move multiple crates at once_. 75 | 76 | Again considering the example above, the crates begin in the same configuration: 77 | 78 | ``` 79 | [D] 80 | [N] [C] 81 | [Z] [M] [P] 82 | 1 2 3 83 | ``` 84 | 85 | Moving a single crate from stack 2 to stack 1 behaves the same as before: 86 | 87 | ``` 88 | [D] 89 | [N] [C] 90 | [Z] [M] [P] 91 | 1 2 3 92 | ``` 93 | 94 | However, the action of moving three crates from stack 1 to stack 3 means that those three moved crates _stay in the same order_, resulting in this new configuration: 95 | 96 | ``` 97 | [D] 98 | [N] 99 | [C] [Z] 100 | [M] [P] 101 | 1 2 3 102 | ``` 103 | 104 | Next, as both crates are moved from stack 2 to stack 1, they _retain their order_ as well: 105 | 106 | ``` 107 | [D] 108 | [N] 109 | [C] [Z] 110 | [M] [P] 111 | 1 2 3 112 | ``` 113 | 114 | Finally, a single crate is still moved from stack 1 to stack 2, but now it's crate `C` that gets moved: 115 | 116 | ``` 117 | [D] 118 | [N] 119 | [Z] 120 | [M] [C] [P] 121 | 1 2 3 122 | 123 | ``` 124 | 125 | In this example, the CrateMover 9001 has put the crates in a totally different order: `MCD`. 126 | 127 | Before the rearrangement process finishes, update your simulation so that the Elves know where they should stand to be ready to unload the final supplies. **After the rearrangement procedure completes, what crate ends up on top of each stack?** 128 | -------------------------------------------------------------------------------- /day-05/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines, Stack } from '../utils/index.js'; 2 | 3 | function groupItems(str) { 4 | const groups = []; 5 | 6 | for (let i = 0; i < str.length; i += 4) { 7 | groups.push(str.slice(i, i + 4)); 8 | } 9 | 10 | return groups; 11 | } 12 | 13 | function parseCrates(rawCrates) { 14 | const getCrateID = (item) => 15 | item.trim().length === 0 ? null : item.replace(/[\s+\[\]]/g, ''); 16 | 17 | const lines = rawCrates 18 | .split('\n') 19 | .reverse() 20 | .slice(1) 21 | .map(groupItems) 22 | .map((line) => line.map(getCrateID)); 23 | 24 | const stacks = Array(lines[0].length) 25 | .fill() 26 | .map(() => new Stack()); 27 | 28 | lines.forEach((line) => { 29 | line.forEach((char, i) => { 30 | if (char) { 31 | stacks[i].push(char); 32 | } 33 | }); 34 | }); 35 | 36 | return stacks; 37 | } 38 | 39 | function parseMoves(rawMoves) { 40 | function getMove(line) { 41 | const regex = /move (?\d+) from (?\d+) to (?\d+)/i; 42 | const { from, qty, to } = line.match(regex).groups; 43 | 44 | return { from: from - 1, qty: qty - 0, to: to - 1 }; 45 | } 46 | 47 | return splitLines(rawMoves).map(getMove); 48 | } 49 | 50 | function parseInput(input) { 51 | const [rawCrates, rawMoves] = input.split('\n\n'); 52 | 53 | return { 54 | crates: parseCrates(rawCrates), 55 | moves: parseMoves(rawMoves), 56 | }; 57 | } 58 | 59 | export function getTopCrates(input) { 60 | const { crates, moves } = parseInput(input); 61 | 62 | for (let move of moves) { 63 | for (let i = 0; i < move.qty; i++) { 64 | const item = crates[move.from].pop(); 65 | crates[move.to].push(item); 66 | } 67 | } 68 | 69 | return crates.map((stack) => stack.peek()).join(''); 70 | } 71 | 72 | export function getTopCrates9001(input) { 73 | const { crates, moves } = parseInput(input); 74 | 75 | for (let move of moves) { 76 | const popped = []; 77 | 78 | for (let i = 0; i < move.qty; i++) { 79 | popped.unshift(crates[move.from].pop()); 80 | } 81 | for (let i = 0; i < move.qty; i++) { 82 | crates[move.to].push(popped[i]); 83 | } 84 | } 85 | 86 | return crates.map((stack) => stack.peek()).join(''); 87 | } 88 | 89 | if (process.env.NODE_ENV !== 'test') { 90 | const input = getInput(import.meta.url); 91 | const answer1 = getTopCrates(input); 92 | const answer2 = getTopCrates9001(input); 93 | 94 | console.log(` 95 | #1 After the rearrangement procedure completes, what crate ends up 96 | on top of each stack? (CrateMover 9000) 97 | ${answer1} 98 | 99 | #2 After the rearrangement procedure completes, what crate ends up 100 | on top of each stack? (CrateMover 9001) 101 | ${answer2} 102 | `); 103 | } 104 | -------------------------------------------------------------------------------- /day-05/index.test.js: -------------------------------------------------------------------------------- 1 | import { getTopCrates, getTopCrates9001 } from './index.js'; 2 | 3 | const input = ` 4 | [D] 5 | [N] [C] 6 | [Z] [M] [P] 7 | 1 2 3 8 | 9 | move 1 from 2 to 1 10 | move 3 from 1 to 3 11 | move 2 from 2 to 1 12 | move 1 from 1 to 2 13 | `; 14 | 15 | describe('getTopCrates', () => { 16 | it('should return the top crates from each stack', () => { 17 | expect(getTopCrates(input)).toEqual('CMZ'); 18 | }); 19 | }); 20 | 21 | describe('getTopCrates9001', () => { 22 | it('should return the top crates from each stack', () => { 23 | expect(getTopCrates9001(input)).toEqual('MCD'); 24 | }); 25 | }); 26 | -------------------------------------------------------------------------------- /day-05/input.txt: -------------------------------------------------------------------------------- 1 | [T] [P] [J] 2 | [F] [S] [T] [R] [B] 3 | [V] [M] [H] [S] [F] [R] 4 | [Z] [P] [Q] [B] [S] [W] [P] 5 | [C] [Q] [R] [D] [Z] [N] [H] [Q] 6 | [W] [B] [T] [F] [L] [T] [M] [F] [T] 7 | [S] [R] [Z] [V] [G] [R] [Q] [N] [Z] 8 | [Q] [Q] [B] [D] [J] [W] [H] [R] [J] 9 | 1 2 3 4 5 6 7 8 9 10 | 11 | move 3 from 8 to 2 12 | move 3 from 1 to 5 13 | move 3 from 1 to 4 14 | move 2 from 7 to 4 15 | move 3 from 7 to 4 16 | move 8 from 5 to 7 17 | move 2 from 1 to 8 18 | move 7 from 3 to 2 19 | move 1 from 5 to 2 20 | move 1 from 6 to 7 21 | move 2 from 5 to 9 22 | move 1 from 9 to 1 23 | move 3 from 9 to 6 24 | move 5 from 6 to 2 25 | move 10 from 7 to 2 26 | move 3 from 8 to 9 27 | move 7 from 9 to 2 28 | move 1 from 1 to 2 29 | move 1 from 9 to 6 30 | move 1 from 4 to 1 31 | move 1 from 8 to 2 32 | move 11 from 4 to 2 33 | move 1 from 7 to 9 34 | move 1 from 4 to 6 35 | move 1 from 9 to 7 36 | move 1 from 1 to 3 37 | move 1 from 7 to 5 38 | move 1 from 4 to 9 39 | move 1 from 5 to 2 40 | move 1 from 3 to 8 41 | move 1 from 6 to 9 42 | move 1 from 8 to 6 43 | move 11 from 2 to 1 44 | move 1 from 6 to 8 45 | move 7 from 2 to 1 46 | move 14 from 2 to 7 47 | move 1 from 6 to 3 48 | move 1 from 8 to 2 49 | move 1 from 3 to 9 50 | move 7 from 7 to 1 51 | move 1 from 6 to 5 52 | move 5 from 7 to 6 53 | move 4 from 2 to 8 54 | move 3 from 6 to 7 55 | move 3 from 7 to 8 56 | move 9 from 1 to 3 57 | move 8 from 3 to 7 58 | move 1 from 3 to 1 59 | move 2 from 2 to 3 60 | move 1 from 6 to 7 61 | move 2 from 1 to 7 62 | move 7 from 1 to 6 63 | move 1 from 3 to 5 64 | move 2 from 5 to 3 65 | move 7 from 6 to 3 66 | move 9 from 7 to 5 67 | move 1 from 9 to 1 68 | move 4 from 8 to 5 69 | move 7 from 1 to 5 70 | move 4 from 7 to 2 71 | move 1 from 7 to 8 72 | move 1 from 6 to 4 73 | move 10 from 5 to 3 74 | move 8 from 5 to 1 75 | move 2 from 8 to 3 76 | move 2 from 8 to 9 77 | move 8 from 2 to 7 78 | move 4 from 9 to 8 79 | move 13 from 3 to 7 80 | move 1 from 5 to 3 81 | move 6 from 3 to 9 82 | move 10 from 1 to 9 83 | move 1 from 3 to 4 84 | move 6 from 9 to 7 85 | move 1 from 5 to 8 86 | move 14 from 7 to 6 87 | move 14 from 6 to 1 88 | move 13 from 1 to 8 89 | move 1 from 1 to 2 90 | move 9 from 8 to 9 91 | move 6 from 8 to 5 92 | move 2 from 4 to 6 93 | move 1 from 8 to 1 94 | move 2 from 2 to 1 95 | move 2 from 8 to 6 96 | move 3 from 1 to 2 97 | move 3 from 3 to 9 98 | move 16 from 9 to 1 99 | move 3 from 2 to 4 100 | move 3 from 7 to 2 101 | move 6 from 5 to 4 102 | move 5 from 7 to 3 103 | move 4 from 6 to 1 104 | move 10 from 2 to 9 105 | move 13 from 9 to 1 106 | move 5 from 7 to 2 107 | move 2 from 4 to 6 108 | move 1 from 9 to 1 109 | move 2 from 9 to 5 110 | move 2 from 6 to 8 111 | move 2 from 5 to 3 112 | move 1 from 8 to 3 113 | move 31 from 1 to 7 114 | move 2 from 1 to 5 115 | move 12 from 7 to 3 116 | move 11 from 3 to 2 117 | move 1 from 8 to 4 118 | move 6 from 4 to 5 119 | move 1 from 3 to 4 120 | move 8 from 3 to 2 121 | move 5 from 5 to 6 122 | move 2 from 6 to 7 123 | move 4 from 7 to 3 124 | move 1 from 6 to 9 125 | move 13 from 7 to 6 126 | move 13 from 2 to 3 127 | move 1 from 4 to 8 128 | move 10 from 2 to 3 129 | move 3 from 7 to 3 130 | move 2 from 2 to 1 131 | move 1 from 8 to 2 132 | move 2 from 4 to 7 133 | move 1 from 9 to 2 134 | move 3 from 7 to 3 135 | move 1 from 5 to 1 136 | move 2 from 5 to 2 137 | move 15 from 6 to 7 138 | move 4 from 1 to 9 139 | move 22 from 3 to 9 140 | move 7 from 3 to 9 141 | move 4 from 3 to 8 142 | move 4 from 9 to 4 143 | move 3 from 2 to 4 144 | move 5 from 7 to 1 145 | move 7 from 4 to 7 146 | move 2 from 8 to 4 147 | move 1 from 4 to 8 148 | move 3 from 1 to 5 149 | move 2 from 1 to 4 150 | move 1 from 2 to 9 151 | move 2 from 5 to 7 152 | move 1 from 5 to 9 153 | move 3 from 8 to 6 154 | move 8 from 7 to 1 155 | move 6 from 7 to 1 156 | move 10 from 1 to 9 157 | move 3 from 6 to 2 158 | move 2 from 1 to 3 159 | move 2 from 3 to 6 160 | move 3 from 7 to 4 161 | move 2 from 7 to 1 162 | move 1 from 2 to 5 163 | move 13 from 9 to 5 164 | move 12 from 9 to 3 165 | move 6 from 5 to 3 166 | move 2 from 9 to 1 167 | move 11 from 9 to 3 168 | move 1 from 4 to 6 169 | move 2 from 5 to 3 170 | move 1 from 1 to 8 171 | move 24 from 3 to 5 172 | move 2 from 9 to 3 173 | move 2 from 2 to 4 174 | move 1 from 9 to 2 175 | move 2 from 6 to 8 176 | move 5 from 3 to 5 177 | move 2 from 8 to 9 178 | move 1 from 9 to 8 179 | move 4 from 1 to 4 180 | move 1 from 9 to 4 181 | move 1 from 8 to 4 182 | move 1 from 8 to 4 183 | move 7 from 4 to 5 184 | move 1 from 1 to 8 185 | move 1 from 6 to 5 186 | move 35 from 5 to 4 187 | move 18 from 4 to 3 188 | move 6 from 4 to 3 189 | move 8 from 5 to 8 190 | move 8 from 8 to 1 191 | move 2 from 4 to 9 192 | move 23 from 3 to 1 193 | move 1 from 8 to 5 194 | move 1 from 9 to 1 195 | move 1 from 5 to 1 196 | move 1 from 9 to 4 197 | move 11 from 1 to 2 198 | move 16 from 4 to 5 199 | move 3 from 3 to 5 200 | move 9 from 2 to 5 201 | move 1 from 4 to 1 202 | move 2 from 2 to 6 203 | move 1 from 2 to 9 204 | move 1 from 6 to 2 205 | move 1 from 3 to 5 206 | move 1 from 3 to 9 207 | move 1 from 2 to 9 208 | move 23 from 1 to 5 209 | move 1 from 6 to 9 210 | move 1 from 9 to 8 211 | move 27 from 5 to 1 212 | move 1 from 9 to 3 213 | move 18 from 5 to 8 214 | move 6 from 5 to 7 215 | move 1 from 5 to 6 216 | move 1 from 9 to 8 217 | move 12 from 8 to 3 218 | move 1 from 1 to 4 219 | move 6 from 7 to 8 220 | move 1 from 6 to 3 221 | move 1 from 4 to 2 222 | move 2 from 1 to 8 223 | move 1 from 2 to 9 224 | move 8 from 3 to 2 225 | move 2 from 9 to 7 226 | move 5 from 2 to 7 227 | move 7 from 7 to 2 228 | move 2 from 8 to 2 229 | move 3 from 1 to 9 230 | move 5 from 1 to 2 231 | move 3 from 9 to 8 232 | move 3 from 8 to 7 233 | move 5 from 2 to 5 234 | move 2 from 7 to 6 235 | move 12 from 8 to 9 236 | move 12 from 1 to 4 237 | move 9 from 9 to 3 238 | move 4 from 5 to 8 239 | move 12 from 3 to 8 240 | move 1 from 7 to 9 241 | move 3 from 9 to 2 242 | move 1 from 4 to 7 243 | move 3 from 1 to 7 244 | move 7 from 4 to 6 245 | move 3 from 6 to 2 246 | move 2 from 7 to 9 247 | move 18 from 8 to 1 248 | move 2 from 4 to 7 249 | move 1 from 2 to 8 250 | move 1 from 8 to 2 251 | move 10 from 2 to 3 252 | move 3 from 9 to 8 253 | move 2 from 6 to 7 254 | move 13 from 3 to 1 255 | move 2 from 8 to 9 256 | move 28 from 1 to 8 257 | move 1 from 5 to 2 258 | move 1 from 4 to 3 259 | move 4 from 7 to 6 260 | move 5 from 6 to 7 261 | move 7 from 2 to 6 262 | move 1 from 9 to 6 263 | move 2 from 2 to 4 264 | move 1 from 9 to 1 265 | move 4 from 1 to 2 266 | move 3 from 2 to 5 267 | move 3 from 4 to 9 268 | move 3 from 5 to 7 269 | move 1 from 1 to 4 270 | move 6 from 7 to 6 271 | move 1 from 2 to 6 272 | move 1 from 4 to 1 273 | move 1 from 1 to 8 274 | move 3 from 9 to 4 275 | move 18 from 6 to 3 276 | move 4 from 3 to 6 277 | move 1 from 7 to 9 278 | move 1 from 6 to 9 279 | move 2 from 3 to 6 280 | move 1 from 9 to 6 281 | move 1 from 9 to 2 282 | move 6 from 6 to 8 283 | move 3 from 4 to 7 284 | move 2 from 7 to 2 285 | move 35 from 8 to 7 286 | move 3 from 3 to 1 287 | move 26 from 7 to 2 288 | move 10 from 3 to 9 289 | move 6 from 9 to 4 290 | move 3 from 1 to 2 291 | move 1 from 4 to 3 292 | move 4 from 4 to 1 293 | move 1 from 3 to 6 294 | move 1 from 8 to 3 295 | move 1 from 6 to 2 296 | move 1 from 3 to 2 297 | move 13 from 7 to 3 298 | move 3 from 1 to 4 299 | move 4 from 3 to 1 300 | move 3 from 1 to 9 301 | move 2 from 1 to 9 302 | move 10 from 2 to 9 303 | move 19 from 2 to 9 304 | move 6 from 3 to 9 305 | move 2 from 3 to 4 306 | move 2 from 2 to 6 307 | move 17 from 9 to 8 308 | move 1 from 2 to 8 309 | move 2 from 9 to 3 310 | move 2 from 6 to 7 311 | move 8 from 9 to 3 312 | move 5 from 4 to 5 313 | move 14 from 9 to 4 314 | move 1 from 2 to 3 315 | move 1 from 7 to 2 316 | move 2 from 9 to 3 317 | move 1 from 2 to 7 318 | move 5 from 5 to 1 319 | move 1 from 2 to 1 320 | move 1 from 3 to 1 321 | move 1 from 9 to 7 322 | move 3 from 7 to 2 323 | move 3 from 3 to 7 324 | move 1 from 2 to 4 325 | move 1 from 3 to 8 326 | move 1 from 2 to 4 327 | move 4 from 3 to 4 328 | move 16 from 8 to 9 329 | move 3 from 1 to 4 330 | move 21 from 4 to 6 331 | move 1 from 7 to 2 332 | move 1 from 8 to 2 333 | move 1 from 1 to 3 334 | move 6 from 6 to 7 335 | move 3 from 1 to 9 336 | move 3 from 7 to 3 337 | move 1 from 4 to 6 338 | move 1 from 4 to 7 339 | move 2 from 2 to 6 340 | move 1 from 8 to 6 341 | move 13 from 6 to 7 342 | move 1 from 2 to 3 343 | move 15 from 9 to 8 344 | move 6 from 6 to 3 345 | move 13 from 8 to 3 346 | move 4 from 9 to 4 347 | move 5 from 4 to 8 348 | move 19 from 3 to 9 349 | move 3 from 3 to 1 350 | move 5 from 8 to 9 351 | move 17 from 9 to 7 352 | move 1 from 1 to 8 353 | move 4 from 9 to 6 354 | move 3 from 3 to 8 355 | move 1 from 1 to 2 356 | move 3 from 3 to 1 357 | move 36 from 7 to 6 358 | move 1 from 1 to 2 359 | move 7 from 8 to 2 360 | move 24 from 6 to 5 361 | move 2 from 6 to 7 362 | move 1 from 3 to 2 363 | move 4 from 6 to 8 364 | move 19 from 5 to 1 365 | move 8 from 6 to 4 366 | move 7 from 2 to 5 367 | move 3 from 2 to 8 368 | move 15 from 1 to 6 369 | move 2 from 9 to 5 370 | move 2 from 7 to 8 371 | move 3 from 4 to 1 372 | move 4 from 5 to 6 373 | move 1 from 9 to 7 374 | move 1 from 8 to 3 375 | move 3 from 6 to 1 376 | move 2 from 4 to 7 377 | move 13 from 1 to 8 378 | move 1 from 3 to 7 379 | move 1 from 4 to 5 380 | move 19 from 8 to 6 381 | move 1 from 7 to 3 382 | move 8 from 5 to 8 383 | move 1 from 6 to 8 384 | move 3 from 5 to 9 385 | move 1 from 6 to 4 386 | move 3 from 4 to 7 387 | move 1 from 3 to 9 388 | move 4 from 7 to 9 389 | move 20 from 6 to 3 390 | move 1 from 8 to 4 391 | move 2 from 9 to 4 392 | move 2 from 9 to 2 393 | move 2 from 9 to 3 394 | move 13 from 6 to 9 395 | move 9 from 9 to 8 396 | move 2 from 6 to 3 397 | move 8 from 8 to 2 398 | move 2 from 7 to 3 399 | move 5 from 9 to 3 400 | move 12 from 3 to 5 401 | move 1 from 4 to 7 402 | move 8 from 2 to 4 403 | move 8 from 4 to 7 404 | move 2 from 2 to 6 405 | move 2 from 8 to 9 406 | move 2 from 6 to 8 407 | move 2 from 9 to 6 408 | move 2 from 6 to 9 409 | move 2 from 4 to 8 410 | move 2 from 9 to 2 411 | move 6 from 3 to 1 412 | move 2 from 2 to 9 413 | move 3 from 9 to 3 414 | move 8 from 7 to 2 415 | move 6 from 1 to 2 416 | move 8 from 3 to 8 417 | move 1 from 7 to 3 418 | move 5 from 3 to 8 419 | move 6 from 2 to 7 420 | move 3 from 7 to 6 421 | move 2 from 7 to 9 422 | move 1 from 7 to 8 423 | move 8 from 5 to 7 424 | move 7 from 2 to 1 425 | move 7 from 1 to 6 426 | move 7 from 7 to 9 427 | move 1 from 7 to 6 428 | move 2 from 3 to 9 429 | move 2 from 8 to 5 430 | move 25 from 8 to 5 431 | move 5 from 5 to 1 432 | move 1 from 6 to 4 433 | move 17 from 5 to 4 434 | move 5 from 5 to 4 435 | move 23 from 4 to 7 436 | move 2 from 5 to 2 437 | move 4 from 6 to 3 438 | move 6 from 3 to 7 439 | move 1 from 5 to 2 440 | move 1 from 1 to 7 441 | move 2 from 2 to 8 442 | move 2 from 2 to 9 443 | move 1 from 5 to 7 444 | move 4 from 1 to 6 445 | move 2 from 8 to 3 446 | move 2 from 9 to 4 447 | move 1 from 4 to 8 448 | move 7 from 9 to 1 449 | move 2 from 3 to 5 450 | move 28 from 7 to 4 451 | move 4 from 6 to 2 452 | move 2 from 6 to 2 453 | move 3 from 7 to 4 454 | move 2 from 5 to 6 455 | move 4 from 2 to 6 456 | move 9 from 6 to 5 457 | move 4 from 1 to 7 458 | move 1 from 6 to 2 459 | move 3 from 2 to 3 460 | move 1 from 8 to 6 461 | move 1 from 7 to 4 462 | move 2 from 3 to 4 463 | move 1 from 7 to 4 464 | move 2 from 1 to 6 465 | move 1 from 7 to 9 466 | move 1 from 7 to 9 467 | move 1 from 6 to 2 468 | move 7 from 5 to 8 469 | move 1 from 3 to 9 470 | move 1 from 5 to 2 471 | move 7 from 8 to 7 472 | move 4 from 4 to 8 473 | move 2 from 8 to 4 474 | move 2 from 2 to 7 475 | move 1 from 1 to 7 476 | move 1 from 5 to 6 477 | move 32 from 4 to 7 478 | move 2 from 6 to 5 479 | move 2 from 8 to 2 480 | move 1 from 2 to 1 481 | move 2 from 5 to 4 482 | move 1 from 2 to 5 483 | move 1 from 1 to 4 484 | move 4 from 4 to 3 485 | move 1 from 6 to 4 486 | move 1 from 5 to 4 487 | move 5 from 9 to 1 488 | move 4 from 3 to 5 489 | move 3 from 1 to 6 490 | move 2 from 9 to 5 491 | move 2 from 1 to 3 492 | move 15 from 7 to 1 493 | move 5 from 5 to 3 494 | move 1 from 5 to 2 495 | move 3 from 4 to 5 496 | move 2 from 5 to 9 497 | move 3 from 3 to 6 498 | move 3 from 3 to 4 499 | move 1 from 3 to 8 500 | move 1 from 9 to 3 501 | move 2 from 4 to 9 502 | move 1 from 5 to 3 503 | move 2 from 9 to 6 504 | move 1 from 8 to 1 505 | move 1 from 3 to 2 506 | move 1 from 4 to 9 507 | move 2 from 9 to 3 508 | move 9 from 1 to 3 509 | move 5 from 3 to 4 510 | move 2 from 1 to 3 511 | move 4 from 1 to 5 512 | move 1 from 2 to 8 513 | move 3 from 4 to 9 514 | -------------------------------------------------------------------------------- /day-06/README.md: -------------------------------------------------------------------------------- 1 | # Day 6: Tuning Trouble 2 | 3 | The preparations are finally complete; you and the Elves leave camp on foot and begin to make your way toward the star fruit grove. 4 | 5 | As you move through the dense undergrowth, one of the Elves gives you a handheld _device_. He says that it has many fancy features, but the most important one to set up right now is the _communication system_. 6 | 7 | However, because he's heard you have [significant](https://adventofcode.com/2016/day/6) [experience](https://adventofcode.com/2016/day/25) [dealing](https://adventofcode.com/2019/day/7) [with](https://adventofcode.com/2019/day/9) [signal-based](https://adventofcode.com/2019/day/16) [systems](https://adventofcode.com/2021/day/25), he convinced the other Elves that it would be okay to give you their one malfunctioning device - surely you'll have no problem fixing it. 8 | 9 | As if inspired by comedic timing, the device emits a few colorful sparks. 10 | 11 | To be able to communicate with the Elves, the device needs to _lock on to their signal_. The signal is a series of seemingly-random characters that the device receives one at a time. 12 | 13 | To fix the communication system, you need to add a subroutine to the device that detects a _start-of-packet marker_ in the datastream. In the protocol being used by the Elves, the start of a packet is indicated by a sequence of _four characters that are all different_. 14 | 15 | The device will send your subroutine a datastream buffer (your puzzle input); your subroutine needs to identify the first position where the four most recently received characters were all different. Specifically, it needs to report the number of characters from the beginning of the buffer to the end of the first such four-character marker. 16 | 17 | For example, suppose you receive the following datastream buffer: 18 | 19 | `mjqjpqmgbljsphdztnvjfqwrcgsmlb` 20 | 21 | After the first three characters (`mjq`) have been received, there haven't been enough characters received yet to find the marker. The first time a marker could occur is after the fourth character is received, making the most recent four characters `mjqj`. Because `j` is repeated, this isn't a marker. 22 | 23 | The first time a marker appears is after the _seventh_ character arrives. Once it does, the last four characters received are `jpqm`, which are all different. In this case, your subroutine should report the value `7`, because the first start-of-packet marker is complete after 7 characters have been processed. 24 | 25 | Here are a few more examples: 26 | 27 | - `bvwbjplbgvbhsrlpgdmjqwftvncz`: first marker after character `5` 28 | - `nppdvjthqldpwncqszvftbrmjlhg`: first marker after character `6` 29 | - `nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg`: first marker after character `10` 30 | - `zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw`: first marker after character `11` 31 | 32 | **How many characters need to be processed before the first start-of-packet marker is detected?** 33 | 34 | ## Part Two 35 | 36 | Your device's communication system is correctly detecting packets, but still isn't working. It looks like it also needs to look for _messages_. 37 | 38 | A _start-of-message marker_ is just like a start-of-packet marker, except it consists of _14 distinct characters_ rather than 4. 39 | 40 | Here are the first positions of start-of-message markers for all of the above examples: 41 | 42 | - `mjqjpqmgbljsphdztnvjfqwrcgsmlb`: first marker after character `19` 43 | - `bvwbjplbgvbhsrlpgdmjqwftvncz`: first marker after character `23` 44 | - `nppdvjthqldpwncqszvftbrmjlhg`: first marker after character `23` 45 | - `nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg`: first marker after character `29` 46 | - `zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw`: first marker after character `26` 47 | 48 | **How many characters need to be processed before the first start-of-message marker is detected?** 49 | -------------------------------------------------------------------------------- /day-06/index.js: -------------------------------------------------------------------------------- 1 | import { getInput } from '../utils/index.js'; 2 | 3 | export function firstNonRepeatingSubstring(str, windowSize) { 4 | for (let i = 0; i < str.length; i++) { 5 | const substr = str.slice(i, i + windowSize); 6 | 7 | if (new Set(substr).size === windowSize) { 8 | return i + windowSize; 9 | } 10 | } 11 | 12 | return null; 13 | } 14 | 15 | if (process.env.NODE_ENV !== 'test') { 16 | const input = getInput(import.meta.url); 17 | const answer1 = firstNonRepeatingSubstring(input, 4); 18 | const answer2 = firstNonRepeatingSubstring(input, 14); 19 | 20 | console.log(` 21 | #1 How many characters need to be processed before the first 22 | start-of-packet marker is detected? 23 | ${answer1} 24 | 25 | #2 How many characters need to be processed before the first 26 | start-of-message marker is detected? 27 | ${answer2} 28 | `); 29 | } 30 | -------------------------------------------------------------------------------- /day-06/index.test.js: -------------------------------------------------------------------------------- 1 | import { firstNonRepeatingSubstring } from './index.js'; 2 | 3 | const testCases = [ 4 | { 5 | input: 'mjqjpqmgbljsphdztnvjfqwrcgsmlb', 6 | startOfMessage: 19, 7 | startOfPacket: 7, 8 | }, 9 | { 10 | input: 'bvwbjplbgvbhsrlpgdmjqwftvncz', 11 | startOfMessage: 23, 12 | startOfPacket: 5, 13 | }, 14 | { 15 | input: 'nppdvjthqldpwncqszvftbrmjlhg', 16 | startOfMessage: 23, 17 | startOfPacket: 6, 18 | }, 19 | { 20 | input: 'nznrnfrfntjfmvfwmzdfjlvtqnbhcprsg', 21 | startOfMessage: 29, 22 | startOfPacket: 10, 23 | }, 24 | { 25 | input: 'zcfzfwzzqfrljwzlrfnpqdbhtmscgvjw', 26 | startOfMessage: 26, 27 | startOfPacket: 11, 28 | }, 29 | ]; 30 | describe('firstNonRepeatingSubstring', () => { 31 | it('should return the start-of-packet marker', () => { 32 | for (let testCase of testCases) { 33 | expect(firstNonRepeatingSubstring(testCase.input, 4)).toEqual( 34 | testCase.startOfPacket, 35 | ); 36 | } 37 | }); 38 | 39 | it('should return the start-of-packet message', () => { 40 | for (let testCase of testCases) { 41 | expect(firstNonRepeatingSubstring(testCase.input, 14)).toEqual( 42 | testCase.startOfMessage, 43 | ); 44 | } 45 | }); 46 | }); 47 | -------------------------------------------------------------------------------- /day-06/input.txt: -------------------------------------------------------------------------------- 1 | pfptpztzfznzzznszzfgzgqgbgzgmzggwlwnlngnddjttzwtwmttlrrlqqzczpzhppmjmnjnfjnjjjprpfpnfpnpznzbbnwbbdsbswwwwszzzcmcttbftffczctztffppcvccbdbhbtbcbhbrbnrbrzbztbblvlvqvcqvcvcrcprrmffhfwfjwjrjtttvqqsttcwtthwthhqssbbqhhcbhbhqqwsqspqspprbrsrmmvhvvlsvspvpddbvdbdhhgshggfbgbrggzszsnshsvhsvhhnfnhfnhhbzzthtstdssdsrdsrdrtddsrdrcrgcgdcggdbbtgbgzbzwwnlngggspggspspjjfqflqqttjbbnffszfzjjlwjwhjwjccpllzztrzttdpdbbcnntwnnctnnrrgbrbvbccvzvlvnllvrvnnvmmtrmrddjdqdrqrmmvssgllsjsrrwggvcccgwwgddzldzldzdttqrrtggdngdgfdgfgzztdtthrttszzgjglldzdhdphppjfjfzfpfsflfggpwwwjdjssqdqmdmdpmmvbvfvpfpfwfpwfppbgbwgbbpmpwpzplpjpttnwnlnppcvchhmwwmllwppwspwspswpphhdhfhccwpcplpzzjwjssfrsssgnglnglnglngncgcvvpddrcrjrssznnjllslrlmllglpggwhhllzqzssvtsvvbpphpthphdhphnhdhdqdbbmcmqcmcmddtwtqqsbbzddtzdzrzmmfccdttlvljlffzczmzrrtzzrbrllfnfmfnnrcnnctcnnncbcrbccwcnwcnnrbnrrpnprrtwwvcwchwwcbwwwnpnvvgtvvqmvvhttrnnvjjtwtfwtwrrbpbmbmzmpphwphwwqwgwlwclwccjvccsllhhrtrstthvvfjjcvcdcbdcbczcttjbttwtvvvzjzgzwgwjjsnnvrrlbrrvnvdvhvchvvglvvpssdbsszddsqsspvpbpjjgghvvlwvlvggpjjmcjmmmhjmmrgrsgrsggchhcmmqsmsttlslqqmjjbpbrrcnrnbbvqvsvtvftvtmmqzzsnscsffnrnmrmnnszsllsrrrzrszsbbchccsrsmshhzrhrrdlrrjfmlrfhvqqvmpbrntgcqqsqvjmtctflbffddfbsjvzsfdwblprszhfvltwtcfsbdlwjgsmlcrvgstjqtrtnqzbmrmgqnscqjdfnbppcdgcsstwdmdvphsqmrfmzwntjgjjvcdgbhfjqlzglgjdsdlhwwrmfqcfsvhwwfmvprpnmjppvwzjwmddtndspzqjqrpbpnrjfwqfvbtqrgngcbjvhnfbtslcpppbsfhbcmwgpccftwhnbvdrzqdtwnrtjcdlnlmhvlzvljwrzgtfjrpgzjvggtpsvcdgtsvhdzvtfbwmnptfmllgcvfmmgvpbrgnhcnpwltqmjmltsbpzmfrttsmjqwhncvtqrsmcpsnrqzmwftbltllbhzhdfzmfgbvdtgwpvngsffjmwhfhmccfrjgqcqngzlnqvsgrcdzbsmjbmflwvhjldlrdvjrmgvjvpcczdhczpbtwphvhqmhcnljbwnzqwmbctffmctlcmhzcnvprdhtzdvgbhlnnjqzcwcsrgzjjlszssnplwqjlczvftmnbnmdpbjnctnslhgsjswqjwvprdstvbstlnnwwgvsffwmprjrlfccmtgvqbghvhcngwwtzwbwcdmrfstwhtfghgvzbfgtwjglcllwrhgdzptvrrbdhbscjhmtswshjmrsbpzstwmhrwwwncbbmjnjjlzrpdrzfvstbltszvlhcqbcpgbwtzzslsrljmhmtlcvzdbszvnjhrswrjrmfpsfpplwlrsnrpnjngmhwpwqcmtslhbmlsmjhcgmzznftmhvtmzlvmcwnbqtcntqghrqcsztsgzrnmrlvrnhtpmstdflpztmwltvgppttfwhhzzgrffjchswhbljvcjwvvnqnvdvjpsclhwsrtczvjmtcsnwvnwtdllphmrthddfvcjwvggqltmhglllmqzjsbjwgdqwzzmjnrmpbqplgzjgzcdqmtsntprdwwjwthcbsghqqspszndgqdmlzdlzwfcghtbhcqpbpmnfgqzmhtnttvjttvzhllsjvmmcmmppcgssjhnzqwpzdbtmrzsfbvgmgbtbwjrzvdlmgjpzltfmcclpltsszpqbllrwbwsnbhhvfwphrcpdvbjhgmgpphrdpcmjvfsjzrqldlqthwsztzcgttdnzcsbnszcsvmcspddlmwjttggdmlpqrdrfmwfzpdbnrwtmwssvbwtmzhndmhzwtlgdwpbrzghmlbszswqlpzldbvswjgtvjvmtjwdggfsbggbwhpwjdmflhmsgtbzrtbvlpqqmpcrbhflnfmwwsvdsgnnznfrqhqgqfgdfzcdqrtdftsntpbcclhncqjjwvszmssswnscwjlpfvdvltgcmqqttnfvbptbbmlrvrwwfbwwbvlrdrfmscqwdvdjgdrghwfjsttvwngzttzzsmzqnvzdfsvrbrcwtmmjdvnzjzdsnzgtszzcwdphnjmspmdsrqwgdwlzrgghcchpbltmwnjrbhqhzdqqmbrpggjjwnqfnnsqsfzbwqjsfprvrvfwbqvhgpjvqzplnhtqszqrtsvtbptfvzmvjhshbtmqbmqrrwplzphvdvhttlmftdwltqssstzlvnslzhnmjdlsbdprbgpjvcdtcfchzqqqcnngbrmntjwfbvcdcfgbcpnvcbbcvhqfzpsmgbcvrqvjlqlqnvvzdgphfpgtrpbbwztvqjgdpnpwbffdgqzmqvgblwzmdrhwdprhcqppcggrldhcdztnhspclfcwttnqslnzvvshcwgfztvscvztdrprvnlmfsgcpfdmfjgblnhrbsmjrjdzjwvwmlllvscsvfqvhdsdljrqphcvvtcttbwvnwwzwshdcfdqnjszltmddzjgmqgvpjzpzssrmfsrgjhvqtlhsfnndnqhpbcnltmdvlhfwqcmwnqbhsfqqwnfnnfjjbsqmcdrrvlfztdprnmjfhlvcdbjtczbrpljmpcwvchdwrqbwggjnrlhcdgzfwjzzjgfnbpwbpvswqdpcrthwfcffgztrjqntczfcbsrrtrjrwgbbgjshtzvjjlqqtsbgmpsttqjqwgmmbzhshqvvrcgbdsqmtqlrgjbnvbrpzdrgqnzstfdcvdnjhcnjblmsqtfvstlptgrczhbgpllpqwfdmthgjlltmlnltzpvjvjfgtrzslsptlfplgrgpjsbhbbbwlljfdjnhqcndlprfbwpvddndpnqwqccgbqmwlrffpzjpqclwcrgjgljwzpppwltcwdqdchghfnwbhrjndjsvlqnnmlrjfgfpnvgmlhbgnhnztpjzdmltfmjtzclsbspvhfngtjmzwrwmprdfplzzwfrdnbmbgvjlczcdvmpfmtqmzjrpfhjwwzmtnzmptwnhtlbndcpshqrqqrpccqpnvnqqdprvccmdmrsbptdhrhlpcptgfsfwphfpvbcrlnbrtgwcpgjclhhvpjhcwcgghlzbmpbswgtzqhmlwdfrrdfvnbhlqhvhnfjfndlqgrvhwnnnccvgdfqtwlmbwcpdtgscfpvmbdtcdmmgqrfjvnhngqsdtzhlbjwrrcrjfswwrgbhznlwhcjlsfprbqqcqmbdjhgjmmtqmjpldgqvptqcwjmlrjtjwdfbbvhpsnmfvdwnrntqzhfgfmrtgwgddpqvvdjqvrdwdwrsbjlbrmrjjbbpjpqgsjdzfjcrsnbmtmrstcrztzhgswgghwbfltdsvrcqvvjtmjwznnnwtsmshvbbpzwltrjpmbgsbqwphmwlhgpltsgjmgbdfrlhcbfjnvpvdwzccgdhswtgplcqnsjdwfbhbbpssvfrjbzmcphzjdncjgsvrcrplhqpnwdgfvrjqgfshdwrqjdvjmggtnnghqrccgddnzndcgpgpghtvrpwftfpttvgwqqcjbvnmqzlshdrdj 2 | -------------------------------------------------------------------------------- /day-07/README.md: -------------------------------------------------------------------------------- 1 | # Day 7: No Space Left On Device 2 | 3 | You can hear birds chirping and raindrops hitting leaves as the expedition proceeds. Occasionally, you can even hear much louder sounds in the distance; how big do the animals get out here, anyway? 4 | 5 | The device the Elves gave you has problems with more than just its communication system. You try to run a system update: 6 | 7 | ``` 8 | $ system-update --please --pretty-please-with-sugar-on-top 9 | Error: No space left on device 10 | ``` 11 | 12 | Perhaps you can delete some files to make space for the update? 13 | 14 | You browse around the filesystem to assess the situation and save the resulting terminal output (your puzzle input). For example: 15 | 16 | ``` 17 | $ cd / 18 | $ ls 19 | dir a 20 | 14848514 b.txt 21 | 8504156 c.dat 22 | dir d 23 | $ cd a 24 | $ ls 25 | dir e 26 | 29116 f 27 | 2557 g 28 | 62596 h.lst 29 | $ cd e 30 | $ ls 31 | 584 i 32 | $ cd .. 33 | $ cd .. 34 | $ cd d 35 | $ ls 36 | 4060174 j 37 | 8033020 d.log 38 | 5626152 d.ext 39 | 7214296 k 40 | ``` 41 | 42 | The filesystem consists of a tree of files (plain data) and directories (which can contain other directories or files). The outermost directory is called `/`. You can navigate around the filesystem, moving into or out of directories and listing the contents of the directory you're currently in. 43 | 44 | Within the terminal output, lines that begin with `$` are _commands you executed_, very much like some modern computers: 45 | 46 | - `cd` means _change directory_. This changes which directory is the current directory, but the specific result depends on the argument: 47 | - `cd x` moves _in_ one level: it looks in the current directory for the directory named `x` and makes it the current directory. 48 | - `cd ..` moves _out_ one level: it finds the directory that contains the current directory, then makes that directory the current directory. 49 | - `cd /` switches the current directory to the outermost directory, `/`. 50 | - `ls` means _list_. It prints out all of the files and directories immediately contained by the current directory: 51 | - `123 abc` means that the current directory contains a file named `abc` with size `123`. 52 | - `dir xyz` means that the current directory contains a directory named `xyz`. 53 | 54 | Given the commands and output in the example above, you can determine that the filesystem looks visually like this: 55 | 56 | ``` 57 | - / (dir) 58 | - a (dir) 59 | - e (dir) 60 | - i (file, size=584) 61 | - f (file, size=29116) 62 | - g (file, size=2557) 63 | - h.lst (file, size=62596) 64 | - b.txt (file, size=14848514) 65 | - c.dat (file, size=8504156) 66 | - d (dir) 67 | - j (file, size=4060174) 68 | - d.log (file, size=8033020) 69 | - d.ext (file, size=5626152) 70 | - k (file, size=7214296) 71 | ``` 72 | 73 | Here, there are four directories: `/` (the outermost directory), `a` and `d` (which are in `/`), and `e` (which is in `a`). These directories also contain files of various sizes. 74 | 75 | Since the disk is full, your first step should probably be to find directories that are good candidates for deletion. To do this, you need to determine the `total size` of each directory. The total size of a directory is the sum of the sizes of the files it contains, directly or indirectly. (Directories themselves do not count as having any intrinsic size.) 76 | 77 | The total sizes of the directories above can be found as follows: 78 | 79 | - The total size of directory `e` is _584_ because it contains a single file `i` of size 584 and no other directories. 80 | - The directory a has total size _94853_ because it contains files `f` (size 29116), `g` (size 2557), and `h.lst` (size 62596), plus file `i` indirectly (`a` contains `e` which contains `i`). 81 | - Directory `d` has total size _24933642_. 82 | - As the outermost directory, `/` contains every file. Its total size is _48381165_, the sum of the size of every file. 83 | 84 | To begin, find all of the directories with a total size of _at most 100000_, then calculate the sum of their total sizes. In the example above, these directories are `a` and `e`; the sum of their total sizes is _95437_ (94853 + 584). (As in this example, this process can count files more than once!) 85 | 86 | Find all of the directories with a total size of at most 100000. **What is the sum of the total sizes of those directories?** 87 | 88 | ## Part Two 89 | 90 | Now, you're ready to choose a directory to delete. 91 | 92 | The total disk space available to the filesystem is `70000000`. To run the update, you need unused space of at least `30000000`. You need to find a directory you can delete that will _free up enough space_ to run the update. 93 | 94 | In the example above, the total size of the outermost directory (and thus the total amount of used space) is `48381165`; this means that the size of the _unused_ space must currently be `21618835`, which isn't quite the `30000000` required by the update. Therefore, the update still requires a directory with total size of at least 8381165 to be deleted before it can run. 95 | 96 | To achieve this, you have the following options: 97 | 98 | - Delete directory `e`, which would increase unused space by `584`. 99 | - Delete directory `a`, which would increase unused space by `94853`. 100 | - Delete directory `d`, which would increase unused space by `24933642`. 101 | - Delete directory `/`, which would increase unused space by `48381165`. 102 | 103 | Directories `e` and `a` are both too small; deleting them would not free up enough space. However, directories `d` and `/` are both big enough! Between these, choose the smallest: `d`, increasing unused space by `24933642`. 104 | 105 | Find the smallest directory that, if deleted, would free up enough space on the filesystem to run the update. **What is the total size of that directory?** 106 | -------------------------------------------------------------------------------- /day-07/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines } from '../utils/index.js'; 2 | 3 | const ROOT = '.'; 4 | 5 | function getType(line) { 6 | if (line.startsWith('$')) return 'command'; 7 | if (line.startsWith('dir')) return 'directory'; 8 | return 'file'; 9 | } 10 | 11 | export function getDirectorySizes(input) { 12 | const lines = splitLines(input); 13 | const dirs = new Map(); 14 | let currentDirectory = [ROOT]; 15 | 16 | for (let line of lines) { 17 | if (getType(line) === 'command') { 18 | let [, command, arg] = line.split(' '); 19 | 20 | if (command === 'cd') { 21 | if (arg === '/') { 22 | currentDirectory.splice(1); 23 | } else if (arg === '..') { 24 | currentDirectory.pop(); 25 | } else { 26 | currentDirectory.push(arg); 27 | } 28 | } 29 | } 30 | 31 | if (getType(line) === 'file') { 32 | const [size] = line.split(' '); 33 | const key = currentDirectory.join('/'); 34 | 35 | dirs.set(key, (dirs.get(key) || 0) + Number(size)); 36 | 37 | if (currentDirectory.length > 1) { 38 | for (let i = currentDirectory.length - 1; i > 0; i--) { 39 | const parentKey = currentDirectory.slice(0, i).join('/'); 40 | 41 | dirs.set(parentKey, (dirs.get(parentKey) || 0) + Number(size)); 42 | } 43 | } 44 | } 45 | } 46 | 47 | return dirs; 48 | } 49 | 50 | export function getSumOfTotalSizes(dirs) { 51 | const MAX_DIR_SIZE = 100_000; 52 | let total = 0; 53 | 54 | for (let size of dirs.values()) { 55 | if (size <= MAX_DIR_SIZE) { 56 | total += size; 57 | } 58 | } 59 | 60 | return total; 61 | } 62 | 63 | export function getSmallestDirToDelete(dirs) { 64 | const TOTAL_DISKSPACE = 70_000_000; 65 | const UNUSED_SPACE = 30_000_000; 66 | const usedSpace = dirs.get(ROOT); 67 | const minRequired = UNUSED_SPACE - (TOTAL_DISKSPACE - usedSpace); 68 | let smallest = Infinity; 69 | 70 | for (let size of dirs.values()) { 71 | if (size >= minRequired && size < smallest) { 72 | smallest = size; 73 | } 74 | } 75 | 76 | return smallest; 77 | } 78 | 79 | if (process.env.NODE_ENV !== 'test') { 80 | const input = getInput(import.meta.url); 81 | const dirs = getDirectorySizes(input); 82 | const answer1 = getSumOfTotalSizes(dirs); 83 | const answer2 = getSmallestDirToDelete(dirs); 84 | 85 | console.log(` 86 | #1 What is the sum of the total sizes of the directories with 87 | a total size of at most 100000? 88 | ${answer1} 89 | 90 | #2 What is the size of the smallest directory that, if deleted, 91 | would free up enough space on the filesystem? 92 | ${answer2} 93 | `); 94 | } 95 | -------------------------------------------------------------------------------- /day-07/index.test.js: -------------------------------------------------------------------------------- 1 | import { 2 | getDirectorySizes, 3 | getSmallestDirToDelete, 4 | getSumOfTotalSizes, 5 | } from './index.js'; 6 | 7 | let input = `$ cd / 8 | $ ls 9 | dir a 10 | 14848514 b.txt 11 | 8504156 c.dat 12 | dir d 13 | $ cd a 14 | $ ls 15 | dir e 16 | 29116 f 17 | 2557 g 18 | 62596 h.lst 19 | $ cd e 20 | $ ls 21 | 584 i 22 | $ cd .. 23 | $ cd .. 24 | $ cd d 25 | $ ls 26 | 4060174 j 27 | 8033020 d.log 28 | 5626152 d.ext 29 | 7214296 k`; 30 | 31 | const dirs = getDirectorySizes(input); 32 | 33 | describe('getSumOfTotalSizes', () => { 34 | it('should return the sum of the total sizes of the directories with a total size of at most 100000', () => { 35 | expect(getSumOfTotalSizes(dirs)).toEqual(95437); 36 | }); 37 | }); 38 | 39 | describe('getSmallestDirToDelete', () => { 40 | it('should return the size of the smallest directory that, if deleted, would free up enough space on the filesystem', () => { 41 | expect(getSmallestDirToDelete(dirs)).toEqual(24933642); 42 | }); 43 | }); 44 | -------------------------------------------------------------------------------- /day-07/input.txt: -------------------------------------------------------------------------------- 1 | $ cd / 2 | $ ls 3 | dir cvt 4 | 4967 hcqbmwc.gts 5 | 5512 hsbhwb.clj 6 | dir hvfvt 7 | dir phwgv 8 | 277125 pwgswq.fld 9 | 42131 qdzr.btl 10 | dir svw 11 | 144372 vmbnlzgb.wbd 12 | dir zft 13 | $ cd cvt 14 | $ ls 15 | dir bbgsthsd 16 | 146042 bcqrmp.czf 17 | dir chhdjtlw 18 | dir cpcfcc 19 | dir dch 20 | dir djb 21 | dir djfww 22 | dir drdf 23 | dir fgbqtjlj 24 | dir hjsmmj 25 | 243293 hvfvt.qtb 26 | 245795 lrpb 27 | dir msptbrl 28 | 181756 qlqqmndd.zcb 29 | 18658 rtfzt.tjp 30 | dir slpc 31 | $ cd bbgsthsd 32 | $ ls 33 | 236957 djfww.fcb 34 | 112286 hcqbmwc.gts 35 | 106102 qggjrzts 36 | $ cd .. 37 | $ cd chhdjtlw 38 | $ ls 39 | 226927 cpcfcc 40 | 309815 djfww 41 | 117933 hcqbmwc.gts 42 | dir mbdrgfzs 43 | dir pbmcnpzf 44 | 131558 pwgswq.fld 45 | 298691 qlqqmndd.zcb 46 | $ cd mbdrgfzs 47 | $ ls 48 | 164331 hvfvt.dvq 49 | $ cd .. 50 | $ cd pbmcnpzf 51 | $ ls 52 | 102120 bjgg.cqd 53 | $ cd .. 54 | $ cd .. 55 | $ cd cpcfcc 56 | $ ls 57 | 15756 ddc 58 | dir dqc 59 | dir glm 60 | dir jbszm 61 | 200345 pwgswq.fld 62 | 145508 qlqqmndd.zcb 63 | dir vcptbw 64 | dir zrtm 65 | $ cd dqc 66 | $ ls 67 | dir cpcfcc 68 | 92063 mzp 69 | dir qmhnvmh 70 | dir snqqcjlw 71 | 8423 zdjwr.blc 72 | $ cd cpcfcc 73 | $ ls 74 | dir hvfvt 75 | $ cd hvfvt 76 | $ ls 77 | 289372 pwgswq.fld 78 | 307397 qlqqmndd.zcb 79 | $ cd .. 80 | $ cd .. 81 | $ cd qmhnvmh 82 | $ ls 83 | 274778 jczjwdl.smd 84 | 194322 ngrrfm 85 | $ cd .. 86 | $ cd snqqcjlw 87 | $ ls 88 | 182851 nprvrgd.tbb 89 | $ cd .. 90 | $ cd .. 91 | $ cd glm 92 | $ ls 93 | 188702 hpq.hgm 94 | $ cd .. 95 | $ cd jbszm 96 | $ ls 97 | 187645 pwgswq.fld 98 | $ cd .. 99 | $ cd vcptbw 100 | $ ls 101 | dir mgqd 102 | $ cd mgqd 103 | $ ls 104 | 157695 rhldvntj.jzm 105 | 268696 rjnngctw 106 | $ cd .. 107 | $ cd .. 108 | $ cd zrtm 109 | $ ls 110 | 218820 bcqrmp.czf 111 | 172319 czpsl.dnf 112 | 180114 hcqbmwc.gts 113 | 165216 hvfvt.nnw 114 | dir zft 115 | $ cd zft 116 | $ ls 117 | 161245 dtqjg.czv 118 | 249888 hpq.hgm 119 | 192037 zft 120 | $ cd .. 121 | $ cd .. 122 | $ cd .. 123 | $ cd dch 124 | $ ls 125 | dir djfww 126 | dir fzqgwwnf 127 | dir hqvmq 128 | dir mmcrzqc 129 | 42136 qlqqmndd.zcb 130 | dir vdtlh 131 | dir wfltm 132 | 271200 zrtm 133 | $ cd djfww 134 | $ ls 135 | 37427 dct 136 | 204401 hcqbmwc.gts 137 | 283140 jmq 138 | dir lbrhbc 139 | 154148 pncb.bmp 140 | 53366 vzt.cnn 141 | $ cd lbrhbc 142 | $ ls 143 | dir djfww 144 | 153648 djfww.pps 145 | 308911 mvtjzp.btg 146 | 219150 ncmc 147 | 253604 wqft.ggb 148 | 293759 zft 149 | $ cd djfww 150 | $ ls 151 | 24794 hcqbmwc.gts 152 | $ cd .. 153 | $ cd .. 154 | $ cd .. 155 | $ cd fzqgwwnf 156 | $ ls 157 | 233720 scdd.pwr 158 | $ cd .. 159 | $ cd hqvmq 160 | $ ls 161 | dir cdld 162 | dir cpcfcc 163 | dir djfww 164 | 85564 hpq.hgm 165 | dir qnc 166 | 81509 wtnl.crs 167 | $ cd cdld 168 | $ ls 169 | 293421 llpltsgn.tqb 170 | $ cd .. 171 | $ cd cpcfcc 172 | $ ls 173 | 230813 cglljgv 174 | 178203 qlqqmndd.zcb 175 | 186410 zrtm.tbt 176 | $ cd .. 177 | $ cd djfww 178 | $ ls 179 | 201830 zrtm 180 | $ cd .. 181 | $ cd qnc 182 | $ ls 183 | 305356 bdf.jrh 184 | dir zrtm 185 | $ cd zrtm 186 | $ ls 187 | dir bdhdrr 188 | $ cd bdhdrr 189 | $ ls 190 | dir nffdrnb 191 | $ cd nffdrnb 192 | $ ls 193 | 301601 nbrjz 194 | $ cd .. 195 | $ cd .. 196 | $ cd .. 197 | $ cd .. 198 | $ cd .. 199 | $ cd mmcrzqc 200 | $ ls 201 | dir cpcfcc 202 | 264271 hpq.hgm 203 | 208744 tzsjrf.zdc 204 | 274096 zft 205 | $ cd cpcfcc 206 | $ ls 207 | 226054 cpcfcc 208 | $ cd .. 209 | $ cd .. 210 | $ cd vdtlh 211 | $ ls 212 | 84229 bzlg.crn 213 | 58668 cpcfcc.zqw 214 | 141409 hpq.hgm 215 | dir mdgst 216 | 37090 pstsh.qwv 217 | 40357 qlqqmndd.zcb 218 | dir smr 219 | dir sqbgcsgh 220 | dir trp 221 | $ cd mdgst 222 | $ ls 223 | 151033 fsmvbpsl.nqr 224 | $ cd .. 225 | $ cd smr 226 | $ ls 227 | 140764 cpcfcc.dpg 228 | $ cd .. 229 | $ cd sqbgcsgh 230 | $ ls 231 | dir djfww 232 | 263783 dvm 233 | 105219 hpq.hgm 234 | 29647 hwcgv.gvg 235 | 162537 lwjhgh.wmt 236 | 235511 nlw 237 | dir zwddrdfz 238 | $ cd djfww 239 | $ ls 240 | 260084 vcgpvpd 241 | $ cd .. 242 | $ cd zwddrdfz 243 | $ ls 244 | 225632 bhrzzw 245 | 269756 cqq.vrz 246 | $ cd .. 247 | $ cd .. 248 | $ cd trp 249 | $ ls 250 | 233192 vqwngcs 251 | $ cd .. 252 | $ cd .. 253 | $ cd wfltm 254 | $ ls 255 | 140990 djfww 256 | $ cd .. 257 | $ cd .. 258 | $ cd djb 259 | $ ls 260 | 213191 cjwrs.prd 261 | dir dhvpqt 262 | dir gtgftm 263 | dir hvfvt 264 | 208325 jwhp 265 | 301446 qlqqmndd.zcb 266 | dir qnlbgvf 267 | dir tps 268 | dir zft 269 | dir zrtm 270 | dir zwnlm 271 | $ cd dhvpqt 272 | $ ls 273 | dir sbcj 274 | $ cd sbcj 275 | $ ls 276 | 20611 ggt 277 | $ cd .. 278 | $ cd .. 279 | $ cd gtgftm 280 | $ ls 281 | 179526 qcqbtmvq 282 | $ cd .. 283 | $ cd hvfvt 284 | $ ls 285 | dir djstcnrt 286 | dir hggpvn 287 | dir hvfvt 288 | 63889 hvfvt.tjm 289 | 265836 qlqqmndd.zcb 290 | 105663 zft 291 | 223582 zft.llg 292 | 26037 zzwwg.lqh 293 | $ cd djstcnrt 294 | $ ls 295 | 201498 hcqbmwc.gts 296 | 139156 hpq.hgm 297 | 277342 pshgz.rtp 298 | dir rjb 299 | 257294 rqrb.lhh 300 | dir tqnbfnt 301 | 313308 zft.dvc 302 | $ cd rjb 303 | $ ls 304 | 268438 hpq.hgm 305 | dir hvfvt 306 | dir hvwpb 307 | 161024 mzbcgqc.nvw 308 | 137875 pwgswq.fld 309 | 260008 pzzcww 310 | 283261 wnvlrg.tmn 311 | $ cd hvfvt 312 | $ ls 313 | dir dvwqqt 314 | 163397 hcqbmwc.gts 315 | 265154 pwgswq.fld 316 | dir trsh 317 | dir vnf 318 | $ cd dvwqqt 319 | $ ls 320 | 315187 hcqbmwc.gts 321 | $ cd .. 322 | $ cd trsh 323 | $ ls 324 | dir ssrdpg 325 | $ cd ssrdpg 326 | $ ls 327 | dir vjdc 328 | $ cd vjdc 329 | $ ls 330 | dir srvdrhdq 331 | $ cd srvdrhdq 332 | $ ls 333 | 74145 djfww 334 | $ cd .. 335 | $ cd .. 336 | $ cd .. 337 | $ cd .. 338 | $ cd vnf 339 | $ ls 340 | dir djfww 341 | $ cd djfww 342 | $ ls 343 | 184018 pwgswq.fld 344 | $ cd .. 345 | $ cd .. 346 | $ cd .. 347 | $ cd hvwpb 348 | $ ls 349 | dir jwpjrcvs 350 | $ cd jwpjrcvs 351 | $ ls 352 | dir cpcfcc 353 | $ cd cpcfcc 354 | $ ls 355 | 52191 sdlv 356 | $ cd .. 357 | $ cd .. 358 | $ cd .. 359 | $ cd .. 360 | $ cd tqnbfnt 361 | $ ls 362 | dir djfww 363 | 206341 fmpb.lnp 364 | dir fpsjg 365 | 4589 hcqbmwc.gts 366 | dir hvfvt 367 | 8796 hvfvt.hdz 368 | 238364 tgcdpjc.fjm 369 | dir zrtm 370 | 40577 zrtm.fsr 371 | $ cd djfww 372 | $ ls 373 | 217182 djfww.rbf 374 | $ cd .. 375 | $ cd fpsjg 376 | $ ls 377 | 52456 djfww 378 | $ cd .. 379 | $ cd hvfvt 380 | $ ls 381 | dir rqhzvb 382 | 275026 szwgzm.qjd 383 | dir zbmtstj 384 | $ cd rqhzvb 385 | $ ls 386 | 8395 gcmzsd.jzf 387 | $ cd .. 388 | $ cd zbmtstj 389 | $ ls 390 | 39691 qlqqmndd.zcb 391 | dir qqcdss 392 | 180676 rwl.zwr 393 | $ cd qqcdss 394 | $ ls 395 | 106297 zrtm.nsl 396 | $ cd .. 397 | $ cd .. 398 | $ cd .. 399 | $ cd zrtm 400 | $ ls 401 | 153478 ldhvt 402 | $ cd .. 403 | $ cd .. 404 | $ cd .. 405 | $ cd hggpvn 406 | $ ls 407 | 19109 cpcfcc.fbh 408 | 249168 fnqjc 409 | 207420 qgzsh.pfs 410 | 135472 qlqqmndd.zcb 411 | $ cd .. 412 | $ cd hvfvt 413 | $ ls 414 | dir djfww 415 | 213659 hcqbmwc.gts 416 | dir jzdwq 417 | 204021 nvbgf 418 | 185328 qlqqmndd.zcb 419 | dir zrtm 420 | $ cd djfww 421 | $ ls 422 | 180713 rwmm.gjt 423 | $ cd .. 424 | $ cd jzdwq 425 | $ ls 426 | 57424 djfww.qtm 427 | 104960 slq.bfp 428 | 174906 svc 429 | $ cd .. 430 | $ cd zrtm 431 | $ ls 432 | dir mrtvhht 433 | $ cd mrtvhht 434 | $ ls 435 | 188512 djfww.fvm 436 | $ cd .. 437 | $ cd .. 438 | $ cd .. 439 | $ cd .. 440 | $ cd qnlbgvf 441 | $ ls 442 | dir fjrhtssv 443 | 46767 jhbnml.lpq 444 | $ cd fjrhtssv 445 | $ ls 446 | 198664 fgcc 447 | 245142 tsc.rsd 448 | $ cd .. 449 | $ cd .. 450 | $ cd tps 451 | $ ls 452 | dir fmlwghjv 453 | 146731 gwch.ttr 454 | dir jjzmdd 455 | dir rtltrng 456 | 191609 wff.mqt 457 | $ cd fmlwghjv 458 | $ ls 459 | 189227 zrtm.vgg 460 | $ cd .. 461 | $ cd jjzmdd 462 | $ ls 463 | dir hvfvt 464 | 178057 mpdfrrm 465 | 49493 pwgswq.fld 466 | 220129 sqgfb.flm 467 | 231012 zrmsnmr 468 | $ cd hvfvt 469 | $ ls 470 | dir lbndbhc 471 | 12602 mnclbss 472 | 746 ppw 473 | $ cd lbndbhc 474 | $ ls 475 | 49601 cdqvs.gwc 476 | 158670 wvjpchjg 477 | $ cd .. 478 | $ cd .. 479 | $ cd .. 480 | $ cd rtltrng 481 | $ ls 482 | dir cpgh 483 | 115613 hvfvt 484 | 59441 zfs 485 | $ cd cpgh 486 | $ ls 487 | dir djfww 488 | $ cd djfww 489 | $ ls 490 | dir tgt 491 | $ cd tgt 492 | $ ls 493 | dir vqwvqss 494 | $ cd vqwvqss 495 | $ ls 496 | dir bsdrhz 497 | $ cd bsdrhz 498 | $ ls 499 | dir pld 500 | $ cd pld 501 | $ ls 502 | 8543 mfs.gsb 503 | $ cd .. 504 | $ cd .. 505 | $ cd .. 506 | $ cd .. 507 | $ cd .. 508 | $ cd .. 509 | $ cd .. 510 | $ cd .. 511 | $ cd zft 512 | $ ls 513 | dir fhjgg 514 | $ cd fhjgg 515 | $ ls 516 | 114494 pwgswq.fld 517 | $ cd .. 518 | $ cd .. 519 | $ cd zrtm 520 | $ ls 521 | 201142 tlhr.rtd 522 | 298232 wlcztszv 523 | $ cd .. 524 | $ cd zwnlm 525 | $ ls 526 | 240023 hcqbmwc.gts 527 | 159126 hpq.hgm 528 | 22101 hvfvt.bfw 529 | dir ltzl 530 | dir mtfr 531 | dir sbw 532 | dir sqscdjlj 533 | dir ssf 534 | $ cd ltzl 535 | $ ls 536 | 260692 hpq.hgm 537 | 204540 hvfvt 538 | $ cd .. 539 | $ cd mtfr 540 | $ ls 541 | 15391 pwgswq.fld 542 | $ cd .. 543 | $ cd sbw 544 | $ ls 545 | 293226 hcqbmwc.gts 546 | 267478 htllcq 547 | 176349 nlbhcf.vpn 548 | 286577 zft.gds 549 | $ cd .. 550 | $ cd sqscdjlj 551 | $ ls 552 | 128776 gnh 553 | dir qbdpvcbt 554 | 284505 qlsn.vdq 555 | $ cd qbdpvcbt 556 | $ ls 557 | 280709 crv.hgm 558 | $ cd .. 559 | $ cd .. 560 | $ cd ssf 561 | $ ls 562 | 13328 djfww.pjn 563 | 19971 hvfvt 564 | dir zft 565 | $ cd zft 566 | $ ls 567 | 97761 dnmnz 568 | $ cd .. 569 | $ cd .. 570 | $ cd .. 571 | $ cd .. 572 | $ cd djfww 573 | $ ls 574 | 109590 bwfnnf.wpd 575 | 297297 cmht.ljg 576 | 280726 hvfvt 577 | $ cd .. 578 | $ cd drdf 579 | $ ls 580 | 56764 pwgswq.fld 581 | 300547 wqqm 582 | 210698 zrtm.jvq 583 | $ cd .. 584 | $ cd fgbqtjlj 585 | $ ls 586 | 22217 vrmgsz.ctg 587 | $ cd .. 588 | $ cd hjsmmj 589 | $ ls 590 | 232911 bcqrmp.czf 591 | 164656 hcqbmwc.gts 592 | dir jql 593 | dir ntd 594 | dir prgm 595 | dir psfvhh 596 | dir zft 597 | $ cd jql 598 | $ ls 599 | 212767 zhnhn.lzm 600 | dir zrtm 601 | $ cd zrtm 602 | $ ls 603 | 35950 bcqrmp.czf 604 | $ cd .. 605 | $ cd .. 606 | $ cd ntd 607 | $ ls 608 | dir vml 609 | $ cd vml 610 | $ ls 611 | 60833 bcqrmp.czf 612 | $ cd .. 613 | $ cd .. 614 | $ cd prgm 615 | $ ls 616 | 316166 pwgswq.fld 617 | $ cd .. 618 | $ cd psfvhh 619 | $ ls 620 | 152195 pwgswq.fld 621 | 92448 qlqqmndd.zcb 622 | $ cd .. 623 | $ cd zft 624 | $ ls 625 | 95808 hpq.hgm 626 | $ cd .. 627 | $ cd .. 628 | $ cd msptbrl 629 | $ ls 630 | 256069 hpq.hgm 631 | $ cd .. 632 | $ cd slpc 633 | $ ls 634 | dir djfww 635 | 285380 djfww.gcm 636 | 169898 hcqbmwc.gts 637 | 40914 mnpnhpz 638 | 188062 pwgswq.fld 639 | dir zrtm 640 | $ cd djfww 641 | $ ls 642 | 94935 pwgswq.fld 643 | 70655 qlqqmndd.zcb 644 | 48528 zft.qvh 645 | $ cd .. 646 | $ cd zrtm 647 | $ ls 648 | 160137 hcqbmwc.gts 649 | $ cd .. 650 | $ cd .. 651 | $ cd .. 652 | $ cd hvfvt 653 | $ ls 654 | dir cslthslv 655 | 129407 prwq 656 | dir vrzfbtt 657 | $ cd cslthslv 658 | $ ls 659 | dir cpcfcc 660 | 158361 hcqbmwc.gts 661 | $ cd cpcfcc 662 | $ ls 663 | dir zpgnczq 664 | $ cd zpgnczq 665 | $ ls 666 | 158414 zft 667 | $ cd .. 668 | $ cd .. 669 | $ cd .. 670 | $ cd vrzfbtt 671 | $ ls 672 | 185263 nqvvl 673 | $ cd .. 674 | $ cd .. 675 | $ cd phwgv 676 | $ ls 677 | 253690 bzpcj.fcj 678 | dir wtbr 679 | 168025 zdsh.tnq 680 | 157840 zsdfqb.zbd 681 | $ cd wtbr 682 | $ ls 683 | dir lvgdb 684 | $ cd lvgdb 685 | $ ls 686 | 177751 cpcfcc.dzr 687 | $ cd .. 688 | $ cd .. 689 | $ cd .. 690 | $ cd svw 691 | $ ls 692 | dir cpcfcc 693 | 189430 hpq.hgm 694 | dir ntzbj 695 | 13384 qlqqmndd.zcb 696 | 10333 wdvqhwgl.trq 697 | 161318 zwzp.jsn 698 | $ cd cpcfcc 699 | $ ls 700 | 298999 hcqbmwc.gts 701 | 290883 hpq.hgm 702 | dir qlnntp 703 | dir vpshs 704 | 5547 wlrmg.bpc 705 | dir zft 706 | $ cd qlnntp 707 | $ ls 708 | 168562 nqds.tqn 709 | $ cd .. 710 | $ cd vpshs 711 | $ ls 712 | 246400 pwgswq.fld 713 | $ cd .. 714 | $ cd zft 715 | $ ls 716 | 235634 hvfvt.hst 717 | $ cd .. 718 | $ cd .. 719 | $ cd ntzbj 720 | $ ls 721 | 98777 qlqqmndd.zcb 722 | $ cd .. 723 | $ cd .. 724 | $ cd zft 725 | $ ls 726 | dir dhnzm 727 | 299292 hvfvt.pvb 728 | dir ltfb 729 | dir mrvsjgsq 730 | dir ntr 731 | dir swmvhgd 732 | dir zrtm 733 | $ cd dhnzm 734 | $ ls 735 | 267041 bbsj 736 | $ cd .. 737 | $ cd ltfb 738 | $ ls 739 | 242136 bcqrmp.czf 740 | 314862 dgdz 741 | 203160 hcqbmwc.gts 742 | 80422 hgvz 743 | dir qftjfqfv 744 | 180815 sstl.wzg 745 | dir wmhm 746 | dir zft 747 | dir zszp 748 | $ cd qftjfqfv 749 | $ ls 750 | dir bmmw 751 | $ cd bmmw 752 | $ ls 753 | dir hvfvt 754 | 318039 hvfvt.whc 755 | 17057 pwgswq.fld 756 | $ cd hvfvt 757 | $ ls 758 | 170348 brplf.wgv 759 | 156783 hcqbmwc.gts 760 | $ cd .. 761 | $ cd .. 762 | $ cd .. 763 | $ cd wmhm 764 | $ ls 765 | 178474 bcqrmp.czf 766 | dir cmsgv 767 | dir dcfvrtj 768 | 225393 htjflrs.tlm 769 | dir hvfvt 770 | dir nlrs 771 | 273173 nsmdd.glc 772 | 151259 pwgswq.fld 773 | dir ztqvwjr 774 | $ cd cmsgv 775 | $ ls 776 | dir flgjbjg 777 | $ cd flgjbjg 778 | $ ls 779 | 13971 cpcfcc 780 | 20601 qlqqmndd.zcb 781 | $ cd .. 782 | $ cd .. 783 | $ cd dcfvrtj 784 | $ ls 785 | 141992 djfww.djn 786 | 118149 hpq.hgm 787 | dir qrmqslq 788 | $ cd qrmqslq 789 | $ ls 790 | 105940 zrtm.vql 791 | $ cd .. 792 | $ cd .. 793 | $ cd hvfvt 794 | $ ls 795 | 181962 hpq.hgm 796 | $ cd .. 797 | $ cd nlrs 798 | $ ls 799 | 82705 vnfwjf.hhl 800 | $ cd .. 801 | $ cd ztqvwjr 802 | $ ls 803 | 98257 pwgswq.fld 804 | 83864 scv.pbp 805 | $ cd .. 806 | $ cd .. 807 | $ cd zft 808 | $ ls 809 | 183072 rsbfsl.zsj 810 | $ cd .. 811 | $ cd zszp 812 | $ ls 813 | dir hvfvt 814 | $ cd hvfvt 815 | $ ls 816 | dir djfww 817 | dir dqdtgjtg 818 | dir hvfvt 819 | $ cd djfww 820 | $ ls 821 | 117037 rnmbsq.zph 822 | 259243 zrtm.znf 823 | $ cd .. 824 | $ cd dqdtgjtg 825 | $ ls 826 | dir lrbsvng 827 | 59301 zft 828 | $ cd lrbsvng 829 | $ ls 830 | 46301 bcqrmp.czf 831 | $ cd .. 832 | $ cd .. 833 | $ cd hvfvt 834 | $ ls 835 | 223277 qlqqmndd.zcb 836 | $ cd .. 837 | $ cd .. 838 | $ cd .. 839 | $ cd .. 840 | $ cd mrvsjgsq 841 | $ ls 842 | 160189 cpcfcc 843 | dir lzqf 844 | 232626 pwgswq.fld 845 | dir rpmfcg 846 | $ cd lzqf 847 | $ ls 848 | 135552 bcqrmp.czf 849 | 48083 qlqqmndd.zcb 850 | dir rbg 851 | 229086 rdswb.cjz 852 | 204486 spbwfrwf.cmj 853 | $ cd rbg 854 | $ ls 855 | dir sjdwsbqq 856 | $ cd sjdwsbqq 857 | $ ls 858 | 270621 rhv.shw 859 | $ cd .. 860 | $ cd .. 861 | $ cd .. 862 | $ cd rpmfcg 863 | $ ls 864 | 227216 bld.jtn 865 | dir zft 866 | $ cd zft 867 | $ ls 868 | 43056 vzc 869 | $ cd .. 870 | $ cd .. 871 | $ cd .. 872 | $ cd ntr 873 | $ ls 874 | dir cmtnqb 875 | dir djfww 876 | 195371 wffvmql.lrv 877 | $ cd cmtnqb 878 | $ ls 879 | 135380 pbng.vhq 880 | $ cd .. 881 | $ cd djfww 882 | $ ls 883 | dir fmvrrrq 884 | dir mbhrbss 885 | dir zrtm 886 | $ cd fmvrrrq 887 | $ ls 888 | dir cpcfcc 889 | 79110 djfww 890 | 300581 ftcdj.wcc 891 | $ cd cpcfcc 892 | $ ls 893 | 234211 zsgsm 894 | $ cd .. 895 | $ cd .. 896 | $ cd mbhrbss 897 | $ ls 898 | 149184 djfww.gwh 899 | 185815 rhgw.rmj 900 | $ cd .. 901 | $ cd zrtm 902 | $ ls 903 | dir zft 904 | $ cd zft 905 | $ ls 906 | 310043 bnwvt.fbg 907 | $ cd .. 908 | $ cd .. 909 | $ cd .. 910 | $ cd .. 911 | $ cd swmvhgd 912 | $ ls 913 | 77547 djfww.jwr 914 | 318547 drggg 915 | 300962 pwgswq.fld 916 | $ cd .. 917 | $ cd zrtm 918 | $ ls 919 | 229319 bflnffjj 920 | dir djfww 921 | 142526 hvfvt 922 | 232722 jprrf 923 | 94024 ndmf.hdr 924 | dir vhdhn 925 | $ cd djfww 926 | $ ls 927 | 30770 bcqrmp.czf 928 | $ cd .. 929 | $ cd vhdhn 930 | $ ls 931 | dir djfww 932 | 48261 djfww.frg 933 | dir gqc 934 | 316163 qlqqmndd.zcb 935 | $ cd djfww 936 | $ ls 937 | 104095 cvjlthn.cfl 938 | 223454 hgqwzh 939 | 24715 pwgswq.fld 940 | 283499 qlqqmndd.zcb 941 | dir zft 942 | 224574 zlnwn 943 | $ cd zft 944 | $ ls 945 | 100941 pwgswq.fld 946 | $ cd .. 947 | $ cd .. 948 | $ cd gqc 949 | $ ls 950 | 156273 wpgwrdl 951 | -------------------------------------------------------------------------------- /day-08/README.md: -------------------------------------------------------------------------------- 1 | # Day 8: Treetop Tree House 2 | 3 | The expedition comes across a peculiar patch of tall trees all planted carefully in a grid. The Elves explain that a previous expedition planted these trees as a reforestation effort. Now, they're curious if this would be a good location for a [tree house](https://en.wikipedia.org/wiki/Tree_house). 4 | 5 | First, determine whether there is enough tree cover here to keep a tree house _hidden_. To do this, you need to count the number of trees that are _visible from outside the grid_ when looking directly along a row or column. 6 | 7 | The Elves have already launched a [quadcopter](https://en.wikipedia.org/wiki/Quadcopter) to generate a map with the height of each tree (your puzzle input). For example: 8 | 9 | ``` 10 | 30373 11 | 2`5`5512 12 | 65332 13 | 33549 14 | 35390 15 | ``` 16 | 17 | Each tree is represented as a single digit whose value is its height, where `0` is the shortest and `9` is the tallest. 18 | 19 | A tree is _visible_ if all of the other trees between it and an edge of the grid are _shorter_ than it. Only consider trees in the same row or column; that is, only look up, down, left, or right from any given tree. 20 | 21 | All of the trees around the edge of the grid are _visible_ - since they are already on the edge, there are no trees to block the view. In this example, that only leaves the _interior nine trees_ to consider: 22 | 23 | - The top-left `5` is _visible_ from the left and top. (It isn't visible from the right or bottom since other trees of height `5` are in the way.) 24 | - The top-middle `5` is _visible_ from the top and right. 25 | - The top-right `1` is not visible from any direction; for it to be visible, there would need to only be trees of height _0_ between it and an edge. 26 | - The left-middle `5` is _visible_, but only from the right. 27 | - The center `3` is not visible from any direction; for it to be visible, there would need to be only trees of at most height `2` between it and an edge. 28 | - The right-middle `3` is _visible_ from the right. 29 | - In the bottom row, the middle `5` is _visible_, but the `3` and `4` are not. 30 | 31 | With 16 trees visible on the edge and another 5 visible in the interior, a total of `21` trees are visible in this arrangement. 32 | 33 | Consider your map; **how many trees are visible from outside the grid?** 34 | 35 | ## Part Two 36 | 37 | Content with the amount of tree cover available, the Elves just need to know the best spot to build their tree house: they would like to be able to see a lot of _trees_. 38 | 39 | To measure the viewing distance from a given tree, look up, down, left, and right from that tree; stop if you reach an edge or at the first tree that is the same height or taller than the tree under consideration. (If a tree is right on the edge, at least one of its viewing distances will be zero.) 40 | 41 | The Elves don't care about distant trees taller than those found by the rules above; the proposed tree house has large [eaves](https://en.wikipedia.org/wiki/Eaves) to keep it dry, so they wouldn't be able to see higher than the tree house anyway. 42 | 43 | In the example above, consider the middle `5` in the second row: 44 | 45 | ``` 46 | 30373 47 | 25512 48 | 65332 49 | 33549 50 | 35390 51 | ``` 52 | 53 | - Looking up, its view is not blocked; it can see `1` tree (of height `3`). 54 | - Looking left, its view is blocked immediately; it can see only `1` tree (of height `5`, right next to it). 55 | - Looking right, its view is not blocked; it can see `2` trees. 56 | - Looking down, its view is blocked eventually; it can see `2` trees (one of height `3`, then the tree of height `5` that blocks its view). 57 | 58 | A tree's _scenic score_ is found by _multiplying together_ its viewing distance in each of the four directions. For this tree, this is `4` (found by multiplying `1 * 1 * 2 * 2`). 59 | 60 | However, you can do even better: consider the tree of height `5` in the middle of the fourth row: 61 | 62 | ``` 63 | 30373 64 | 25512 65 | 65332 66 | 33549 67 | 35390 68 | ``` 69 | 70 | - Looking up, its view is blocked at `2` trees (by another tree with a height of `5`). 71 | - Looking left, its view is not blocked; it can see `2` trees. 72 | - Looking down, its view is also not blocked; it can see `1` tree. 73 | - Looking right, its view is blocked at `2` trees (by a massive tree of height `9`). 74 | 75 | This tree's scenic score is `8` (`2 * 2 * 1 * 2`); this is the ideal spot for the tree house. 76 | 77 | Consider each tree on your map. **What is the highest scenic score possible for any tree?** 78 | -------------------------------------------------------------------------------- /day-08/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines } from '../utils/index.js'; 2 | 3 | function parseInput(input) { 4 | return splitLines(input).map((str) => str.split('').map(Number)); 5 | } 6 | 7 | function getNeighbours(grid, rowIndex, colIndex) { 8 | return [ 9 | // top 10 | grid 11 | .slice(0, rowIndex) 12 | .map((row) => row[colIndex]) 13 | .reverse(), 14 | // right 15 | grid[rowIndex].slice(colIndex + 1), 16 | // bottom 17 | grid.slice(rowIndex + 1).map((row) => row[colIndex]), 18 | // left 19 | grid[rowIndex].slice(0, colIndex).reverse(), 20 | ]; 21 | } 22 | 23 | function isVisible(grid, rowIndex, colIndex) { 24 | const height = grid[rowIndex][colIndex]; 25 | const neighbours = getNeighbours(grid, rowIndex, colIndex); 26 | 27 | return neighbours.some((direction) => 28 | direction.every((tree) => tree < height), 29 | ); 30 | } 31 | 32 | export function getTotalVisibleTrees(input) { 33 | const grid = parseInput(input); 34 | let visible = 0; 35 | 36 | grid.forEach((row, rowIndex) => 37 | row.forEach((_, colIndex) => { 38 | if (isVisible(grid, rowIndex, colIndex)) { 39 | visible++; 40 | } 41 | }), 42 | ); 43 | 44 | return visible; 45 | } 46 | 47 | function getScenicScore(grid, rowIndex, colIndex) { 48 | const height = grid[rowIndex][colIndex]; 49 | const neighbours = getNeighbours(grid, rowIndex, colIndex); 50 | 51 | function getCount(trees) { 52 | let counter = 0; 53 | 54 | for (let tree of trees) { 55 | counter++; 56 | if (tree >= height) { 57 | return counter; 58 | } 59 | } 60 | 61 | return counter; 62 | } 63 | 64 | return neighbours.reduce((a, b) => a * getCount(b), 1); 65 | } 66 | 67 | export function getHighestScenicScore(input) { 68 | const grid = parseInput(input); 69 | let highestScore = 0; 70 | 71 | grid.forEach((row, rowIndex) => 72 | row.forEach((_, colIndex) => { 73 | let score = getScenicScore(grid, rowIndex, colIndex); 74 | 75 | if (score > highestScore) { 76 | highestScore = score; 77 | } 78 | }), 79 | ); 80 | 81 | return highestScore; 82 | } 83 | 84 | if (process.env.NODE_ENV !== 'test') { 85 | const input = getInput(import.meta.url); 86 | const answer1 = getTotalVisibleTrees(input); 87 | const answer2 = getHighestScenicScore(input); 88 | 89 | console.log(` 90 | #1 Consider your map; how many trees are visible from outside 91 | the grid? 92 | ${answer1} 93 | 94 | #2 Consider each tree on your map. What is the highest scenic 95 | score possible for any tree? 96 | ${answer2} 97 | `); 98 | } 99 | -------------------------------------------------------------------------------- /day-08/index.test.js: -------------------------------------------------------------------------------- 1 | import { getHighestScenicScore, getTotalVisibleTrees } from './index.js'; 2 | 3 | const input = ` 4 | 30373 5 | 25512 6 | 65332 7 | 33549 8 | 35390 9 | `; 10 | 11 | describe('getTotalVisibleTrees', () => { 12 | it('should return the number of trees visible from outside the grid', () => { 13 | expect(getTotalVisibleTrees(input)).toEqual(21); 14 | }); 15 | }); 16 | 17 | describe('getHighestScenicScore', () => { 18 | it('should return the highest scenic score possible for any tree', () => { 19 | expect(getHighestScenicScore(input)).toEqual(8); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /day-08/input.txt: -------------------------------------------------------------------------------- 1 | 211332213033101124130110410025404035324540506465522424325025442423205322144201114032433102223133301 2 | 311023320242030112033354205533003100224166354233554634221041635230051410343235342432112434034030100 3 | 001223204433022013103305410222315554032366506021405002315044463420051033302201255133143124420412122 4 | 013132233012344225535033304112253201303421563422623305021204605543621044544210352330412212401012131 5 | 123203213200414113431324051024435265606056206220330353405664413252121241340014021504043322022404322 6 | 300314334303200324110001011065050624136654044030061620050042314252632633325011034021521210022442213 7 | 300312304313121233203544305130444460463436450145663611020201513406316245230444434551201440322230302 8 | 121213330224031553422231036233163250606241600057176176344004346462440003006410044502531341130240114 9 | 301324240431503125500116062453142425154655731122643437177477550414605433012615301235013252120302340 10 | 003232040401112004305510155520121504621467762731313536577767114335412665224212525123530315344321124 11 | 020011211014152120140622132315236133565515235564134376673433256457543305603063000545505055054420401 12 | 120232244154134255122415053246324763251764537642172244222741232566733246632230131225000041540131403 13 | 340032215420250553142064146064564173357273533153247735663417273646632371434553560636420004452544143 14 | 043414443322552422161330440067615566131775467414772511621257632542341175313336105314043250123012200 15 | 012111021442304652102413106134662444516476275112834287667673516365611433432545515260120211024041202 16 | 032102521544554062032010572477745124332575337882847632625227237576235753415421361112101043554053100 17 | 311444312333365122206150371721763624374376873885257652577482877454566142635223501265056342151423503 18 | 144251432134413522432634164521765222778875228537684473757528335574576764563372055450540131505303034 19 | 000255023251250523115357427615753523575838766845363763466455836854431647317161446453545305422435355 20 | 245002340133321145325367575315512257574665372575562748686454783577847666453745464626164131031332100 21 | 050553025366530325021416326145857322624322772785872882346577742678858344161622134432426516051344250 22 | 152311521001545435344376115464326457845848454437444432763844343744467358574522513450314302061503452 23 | 432454304206244265363237124475585684786823237698738473868377345823852284311544625730363140211242142 24 | 454020453313433443537657634364823277466449658493374864768899457268665377243765726567464021363445250 25 | 552431324265025566426217457328875767435899547855738449793664649385627243287213716374361136462440243 26 | 031052136256223525442167246873557667773568893448343999893549698865743526327856612255315524012102000 27 | 345323665312406654514446384583427637865769666594853994657493368533935635676521153437537311305202142 28 | 342110244050561175476152877378374945653376889649978659538759435748334872266574665131763066015150414 29 | 145433434262576274652174742347844566354377337849447759743936477456984862853785777171357505003212025 30 | 310242523113472175765257374582489598876797985649454666865333776554339348242882833175411762344652012 31 | 434056456416337446635277274487757585458766758586996458774953698859555746353645282477417311113216435 32 | 045021105500376267478536827836355597677975786498896678587684858536744539776275465227567675153251405 33 | 300142642025442446482242442484398879535896799784784778494989949379689755588234538855243763305416321 34 | 353622636633651765254457642339454687946896697548485487765646998666995567567726837277556747624363451 35 | 202435626512143732835284377793378475946599964657457656969997944856356445774883877827536725303005505 36 | 135650034646464156744647526498458647549464945549765974544889665765659884799642263733421214426362624 37 | 150435334074657468688563599355379375877984576587798777599554755799738577897957837453257132312302144 38 | 512443536422754252577234434969994856586456545889988865785958887667666384435563246262331235420111143 39 | 466652116227352685834266983738374448949754669575866999669685556447597478636534623278751113456645060 40 | 021164506132145534653735865996437996949669685788777975556657797445847474955965558246253533611024642 41 | 231050262356423276576326937834369549887967896966756856658985767688875977398375688846413232324304226 42 | 435212106653324768273769678978879679954786766976999558656777959955869577458834883774845467247506214 43 | 160366254415742474477255579484597574496859676569755788769767586676674847997944768266836256767533110 44 | 241513312227373552852675497876868858749576878555778658557589787666975955754559662763784164711060064 45 | 351110451267671255426564695657766766686759856878789989756858799968497958544598723587586767222266454 46 | 316062153252225354662464658785786565488858687886778777967566595898554596936489753547456317121214424 47 | 212536666162371857232636965378959948576758567679878996998888878797474958786685542845571126616220264 48 | 510024546261143787272349466837799649568665658866988878698565865894746985377749787572341577611344166 49 | 004351216364728646844848837567468684779987996888767898677985599854955668566559858835633322134522334 50 | 336463436447757363543649949947564678786988588988866877968758989665477866657945447564627357126653146 51 | 026065162577657624222467836757949464596556769778678999898769595755945784554668326364364774614112042 52 | 503221631577514777533445365468588455658986887687687789867975758885748889857396423825776253156736650 53 | 546513661435242553764893754934757584678877997789877686967898678564676598335965867335727137112215030 54 | 611265646576763532336777659499858694897877758999678876979977887874768566899568336424484421461153426 55 | 354632527555434648642259948845976658869997857679769998977895558994584876439733545486722237134252244 56 | 520066365142477526347774786479494548687879769997669786998678978895445886967346756354286727222124503 57 | 036426316533162875778686487545896556958758868879977868686688986574849753898677468557551537174650421 58 | 560265634575463724567588788767856667457699558755596657566679586798788873437533663746231724155125525 59 | 154560626115545678446889538386759776485985597568577777558958786887687647784334647726551367164130624 60 | 435604614267661345622839365943384759557699679885767759599566796964556464635883224855517743254442610 61 | 015330201727631536234389975658784474799697966578756955569957997995994446883848582283235113446522166 62 | 352230033476456648636532764835957899749588885668565677958598595585884536843566635235535143233400362 63 | 154324641154514622554238347338736749648497879886988865566875744965765539565765428586545254520653004 64 | 453036521326216338225852566856869755589995557886678566578454876595677374667726383554235644733043120 65 | 255116155525323462526438743774389777499948654465588776697977856998545943966845458742427155331033531 66 | 025560625413477123376683438634566738565665455954779575658546654745567665935272473226176343466230234 67 | 024466546555224254763532784959665896878967666774886569787656978898736887735524866681527476335351660 68 | 431553605003462632355435287785653379467565865846957764769957785898849746583877462511543675401304331 69 | 245166660214751253743856378267388633494584489567844846476445548983654883554368632374551522612226505 70 | 540335146233545626252387487873545495675665748448745979949594735654895943368867237133447443126433414 71 | 234255620120615565122843883767337363659787964676878598696674776783394766454355878652417710601552535 72 | 155234425620263264536252385765564357733857634857584669678763477778599626835456677357151640115601402 73 | 415011642631335751527728632365876445738339479934933867368973986563564488774233653717376514142421112 74 | 331553124665647777751514436356443477749885879596563793484897353687466437233338475237523161110142051 75 | 125403316650422145565532565656426288343597345985455577884935753554564626425235737254643554446160112 76 | 244245221040325667524534344843767845646457957737955963874753776775484255785447725731356435212213414 77 | 502435004653346035253622224342447486734347953679733888847856349544574634822773162422363261331201024 78 | 324222044306505016426445557827266762373537588855883779693953564587846832687121422621334643504041214 79 | 242441310622432165134457161657567575877727367394894947493553362876526782815233251471504221505502531 80 | 404413131464141606677317644575735753536548433834477734384655752565382465763337735513154564140342251 81 | 301100110415420444111615617662387653344875842557335485555688447688575465433323177644556524120212234 82 | 121350153052662132322721116134216553883566368426252878468274827563855654437763154152652520055535413 83 | 300411255204026610413574577661773545843284364682683778487466278862352135457325560155622450041155414 84 | 201513150243444362415017756317333176455677876825338686288332246436653511332623525023535335010251403 85 | 442151212200240012240515354421652475542422627327336365453756577274176715121634500306606230505005442 86 | 221142355114024136331532344422671215757576745773483847686535252141745132161123140234155444022141343 87 | 303111241400254212624566606371413763653433175765433383216314527571326314157614031441404441454123113 88 | 244200502534242261362202215053674434622174351252464554756217534657676575631240166556655421245234022 89 | 033140410031001244605126654665654443346166177754221527272665473526726632645640155606531431321003203 90 | 333144020203540344460212034601443662327775175627432461421467275253741652534221451541150344324122432 91 | 003441144232331144321240262132134156264312772115415535174111161372132213423063330000551314401242014 92 | 431244213034140532345020014016302213467251277744712151733426334265042000625105541402423314424042442 93 | 032332242311014553503456362533135654462331252577334743117656122022210110152631423434352520024421043 94 | 102103002322052451100230340420161635556642503226271246652053202351054222634613532434255202434131242 95 | 203130013133233045044204223404060632403351664241443631454330322650226245651432113040525413323340210 96 | 030124200340221230241225521446452652313241114064226552054332165233441366221221035421132414124314402 97 | 120112413030344114412231514332254000023525634236200334160045616312416360423100451201322404023012301 98 | 212011312011233130523111525121303414244121320644050343211556336246463215444025331411002041412122121 99 | 002023323443102242311523000140150506160522004635222556200251663551444551235250440223242010414011021 100 | -------------------------------------------------------------------------------- /day-09/README.md: -------------------------------------------------------------------------------- 1 | # Day 9: Rope Bridge 2 | 3 | This rope bridge creaks as you walk along it. You aren't sure how old it is, or whether it can even support your weight. 4 | 5 | It seems to support the Elves just fine, though. The bridge spans a gorge which was carved out by the massive river far below you. 6 | 7 | You step carefully; as you do, the ropes stretch and twist. You decide to distract yourself by modeling rope physics; maybe you can even figure out where _not_ to step. 8 | 9 | Consider a rope with a knot at each end; these knots mark the _head_ and the _tail_ of the rope. If the head moves far enough away from the tail, the tail is pulled toward the head. 10 | 11 | Due to nebulous reasoning involving [Planck lengths](https://en.wikipedia.org/wiki/Planck_units#Planck_length), you should be able to model the positions of the knots on a two-dimensional grid. Then, by following a hypothetical _series of motions_ (your puzzle input) for the head, you can determine how the tail will move. 12 | 13 | Due to the aforementioned Planck lengths, the rope must be quite short; in fact, the head (H) and tail (T) must _always be touching_ (diagonally adjacent and even overlapping both count as touching): 14 | 15 | ```js 16 | .... 17 | .TH. 18 | .... 19 | 20 | .... 21 | .H.. 22 | ..T. 23 | .... 24 | 25 | ... 26 | .H. (H covers T) 27 | ... 28 | ``` 29 | 30 | If the head is ever two steps directly up, down, left, or right from the tail, the tail must also move one step in that direction so it remains close enough: 31 | 32 | ``` 33 | ..... ..... ..... 34 | .TH.. -> .T.H. -> ..TH. 35 | ..... ..... ..... 36 | 37 | ... ... ... 38 | .T. .T. ... 39 | .H. -> ... -> .T. 40 | ... .H. .H. 41 | ... ... ... 42 | ``` 43 | 44 | Otherwise, if the head and tail aren't touching and aren't in the same row or column, the tail always moves one step diagonally to keep up: 45 | 46 | ``` 47 | ..... ..... ..... 48 | ..... ..H.. ..H.. 49 | ..H.. -> ..... -> ..T.. 50 | .T... .T... ..... 51 | ..... ..... ..... 52 | 53 | ..... ..... ..... 54 | ..... ..... ..... 55 | ..H.. -> ...H. -> ..TH. 56 | .T... .T... ..... 57 | ..... ..... ..... 58 | ``` 59 | 60 | You just need to work out where the tail goes as the head follows a series of motions. Assume the head and the tail both start at the same position, overlapping. 61 | 62 | For example: 63 | 64 | ``` 65 | R 4 66 | U 4 67 | L 3 68 | D 1 69 | R 4 70 | D 1 71 | L 5 72 | R 2 73 | ``` 74 | 75 | This series of motions moves the head _right_ four steps, then _up_ four steps, then _left_ three steps, then _down_ one step, and so on. After each step, you'll need to update the position of the tail if the step means the head is no longer adjacent to the tail. Visually, these motions occur as follows (s marks the starting position as a reference point): 76 | 77 | ``` 78 | == Initial State == 79 | 80 | ...... 81 | ...... 82 | ...... 83 | ...... 84 | H..... (H covers T, s) 85 | 86 | == R 4 == 87 | 88 | ...... 89 | ...... 90 | ...... 91 | ...... 92 | TH.... (T covers s) 93 | 94 | ...... 95 | ...... 96 | ...... 97 | ...... 98 | sTH... 99 | 100 | ...... 101 | ...... 102 | ...... 103 | ...... 104 | s.TH.. 105 | 106 | ...... 107 | ...... 108 | ...... 109 | ...... 110 | s..TH. 111 | 112 | == U 4 == 113 | 114 | ...... 115 | ...... 116 | ...... 117 | ....H. 118 | s..T.. 119 | 120 | ...... 121 | ...... 122 | ....H. 123 | ....T. 124 | s..... 125 | 126 | ...... 127 | ....H. 128 | ....T. 129 | ...... 130 | s..... 131 | 132 | ....H. 133 | ....T. 134 | ...... 135 | ...... 136 | s..... 137 | 138 | == L 3 == 139 | 140 | ...H.. 141 | ....T. 142 | ...... 143 | ...... 144 | s..... 145 | 146 | ..HT.. 147 | ...... 148 | ...... 149 | ...... 150 | s..... 151 | 152 | .HT... 153 | ...... 154 | ...... 155 | ...... 156 | s..... 157 | 158 | == D 1 == 159 | 160 | ..T... 161 | .H.... 162 | ...... 163 | ...... 164 | s..... 165 | 166 | == R 4 == 167 | 168 | ..T... 169 | ..H... 170 | ...... 171 | ...... 172 | s..... 173 | 174 | ..T... 175 | ...H.. 176 | ...... 177 | ...... 178 | s..... 179 | 180 | ...... 181 | ...TH. 182 | ...... 183 | ...... 184 | s..... 185 | 186 | ...... 187 | ....TH 188 | ...... 189 | ...... 190 | s..... 191 | 192 | == D 1 == 193 | 194 | ...... 195 | ....T. 196 | .....H 197 | ...... 198 | s..... 199 | 200 | == L 5 == 201 | 202 | ...... 203 | ....T. 204 | ....H. 205 | ...... 206 | s..... 207 | 208 | ...... 209 | ....T. 210 | ...H.. 211 | ...... 212 | s..... 213 | 214 | ...... 215 | ...... 216 | ..HT.. 217 | ...... 218 | s..... 219 | 220 | ...... 221 | ...... 222 | .HT... 223 | ...... 224 | s..... 225 | 226 | ...... 227 | ...... 228 | HT.... 229 | ...... 230 | s..... 231 | 232 | == R 2 == 233 | 234 | ...... 235 | ...... 236 | .H.... (H covers T) 237 | ...... 238 | s..... 239 | 240 | ...... 241 | ...... 242 | .TH... 243 | ...... 244 | s..... 245 | ``` 246 | 247 | After simulating the rope, you can count up all of the positions the _tail visited at least once_. In this diagram, `s` again marks the starting position (which the tail also visited) and `#` marks other positions the tail visited: 248 | 249 | ``` 250 | ..##.. 251 | ...##. 252 | .####. 253 | ....#. 254 | s###.. 255 | ``` 256 | 257 | So, there are `13` positions the tail visited at least once. 258 | 259 | Simulate your complete hypothetical series of motions. **How many positions does the tail of the rope visit at least once?** 260 | 261 | ## Part Two 262 | 263 | A rope snaps! Suddenly, the river is getting a lot closer than you remember. The bridge is still there, but some of the ropes that broke are now whipping toward you as you fall through the air! 264 | 265 | The ropes are moving too quickly to grab; you only have a few seconds to choose how to arch your body to avoid being hit. Fortunately, your simulation can be extended to support longer ropes. 266 | 267 | Rather than two knots, you now must simulate a rope consisting of ten knots. One knot is still the head of the rope and moves according to the series of motions. Each knot further down the rope follows the knot in front of it using the same rules as before. 268 | 269 | Using the same series of motions as the above example, but with the knots marked `H`, `1`, `2`, ..., `9`, the motions now occur as follows: 270 | 271 | ``` 272 | == Initial State == 273 | 274 | ...... 275 | ...... 276 | ...... 277 | ...... 278 | H..... (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s) 279 | 280 | == R 4 == 281 | 282 | ...... 283 | ...... 284 | ...... 285 | ...... 286 | 1H.... (1 covers 2, 3, 4, 5, 6, 7, 8, 9, s) 287 | 288 | ...... 289 | ...... 290 | ...... 291 | ...... 292 | 21H... (2 covers 3, 4, 5, 6, 7, 8, 9, s) 293 | 294 | ...... 295 | ...... 296 | ...... 297 | ...... 298 | 321H.. (3 covers 4, 5, 6, 7, 8, 9, s) 299 | 300 | ...... 301 | ...... 302 | ...... 303 | ...... 304 | 4321H. (4 covers 5, 6, 7, 8, 9, s) 305 | 306 | == U 4 == 307 | 308 | ...... 309 | ...... 310 | ...... 311 | ....H. 312 | 4321.. (4 covers 5, 6, 7, 8, 9, s) 313 | 314 | ...... 315 | ...... 316 | ....H. 317 | .4321. 318 | 5..... (5 covers 6, 7, 8, 9, s) 319 | 320 | ...... 321 | ....H. 322 | ....1. 323 | .432.. 324 | 5..... (5 covers 6, 7, 8, 9, s) 325 | 326 | ....H. 327 | ....1. 328 | ..432. 329 | .5.... 330 | 6..... (6 covers 7, 8, 9, s) 331 | 332 | == L 3 == 333 | 334 | ...H.. 335 | ....1. 336 | ..432. 337 | .5.... 338 | 6..... (6 covers 7, 8, 9, s) 339 | 340 | ..H1.. 341 | ...2.. 342 | ..43.. 343 | .5.... 344 | 6..... (6 covers 7, 8, 9, s) 345 | 346 | .H1... 347 | ...2.. 348 | ..43.. 349 | .5.... 350 | 6..... (6 covers 7, 8, 9, s) 351 | 352 | == D 1 == 353 | 354 | ..1... 355 | .H.2.. 356 | ..43.. 357 | .5.... 358 | 6..... (6 covers 7, 8, 9, s) 359 | 360 | == R 4 == 361 | 362 | ..1... 363 | ..H2.. 364 | ..43.. 365 | .5.... 366 | 6..... (6 covers 7, 8, 9, s) 367 | 368 | ..1... 369 | ...H.. (H covers 2) 370 | ..43.. 371 | .5.... 372 | 6..... (6 covers 7, 8, 9, s) 373 | 374 | ...... 375 | ...1H. (1 covers 2) 376 | ..43.. 377 | .5.... 378 | 6..... (6 covers 7, 8, 9, s) 379 | 380 | ...... 381 | ...21H 382 | ..43.. 383 | .5.... 384 | 6..... (6 covers 7, 8, 9, s) 385 | 386 | == D 1 == 387 | 388 | ...... 389 | ...21. 390 | ..43.H 391 | .5.... 392 | 6..... (6 covers 7, 8, 9, s) 393 | 394 | == L 5 == 395 | 396 | ...... 397 | ...21. 398 | ..43H. 399 | .5.... 400 | 6..... (6 covers 7, 8, 9, s) 401 | 402 | ...... 403 | ...21. 404 | ..4H.. (H covers 3) 405 | .5.... 406 | 6..... (6 covers 7, 8, 9, s) 407 | 408 | ...... 409 | ...2.. 410 | ..H1.. (H covers 4; 1 covers 3) 411 | .5.... 412 | 6..... (6 covers 7, 8, 9, s) 413 | 414 | ...... 415 | ...2.. 416 | .H13.. (1 covers 4) 417 | .5.... 418 | 6..... (6 covers 7, 8, 9, s) 419 | 420 | ...... 421 | ...... 422 | H123.. (2 covers 4) 423 | .5.... 424 | 6..... (6 covers 7, 8, 9, s) 425 | 426 | == R 2 == 427 | 428 | ...... 429 | ...... 430 | .H23.. (H covers 1; 2 covers 4) 431 | .5.... 432 | 6..... (6 covers 7, 8, 9, s) 433 | 434 | ...... 435 | ...... 436 | .1H3.. (H covers 2, 4) 437 | .5.... 438 | 6..... (6 covers 7, 8, 9, s) 439 | ``` 440 | 441 | Now, you need to keep track of the positions the new tail, `9`, visits. In this example, the tail never moves, and so it only visits `1` position. However, _be careful_: more types of motion are possible than before, so you might want to visually compare your simulated rope to the one above. 442 | 443 | Here's a larger example: 444 | 445 | ``` 446 | R 5 447 | U 8 448 | L 8 449 | D 3 450 | R 17 451 | D 10 452 | L 25 453 | U 20 454 | ``` 455 | 456 | These motions occur as follows (individual steps are not shown): 457 | 458 | ``` 459 | == Initial State == 460 | 461 | .......................... 462 | .......................... 463 | .......................... 464 | .......................... 465 | .......................... 466 | .......................... 467 | .......................... 468 | .......................... 469 | .......................... 470 | .......................... 471 | .......................... 472 | .......................... 473 | .......................... 474 | .......................... 475 | .......................... 476 | ...........H.............. (H covers 1, 2, 3, 4, 5, 6, 7, 8, 9, s) 477 | .......................... 478 | .......................... 479 | .......................... 480 | .......................... 481 | .......................... 482 | 483 | == R 5 == 484 | 485 | .......................... 486 | .......................... 487 | .......................... 488 | .......................... 489 | .......................... 490 | .......................... 491 | .......................... 492 | .......................... 493 | .......................... 494 | .......................... 495 | .......................... 496 | .......................... 497 | .......................... 498 | .......................... 499 | .......................... 500 | ...........54321H......... (5 covers 6, 7, 8, 9, s) 501 | .......................... 502 | .......................... 503 | .......................... 504 | .......................... 505 | .......................... 506 | 507 | == U 8 == 508 | 509 | .......................... 510 | .......................... 511 | .......................... 512 | .......................... 513 | .......................... 514 | .......................... 515 | .......................... 516 | ................H......... 517 | ................1......... 518 | ................2......... 519 | ................3......... 520 | ...............54......... 521 | ..............6........... 522 | .............7............ 523 | ............8............. 524 | ...........9.............. (9 covers s) 525 | .......................... 526 | .......................... 527 | .......................... 528 | .......................... 529 | .......................... 530 | 531 | == L 8 == 532 | 533 | .......................... 534 | .......................... 535 | .......................... 536 | .......................... 537 | .......................... 538 | .......................... 539 | .......................... 540 | ........H1234............. 541 | ............5............. 542 | ............6............. 543 | ............7............. 544 | ............8............. 545 | ............9............. 546 | .......................... 547 | .......................... 548 | ...........s.............. 549 | .......................... 550 | .......................... 551 | .......................... 552 | .......................... 553 | .......................... 554 | 555 | == D 3 == 556 | 557 | .......................... 558 | .......................... 559 | .......................... 560 | .......................... 561 | .......................... 562 | .......................... 563 | .......................... 564 | .......................... 565 | .........2345............. 566 | ........1...6............. 567 | ........H...7............. 568 | ............8............. 569 | ............9............. 570 | .......................... 571 | .......................... 572 | ...........s.............. 573 | .......................... 574 | .......................... 575 | .......................... 576 | .......................... 577 | .......................... 578 | 579 | == R 17 == 580 | 581 | .......................... 582 | .......................... 583 | .......................... 584 | .......................... 585 | .......................... 586 | .......................... 587 | .......................... 588 | .......................... 589 | .......................... 590 | .......................... 591 | ................987654321H 592 | .......................... 593 | .......................... 594 | .......................... 595 | .......................... 596 | ...........s.............. 597 | .......................... 598 | .......................... 599 | .......................... 600 | .......................... 601 | .......................... 602 | 603 | == D 10 == 604 | 605 | .......................... 606 | .......................... 607 | .......................... 608 | .......................... 609 | .......................... 610 | .......................... 611 | .......................... 612 | .......................... 613 | .......................... 614 | .......................... 615 | .......................... 616 | .......................... 617 | .......................... 618 | .......................... 619 | .......................... 620 | ...........s.........98765 621 | .........................4 622 | .........................3 623 | .........................2 624 | .........................1 625 | .........................H 626 | 627 | == L 25 == 628 | 629 | .......................... 630 | .......................... 631 | .......................... 632 | .......................... 633 | .......................... 634 | .......................... 635 | .......................... 636 | .......................... 637 | .......................... 638 | .......................... 639 | .......................... 640 | .......................... 641 | .......................... 642 | .......................... 643 | .......................... 644 | ...........s.............. 645 | .......................... 646 | .......................... 647 | .......................... 648 | .......................... 649 | H123456789................ 650 | 651 | == U 20 == 652 | 653 | H......................... 654 | 1......................... 655 | 2......................... 656 | 3......................... 657 | 4......................... 658 | 5......................... 659 | 6......................... 660 | 7......................... 661 | 8......................... 662 | 9......................... 663 | .......................... 664 | .......................... 665 | .......................... 666 | .......................... 667 | .......................... 668 | ...........s.............. 669 | .......................... 670 | .......................... 671 | .......................... 672 | .......................... 673 | .......................... 674 | ``` 675 | 676 | Now, the tail (9) visits 36 positions (including s) at least once: 677 | 678 | ``` 679 | .......................... 680 | .......................... 681 | .......................... 682 | .......................... 683 | .......................... 684 | .......................... 685 | .......................... 686 | .......................... 687 | .......................... 688 | #......................... 689 | #.............###......... 690 | #............#...#........ 691 | .#..........#.....#....... 692 | ..#..........#.....#...... 693 | ...#........#.......#..... 694 | ....#......s.........#.... 695 | .....#..............#..... 696 | ......#............#...... 697 | .......#..........#....... 698 | ........#........#........ 699 | .........########......... 700 | ``` 701 | 702 | Simulate your complete series of motions on a larger rope with ten knots. **How many positions does the tail of the rope visit at least once?** 703 | -------------------------------------------------------------------------------- /day-09/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines } from '../utils/index.js'; 2 | 3 | class Knot { 4 | static DIRECTIONS = { 5 | U: { x: 0, y: 1 }, 6 | R: { x: 1, y: 0 }, 7 | D: { x: 0, y: -1 }, 8 | L: { x: -1, y: 0 }, 9 | }; 10 | 11 | constructor() { 12 | this.position = { 13 | x: 0, 14 | y: 0, 15 | }; 16 | } 17 | 18 | move(direction) { 19 | const { x, y } = Knot.DIRECTIONS[direction]; 20 | 21 | this.position.x += x; 22 | this.position.y += y; 23 | } 24 | 25 | distanceFrom(knot) { 26 | return { 27 | x: knot.position.x - this.position.x, 28 | y: knot.position.y - this.position.y, 29 | }; 30 | } 31 | 32 | shouldFollow(previousKnot) { 33 | const distance = this.distanceFrom(previousKnot); 34 | 35 | return Math.abs(distance.x) > 1 || Math.abs(distance.y) > 1; 36 | } 37 | 38 | toString() { 39 | return `${this.position.x}, ${this.position.y}`; 40 | } 41 | } 42 | 43 | export function getVisitedPositions(input, numberOfKnots = 2) { 44 | const lines = splitLines(input); 45 | const visitedPositions = new Set(); 46 | 47 | const rope = Array(numberOfKnots) 48 | .fill() 49 | .map(() => new Knot()); 50 | 51 | for (let line of lines) { 52 | let [direction, steps] = line.split(' '); 53 | 54 | for (let i = 0; i < steps; i++) { 55 | const head = rope[0]; 56 | const tail = rope.at(-1); 57 | 58 | head.move(direction); 59 | 60 | for (let j = 1; j < numberOfKnots; j++) { 61 | const currentKnot = rope[j]; 62 | const previousKnot = rope[j - 1]; 63 | const distance = currentKnot.distanceFrom(previousKnot); 64 | 65 | if (currentKnot.shouldFollow(previousKnot)) { 66 | currentKnot.position.x += Math.sign(distance.x); 67 | currentKnot.position.y += Math.sign(distance.y); 68 | } 69 | } 70 | 71 | visitedPositions.add(`${tail}`); 72 | } 73 | } 74 | 75 | return visitedPositions; 76 | } 77 | 78 | if (process.env.NODE_ENV !== 'test') { 79 | const input = getInput(import.meta.url); 80 | const answer1 = getVisitedPositions(input, 2).size; 81 | const answer2 = getVisitedPositions(input, 10).size; 82 | 83 | console.log(` 84 | #1 Simulate your complete hypothetical series of motions. How many 85 | positions does the tail of the rope visit at least once? 86 | ${answer1} 87 | 88 | #2 Simulate your complete series of motions on a larger rope with 89 | ten knots. How many positions does the tail of the rope visit 90 | at least once? 91 | ${answer2} 92 | `); 93 | } 94 | -------------------------------------------------------------------------------- /day-09/index.test.js: -------------------------------------------------------------------------------- 1 | import { getVisitedPositions } from './index.js'; 2 | 3 | describe('getVisitedPositions', () => { 4 | it('should return the number of positions the tail of the rope with two knots visits at least once', () => { 5 | const input = ` 6 | R 4 7 | U 4 8 | L 3 9 | D 1 10 | R 4 11 | D 1 12 | L 5 13 | R 2 14 | `; 15 | 16 | expect(getVisitedPositions(input, 2).size).toEqual(13); 17 | }); 18 | 19 | it('should return the number of positions the tail of the rope with ten knots visits at least once', () => { 20 | const input = ` 21 | R 5 22 | U 8 23 | L 8 24 | D 3 25 | R 17 26 | D 10 27 | L 25 28 | U 20 29 | `; 30 | expect(getVisitedPositions(input, 10).size).toEqual(36); 31 | }); 32 | }); 33 | -------------------------------------------------------------------------------- /day-09/input.txt: -------------------------------------------------------------------------------- 1 | L 1 2 | D 2 3 | R 2 4 | L 1 5 | D 1 6 | L 1 7 | U 1 8 | R 1 9 | L 2 10 | R 2 11 | L 2 12 | D 1 13 | R 2 14 | D 1 15 | U 2 16 | R 2 17 | D 1 18 | R 1 19 | L 2 20 | R 1 21 | D 1 22 | U 2 23 | R 2 24 | D 1 25 | R 2 26 | L 1 27 | D 1 28 | U 1 29 | R 1 30 | D 2 31 | L 1 32 | D 1 33 | L 1 34 | U 1 35 | L 2 36 | U 1 37 | L 1 38 | U 1 39 | L 1 40 | D 2 41 | R 2 42 | U 1 43 | D 2 44 | R 1 45 | U 1 46 | D 1 47 | R 1 48 | U 2 49 | L 2 50 | D 2 51 | R 1 52 | U 2 53 | L 2 54 | U 1 55 | D 1 56 | L 1 57 | R 2 58 | L 2 59 | R 1 60 | D 2 61 | L 1 62 | D 2 63 | L 1 64 | R 2 65 | U 2 66 | D 2 67 | U 1 68 | R 2 69 | D 2 70 | L 2 71 | U 1 72 | D 2 73 | R 1 74 | L 2 75 | R 1 76 | L 2 77 | U 2 78 | D 2 79 | U 2 80 | D 2 81 | R 1 82 | U 2 83 | L 2 84 | D 1 85 | U 2 86 | L 1 87 | D 1 88 | R 2 89 | U 1 90 | L 1 91 | D 1 92 | U 2 93 | D 2 94 | R 2 95 | U 1 96 | L 2 97 | D 2 98 | L 1 99 | D 2 100 | L 1 101 | U 1 102 | R 2 103 | L 2 104 | D 1 105 | R 2 106 | U 2 107 | R 2 108 | L 2 109 | D 1 110 | R 1 111 | L 1 112 | D 2 113 | U 2 114 | L 1 115 | D 1 116 | R 1 117 | L 3 118 | U 2 119 | R 2 120 | D 3 121 | L 1 122 | R 3 123 | L 1 124 | R 2 125 | D 1 126 | U 3 127 | L 1 128 | U 2 129 | L 1 130 | D 3 131 | R 3 132 | D 1 133 | U 3 134 | R 2 135 | D 2 136 | R 2 137 | L 1 138 | U 1 139 | R 1 140 | U 2 141 | R 3 142 | U 1 143 | D 1 144 | U 1 145 | R 3 146 | D 2 147 | R 2 148 | U 3 149 | D 1 150 | R 3 151 | L 3 152 | U 3 153 | D 3 154 | R 1 155 | D 3 156 | L 1 157 | D 3 158 | L 1 159 | R 1 160 | U 1 161 | L 2 162 | D 3 163 | U 3 164 | D 2 165 | U 3 166 | D 2 167 | U 2 168 | D 1 169 | R 2 170 | U 3 171 | L 1 172 | R 2 173 | L 3 174 | U 3 175 | D 3 176 | L 2 177 | R 2 178 | U 3 179 | R 1 180 | L 1 181 | U 1 182 | D 1 183 | R 2 184 | L 3 185 | U 3 186 | D 1 187 | L 1 188 | U 1 189 | R 1 190 | D 2 191 | L 2 192 | D 2 193 | R 3 194 | D 2 195 | R 3 196 | D 2 197 | R 1 198 | D 1 199 | R 3 200 | D 1 201 | U 1 202 | L 1 203 | R 2 204 | D 3 205 | L 3 206 | R 1 207 | L 2 208 | R 1 209 | U 3 210 | D 2 211 | R 1 212 | U 1 213 | L 2 214 | R 2 215 | L 2 216 | D 1 217 | U 3 218 | R 3 219 | D 2 220 | R 1 221 | U 2 222 | L 3 223 | R 1 224 | D 1 225 | U 2 226 | L 4 227 | D 2 228 | R 1 229 | U 4 230 | R 4 231 | D 3 232 | R 3 233 | U 2 234 | L 2 235 | U 1 236 | D 3 237 | U 2 238 | D 2 239 | R 4 240 | D 3 241 | R 3 242 | D 4 243 | R 2 244 | U 2 245 | L 1 246 | D 1 247 | L 2 248 | U 4 249 | D 4 250 | R 3 251 | U 2 252 | R 3 253 | U 4 254 | D 2 255 | R 3 256 | D 4 257 | L 3 258 | D 1 259 | R 4 260 | D 4 261 | R 4 262 | L 3 263 | U 1 264 | L 1 265 | D 4 266 | L 3 267 | D 1 268 | U 2 269 | R 4 270 | U 1 271 | L 4 272 | D 3 273 | U 2 274 | R 4 275 | D 3 276 | U 3 277 | L 4 278 | U 2 279 | R 1 280 | U 1 281 | D 3 282 | R 3 283 | D 1 284 | U 1 285 | L 3 286 | R 1 287 | D 2 288 | R 4 289 | U 2 290 | D 4 291 | U 4 292 | L 4 293 | R 4 294 | D 2 295 | R 3 296 | D 3 297 | R 4 298 | U 1 299 | D 3 300 | R 4 301 | L 1 302 | U 1 303 | L 1 304 | D 4 305 | R 1 306 | U 4 307 | L 3 308 | R 2 309 | U 4 310 | R 3 311 | U 1 312 | L 3 313 | D 2 314 | L 2 315 | R 3 316 | D 1 317 | L 4 318 | D 2 319 | R 3 320 | L 4 321 | R 4 322 | L 2 323 | U 1 324 | D 1 325 | R 3 326 | U 4 327 | D 4 328 | U 4 329 | D 4 330 | R 4 331 | U 4 332 | D 1 333 | U 1 334 | D 4 335 | U 1 336 | D 4 337 | U 4 338 | R 4 339 | D 4 340 | L 4 341 | D 1 342 | U 5 343 | R 5 344 | U 5 345 | L 1 346 | R 4 347 | U 5 348 | L 2 349 | U 4 350 | D 1 351 | R 1 352 | L 4 353 | D 2 354 | L 5 355 | D 5 356 | R 3 357 | L 2 358 | R 1 359 | U 1 360 | R 5 361 | D 2 362 | U 1 363 | L 1 364 | D 4 365 | U 4 366 | L 2 367 | U 4 368 | L 1 369 | D 4 370 | L 1 371 | U 4 372 | L 3 373 | U 3 374 | D 2 375 | L 3 376 | D 2 377 | L 3 378 | R 1 379 | L 2 380 | U 1 381 | L 2 382 | R 2 383 | D 5 384 | U 4 385 | R 1 386 | D 5 387 | U 2 388 | R 3 389 | U 4 390 | L 4 391 | R 5 392 | L 2 393 | R 5 394 | U 5 395 | D 3 396 | R 2 397 | D 1 398 | R 2 399 | U 4 400 | D 1 401 | R 4 402 | D 5 403 | R 4 404 | L 4 405 | U 5 406 | D 1 407 | L 2 408 | R 1 409 | U 3 410 | L 5 411 | R 5 412 | L 2 413 | D 3 414 | L 2 415 | R 3 416 | U 2 417 | D 2 418 | U 3 419 | L 5 420 | U 3 421 | D 1 422 | R 1 423 | D 3 424 | L 2 425 | U 1 426 | D 2 427 | U 4 428 | L 4 429 | U 5 430 | R 5 431 | U 5 432 | L 5 433 | R 3 434 | L 1 435 | D 1 436 | L 3 437 | D 4 438 | R 1 439 | D 1 440 | R 3 441 | L 4 442 | U 4 443 | L 1 444 | R 5 445 | D 4 446 | U 2 447 | D 6 448 | U 6 449 | L 6 450 | U 2 451 | L 2 452 | D 6 453 | U 2 454 | R 2 455 | U 1 456 | R 6 457 | D 6 458 | R 5 459 | L 4 460 | R 3 461 | D 4 462 | L 6 463 | U 1 464 | D 2 465 | L 5 466 | U 2 467 | D 1 468 | U 6 469 | R 4 470 | L 4 471 | U 3 472 | L 3 473 | U 6 474 | L 4 475 | R 4 476 | L 5 477 | U 2 478 | L 1 479 | U 1 480 | D 5 481 | U 4 482 | D 5 483 | L 5 484 | U 3 485 | R 6 486 | U 5 487 | D 6 488 | R 3 489 | D 1 490 | L 3 491 | R 5 492 | U 5 493 | R 4 494 | D 3 495 | U 1 496 | D 1 497 | R 1 498 | D 1 499 | L 6 500 | U 2 501 | D 4 502 | U 6 503 | D 4 504 | L 6 505 | D 4 506 | R 6 507 | U 4 508 | R 2 509 | D 2 510 | U 1 511 | L 2 512 | U 5 513 | D 4 514 | L 2 515 | D 1 516 | L 3 517 | R 1 518 | L 1 519 | R 6 520 | L 3 521 | U 5 522 | D 3 523 | R 5 524 | U 1 525 | D 5 526 | R 4 527 | D 2 528 | U 6 529 | R 1 530 | U 3 531 | D 2 532 | R 1 533 | U 6 534 | R 2 535 | U 5 536 | R 4 537 | D 6 538 | U 1 539 | R 2 540 | D 6 541 | U 5 542 | R 1 543 | D 6 544 | U 2 545 | L 3 546 | U 3 547 | D 1 548 | R 4 549 | D 1 550 | L 3 551 | R 4 552 | U 2 553 | R 6 554 | L 3 555 | R 6 556 | U 6 557 | D 1 558 | R 4 559 | D 2 560 | U 6 561 | D 3 562 | R 2 563 | L 1 564 | D 5 565 | L 6 566 | R 4 567 | D 3 568 | R 2 569 | U 2 570 | R 4 571 | D 1 572 | U 2 573 | L 6 574 | D 3 575 | L 3 576 | D 6 577 | L 4 578 | U 6 579 | D 2 580 | R 3 581 | D 7 582 | L 7 583 | R 4 584 | D 2 585 | L 1 586 | R 7 587 | L 7 588 | U 7 589 | D 3 590 | R 2 591 | L 4 592 | D 1 593 | L 2 594 | U 6 595 | D 6 596 | R 5 597 | L 5 598 | U 3 599 | L 5 600 | R 2 601 | L 5 602 | U 3 603 | D 6 604 | L 1 605 | D 3 606 | L 7 607 | U 1 608 | R 7 609 | D 1 610 | R 2 611 | U 5 612 | L 3 613 | D 2 614 | L 2 615 | R 2 616 | U 2 617 | R 1 618 | L 5 619 | U 2 620 | D 2 621 | U 1 622 | R 4 623 | D 4 624 | L 6 625 | D 3 626 | U 4 627 | L 3 628 | D 3 629 | U 2 630 | L 4 631 | D 2 632 | R 3 633 | L 6 634 | R 3 635 | D 6 636 | U 1 637 | R 3 638 | U 7 639 | D 5 640 | L 1 641 | R 7 642 | L 5 643 | R 1 644 | D 7 645 | U 4 646 | L 3 647 | R 4 648 | D 1 649 | L 5 650 | D 3 651 | R 6 652 | U 5 653 | L 5 654 | R 5 655 | D 5 656 | U 7 657 | R 1 658 | D 1 659 | U 5 660 | D 3 661 | R 2 662 | U 6 663 | D 5 664 | U 3 665 | L 3 666 | R 4 667 | L 8 668 | U 2 669 | R 1 670 | U 4 671 | R 5 672 | L 6 673 | U 4 674 | R 3 675 | D 2 676 | U 7 677 | R 7 678 | D 1 679 | U 1 680 | L 3 681 | R 4 682 | U 6 683 | L 8 684 | D 4 685 | R 5 686 | D 6 687 | L 1 688 | R 8 689 | U 2 690 | L 7 691 | U 5 692 | R 4 693 | U 1 694 | D 1 695 | R 8 696 | L 6 697 | D 6 698 | R 1 699 | D 1 700 | U 2 701 | R 1 702 | L 6 703 | R 5 704 | U 1 705 | D 1 706 | L 2 707 | U 7 708 | R 4 709 | D 6 710 | L 3 711 | D 7 712 | U 1 713 | R 7 714 | D 1 715 | R 6 716 | L 2 717 | D 4 718 | L 3 719 | R 7 720 | L 7 721 | U 8 722 | R 7 723 | L 5 724 | D 8 725 | R 1 726 | D 4 727 | L 3 728 | R 7 729 | L 4 730 | U 7 731 | L 3 732 | D 7 733 | L 4 734 | R 8 735 | L 5 736 | D 2 737 | R 3 738 | U 6 739 | D 1 740 | L 7 741 | D 1 742 | U 2 743 | D 8 744 | U 7 745 | R 1 746 | U 8 747 | L 4 748 | U 4 749 | D 5 750 | R 2 751 | D 7 752 | R 5 753 | L 4 754 | D 4 755 | U 4 756 | D 5 757 | U 2 758 | D 5 759 | R 8 760 | D 7 761 | U 2 762 | D 7 763 | R 3 764 | U 6 765 | L 6 766 | D 5 767 | L 5 768 | R 3 769 | U 5 770 | R 5 771 | L 3 772 | D 3 773 | R 3 774 | D 5 775 | R 6 776 | D 3 777 | L 1 778 | U 6 779 | R 4 780 | D 4 781 | R 8 782 | D 6 783 | L 8 784 | D 2 785 | U 1 786 | L 9 787 | R 8 788 | D 6 789 | L 8 790 | R 6 791 | L 8 792 | U 4 793 | L 6 794 | R 5 795 | U 1 796 | L 5 797 | R 8 798 | D 3 799 | L 8 800 | R 9 801 | U 9 802 | L 5 803 | D 5 804 | R 2 805 | D 1 806 | U 4 807 | R 1 808 | U 2 809 | R 2 810 | L 8 811 | D 1 812 | L 3 813 | D 2 814 | U 1 815 | L 8 816 | R 5 817 | L 2 818 | D 9 819 | U 4 820 | L 5 821 | D 3 822 | U 4 823 | D 8 824 | L 4 825 | U 1 826 | L 1 827 | D 2 828 | U 6 829 | D 8 830 | U 3 831 | D 2 832 | U 3 833 | R 5 834 | U 6 835 | L 1 836 | U 1 837 | L 8 838 | D 9 839 | L 4 840 | U 4 841 | R 3 842 | D 6 843 | U 5 844 | L 8 845 | D 4 846 | U 4 847 | L 8 848 | R 6 849 | L 4 850 | U 5 851 | R 5 852 | U 4 853 | D 4 854 | U 4 855 | R 7 856 | L 8 857 | U 6 858 | L 9 859 | R 8 860 | U 5 861 | L 2 862 | U 5 863 | D 3 864 | L 7 865 | D 4 866 | R 1 867 | U 3 868 | R 6 869 | L 9 870 | R 8 871 | U 8 872 | L 7 873 | R 1 874 | L 1 875 | U 3 876 | D 8 877 | R 3 878 | D 1 879 | L 5 880 | D 2 881 | R 4 882 | U 9 883 | L 1 884 | R 1 885 | L 5 886 | R 4 887 | U 8 888 | D 6 889 | U 6 890 | R 9 891 | L 3 892 | R 9 893 | U 1 894 | R 9 895 | D 5 896 | L 4 897 | R 6 898 | L 3 899 | R 2 900 | U 9 901 | D 8 902 | R 4 903 | L 6 904 | R 5 905 | L 6 906 | U 6 907 | R 8 908 | U 10 909 | L 2 910 | R 1 911 | D 8 912 | L 9 913 | U 4 914 | D 1 915 | L 9 916 | R 6 917 | U 7 918 | D 7 919 | L 6 920 | R 6 921 | U 2 922 | L 3 923 | U 6 924 | R 4 925 | L 10 926 | R 1 927 | L 5 928 | U 2 929 | R 6 930 | D 2 931 | R 9 932 | L 4 933 | U 4 934 | D 1 935 | L 7 936 | R 8 937 | L 1 938 | D 9 939 | L 6 940 | U 6 941 | L 10 942 | U 1 943 | L 2 944 | R 2 945 | U 3 946 | L 5 947 | D 4 948 | L 8 949 | D 7 950 | L 5 951 | R 3 952 | D 7 953 | U 10 954 | D 10 955 | R 8 956 | D 3 957 | R 7 958 | D 5 959 | R 10 960 | D 9 961 | R 6 962 | L 3 963 | R 1 964 | U 8 965 | L 3 966 | R 9 967 | U 4 968 | D 3 969 | R 8 970 | D 10 971 | U 5 972 | D 8 973 | L 3 974 | D 8 975 | L 3 976 | D 6 977 | R 6 978 | D 1 979 | R 3 980 | D 10 981 | R 4 982 | L 2 983 | R 10 984 | D 4 985 | U 1 986 | L 9 987 | R 9 988 | D 10 989 | U 4 990 | D 2 991 | L 5 992 | R 8 993 | L 2 994 | R 4 995 | U 5 996 | D 1 997 | L 3 998 | U 4 999 | D 7 1000 | L 11 1001 | R 2 1002 | L 1 1003 | D 3 1004 | R 8 1005 | D 5 1006 | U 6 1007 | L 11 1008 | D 7 1009 | U 3 1010 | R 4 1011 | L 6 1012 | U 2 1013 | D 1 1014 | R 5 1015 | U 9 1016 | L 3 1017 | U 4 1018 | R 9 1019 | D 11 1020 | R 1 1021 | U 8 1022 | L 7 1023 | R 6 1024 | D 11 1025 | U 8 1026 | R 3 1027 | D 8 1028 | U 6 1029 | R 8 1030 | U 8 1031 | D 9 1032 | U 6 1033 | R 7 1034 | U 11 1035 | L 10 1036 | U 11 1037 | L 10 1038 | U 10 1039 | R 11 1040 | U 10 1041 | L 10 1042 | R 6 1043 | L 11 1044 | D 1 1045 | L 5 1046 | D 4 1047 | R 1 1048 | L 4 1049 | U 2 1050 | D 8 1051 | L 10 1052 | R 8 1053 | D 10 1054 | L 2 1055 | D 5 1056 | L 11 1057 | R 6 1058 | L 9 1059 | U 3 1060 | L 1 1061 | R 11 1062 | L 8 1063 | D 5 1064 | U 11 1065 | D 10 1066 | R 5 1067 | U 9 1068 | L 4 1069 | U 5 1070 | R 8 1071 | L 8 1072 | U 1 1073 | L 11 1074 | U 6 1075 | R 6 1076 | D 5 1077 | R 5 1078 | L 4 1079 | U 2 1080 | L 6 1081 | D 3 1082 | L 9 1083 | R 6 1084 | U 3 1085 | D 11 1086 | R 1 1087 | D 11 1088 | U 4 1089 | R 9 1090 | D 3 1091 | L 7 1092 | D 7 1093 | L 11 1094 | D 5 1095 | L 5 1096 | D 8 1097 | R 10 1098 | U 2 1099 | L 6 1100 | U 10 1101 | D 10 1102 | R 4 1103 | D 6 1104 | U 10 1105 | R 3 1106 | U 5 1107 | R 4 1108 | U 3 1109 | D 11 1110 | R 7 1111 | D 10 1112 | L 6 1113 | U 2 1114 | L 11 1115 | D 12 1116 | L 8 1117 | U 11 1118 | D 10 1119 | L 2 1120 | D 10 1121 | L 2 1122 | R 3 1123 | D 6 1124 | L 9 1125 | D 9 1126 | U 2 1127 | L 5 1128 | R 3 1129 | U 3 1130 | D 1 1131 | U 7 1132 | L 5 1133 | R 2 1134 | U 7 1135 | D 12 1136 | U 5 1137 | L 1 1138 | R 3 1139 | D 8 1140 | U 3 1141 | D 12 1142 | R 5 1143 | L 11 1144 | U 5 1145 | L 2 1146 | R 3 1147 | L 7 1148 | R 9 1149 | U 5 1150 | D 3 1151 | L 4 1152 | D 8 1153 | U 6 1154 | R 11 1155 | D 10 1156 | U 3 1157 | R 4 1158 | L 3 1159 | R 9 1160 | U 7 1161 | D 5 1162 | L 10 1163 | R 1 1164 | U 8 1165 | D 9 1166 | L 12 1167 | R 6 1168 | D 11 1169 | U 7 1170 | D 11 1171 | R 2 1172 | D 9 1173 | R 11 1174 | U 12 1175 | R 2 1176 | D 11 1177 | R 5 1178 | L 1 1179 | U 6 1180 | D 4 1181 | L 7 1182 | U 10 1183 | L 5 1184 | D 8 1185 | R 7 1186 | L 7 1187 | R 6 1188 | U 7 1189 | L 9 1190 | U 12 1191 | L 9 1192 | U 2 1193 | R 6 1194 | U 11 1195 | L 2 1196 | D 3 1197 | R 3 1198 | U 3 1199 | R 8 1200 | D 5 1201 | R 10 1202 | D 12 1203 | R 1 1204 | D 3 1205 | U 8 1206 | D 2 1207 | L 4 1208 | U 7 1209 | R 1 1210 | L 11 1211 | R 7 1212 | U 11 1213 | D 3 1214 | R 9 1215 | L 1 1216 | D 1 1217 | R 11 1218 | L 12 1219 | R 1 1220 | U 11 1221 | R 9 1222 | L 12 1223 | R 5 1224 | D 11 1225 | R 10 1226 | U 3 1227 | L 13 1228 | U 11 1229 | L 11 1230 | R 3 1231 | L 1 1232 | U 12 1233 | L 7 1234 | U 2 1235 | D 7 1236 | U 9 1237 | R 2 1238 | U 7 1239 | L 10 1240 | R 9 1241 | U 13 1242 | D 8 1243 | R 7 1244 | D 7 1245 | L 1 1246 | U 2 1247 | L 9 1248 | D 9 1249 | L 13 1250 | R 13 1251 | L 12 1252 | U 3 1253 | L 1 1254 | R 5 1255 | D 8 1256 | U 2 1257 | D 12 1258 | R 9 1259 | D 11 1260 | R 12 1261 | L 10 1262 | U 9 1263 | R 1 1264 | U 11 1265 | L 5 1266 | R 10 1267 | L 7 1268 | R 9 1269 | U 11 1270 | D 3 1271 | R 13 1272 | L 11 1273 | U 4 1274 | R 1 1275 | U 7 1276 | L 2 1277 | R 3 1278 | L 6 1279 | D 4 1280 | R 8 1281 | L 8 1282 | U 10 1283 | D 12 1284 | U 9 1285 | R 7 1286 | D 1 1287 | R 8 1288 | U 7 1289 | R 1 1290 | D 8 1291 | L 6 1292 | D 13 1293 | L 6 1294 | R 4 1295 | U 13 1296 | L 2 1297 | R 5 1298 | D 2 1299 | U 1 1300 | L 6 1301 | R 7 1302 | D 11 1303 | L 9 1304 | R 11 1305 | U 3 1306 | L 8 1307 | R 6 1308 | L 10 1309 | U 9 1310 | R 1 1311 | U 3 1312 | R 1 1313 | L 6 1314 | R 4 1315 | L 3 1316 | D 8 1317 | U 3 1318 | D 3 1319 | U 8 1320 | L 12 1321 | R 5 1322 | L 3 1323 | D 8 1324 | L 7 1325 | D 3 1326 | R 5 1327 | L 3 1328 | R 11 1329 | L 4 1330 | U 6 1331 | R 7 1332 | L 11 1333 | D 4 1334 | R 5 1335 | U 6 1336 | R 13 1337 | D 11 1338 | U 2 1339 | D 12 1340 | L 8 1341 | R 3 1342 | D 4 1343 | L 12 1344 | D 7 1345 | R 14 1346 | U 8 1347 | R 12 1348 | U 14 1349 | R 1 1350 | L 3 1351 | R 13 1352 | U 14 1353 | D 12 1354 | R 4 1355 | U 4 1356 | R 14 1357 | D 10 1358 | U 11 1359 | R 10 1360 | D 13 1361 | U 8 1362 | R 13 1363 | L 9 1364 | U 6 1365 | D 7 1366 | U 9 1367 | L 11 1368 | U 10 1369 | L 14 1370 | U 7 1371 | L 5 1372 | D 1 1373 | U 8 1374 | R 14 1375 | U 12 1376 | L 1 1377 | R 4 1378 | L 7 1379 | D 2 1380 | R 5 1381 | D 3 1382 | R 14 1383 | U 6 1384 | D 7 1385 | R 2 1386 | L 8 1387 | U 14 1388 | D 12 1389 | U 12 1390 | L 5 1391 | D 5 1392 | L 1 1393 | U 3 1394 | L 10 1395 | R 4 1396 | U 2 1397 | R 11 1398 | D 6 1399 | U 12 1400 | D 5 1401 | U 11 1402 | D 5 1403 | L 8 1404 | D 1 1405 | L 7 1406 | D 1 1407 | U 9 1408 | D 6 1409 | L 10 1410 | D 7 1411 | L 10 1412 | R 7 1413 | D 11 1414 | L 9 1415 | U 13 1416 | D 10 1417 | U 10 1418 | R 13 1419 | L 2 1420 | R 13 1421 | U 3 1422 | R 8 1423 | D 7 1424 | L 2 1425 | U 1 1426 | L 7 1427 | D 11 1428 | U 6 1429 | D 12 1430 | L 3 1431 | R 3 1432 | D 1 1433 | R 2 1434 | D 2 1435 | U 4 1436 | D 1 1437 | L 12 1438 | U 5 1439 | L 3 1440 | R 13 1441 | D 9 1442 | L 3 1443 | D 10 1444 | L 5 1445 | R 13 1446 | D 9 1447 | L 7 1448 | R 12 1449 | L 8 1450 | U 1 1451 | R 5 1452 | L 3 1453 | D 7 1454 | R 4 1455 | U 6 1456 | R 4 1457 | U 15 1458 | D 13 1459 | R 3 1460 | L 14 1461 | R 1 1462 | U 3 1463 | R 4 1464 | U 12 1465 | R 7 1466 | D 7 1467 | U 1 1468 | R 12 1469 | D 9 1470 | R 14 1471 | U 10 1472 | R 1 1473 | U 6 1474 | D 10 1475 | R 14 1476 | D 12 1477 | R 6 1478 | D 13 1479 | U 14 1480 | R 15 1481 | U 9 1482 | L 6 1483 | R 7 1484 | L 13 1485 | R 4 1486 | D 8 1487 | R 2 1488 | L 6 1489 | U 13 1490 | L 15 1491 | D 5 1492 | U 4 1493 | R 14 1494 | D 5 1495 | L 6 1496 | U 3 1497 | R 10 1498 | L 12 1499 | U 9 1500 | D 5 1501 | L 4 1502 | U 1 1503 | R 10 1504 | L 3 1505 | U 5 1506 | R 12 1507 | D 14 1508 | L 10 1509 | R 9 1510 | D 2 1511 | U 6 1512 | D 6 1513 | U 1 1514 | L 8 1515 | R 3 1516 | D 8 1517 | R 1 1518 | D 5 1519 | L 10 1520 | D 11 1521 | L 5 1522 | R 6 1523 | D 8 1524 | R 2 1525 | D 12 1526 | L 7 1527 | R 14 1528 | D 8 1529 | L 8 1530 | U 14 1531 | R 13 1532 | L 7 1533 | D 8 1534 | U 3 1535 | L 6 1536 | U 6 1537 | D 4 1538 | R 9 1539 | L 11 1540 | R 2 1541 | U 10 1542 | R 14 1543 | D 8 1544 | R 2 1545 | U 10 1546 | R 7 1547 | U 3 1548 | R 4 1549 | D 9 1550 | U 9 1551 | D 11 1552 | U 5 1553 | D 9 1554 | R 14 1555 | U 13 1556 | D 5 1557 | L 7 1558 | R 2 1559 | D 9 1560 | R 2 1561 | U 9 1562 | D 8 1563 | L 12 1564 | R 12 1565 | L 3 1566 | R 6 1567 | U 16 1568 | R 15 1569 | D 8 1570 | U 3 1571 | R 1 1572 | L 8 1573 | D 11 1574 | L 6 1575 | R 5 1576 | L 14 1577 | D 15 1578 | U 1 1579 | R 10 1580 | D 11 1581 | R 16 1582 | D 1 1583 | U 6 1584 | L 12 1585 | U 3 1586 | D 9 1587 | U 1 1588 | D 13 1589 | L 14 1590 | R 8 1591 | L 9 1592 | D 3 1593 | U 16 1594 | R 3 1595 | L 11 1596 | R 13 1597 | L 10 1598 | U 10 1599 | L 3 1600 | R 7 1601 | L 6 1602 | R 2 1603 | D 4 1604 | U 15 1605 | R 13 1606 | U 10 1607 | D 1 1608 | L 3 1609 | D 15 1610 | L 9 1611 | R 8 1612 | D 14 1613 | R 11 1614 | L 11 1615 | D 4 1616 | U 15 1617 | L 2 1618 | U 4 1619 | D 3 1620 | U 6 1621 | D 5 1622 | U 15 1623 | L 8 1624 | D 14 1625 | R 1 1626 | U 8 1627 | L 7 1628 | D 8 1629 | R 8 1630 | U 1 1631 | D 8 1632 | R 11 1633 | D 4 1634 | U 14 1635 | R 11 1636 | D 16 1637 | U 4 1638 | D 9 1639 | R 11 1640 | L 16 1641 | D 5 1642 | L 9 1643 | R 6 1644 | U 9 1645 | D 16 1646 | R 4 1647 | L 11 1648 | U 11 1649 | D 6 1650 | U 13 1651 | D 14 1652 | U 13 1653 | L 8 1654 | U 9 1655 | D 3 1656 | R 4 1657 | L 8 1658 | D 7 1659 | L 12 1660 | D 6 1661 | R 14 1662 | L 11 1663 | U 7 1664 | D 4 1665 | U 1 1666 | L 11 1667 | U 15 1668 | L 5 1669 | D 8 1670 | U 2 1671 | R 15 1672 | L 5 1673 | R 7 1674 | L 8 1675 | R 15 1676 | U 8 1677 | D 7 1678 | U 17 1679 | D 5 1680 | U 15 1681 | R 8 1682 | U 15 1683 | L 7 1684 | U 5 1685 | D 11 1686 | L 4 1687 | U 11 1688 | D 13 1689 | R 10 1690 | D 12 1691 | L 16 1692 | D 9 1693 | L 17 1694 | U 1 1695 | R 10 1696 | D 1 1697 | R 16 1698 | U 6 1699 | L 2 1700 | D 7 1701 | U 8 1702 | D 12 1703 | L 15 1704 | U 16 1705 | R 5 1706 | L 13 1707 | D 2 1708 | U 7 1709 | L 14 1710 | D 6 1711 | L 8 1712 | R 12 1713 | U 4 1714 | D 7 1715 | U 4 1716 | R 3 1717 | U 8 1718 | D 5 1719 | L 4 1720 | U 3 1721 | R 13 1722 | L 14 1723 | R 7 1724 | U 11 1725 | D 9 1726 | R 1 1727 | D 15 1728 | R 11 1729 | L 8 1730 | R 7 1731 | D 17 1732 | U 13 1733 | R 15 1734 | D 5 1735 | R 15 1736 | U 7 1737 | R 10 1738 | U 14 1739 | D 2 1740 | L 7 1741 | R 13 1742 | D 10 1743 | U 16 1744 | D 6 1745 | R 10 1746 | D 4 1747 | U 1 1748 | R 14 1749 | U 2 1750 | L 2 1751 | U 1 1752 | L 13 1753 | D 2 1754 | U 16 1755 | D 1 1756 | U 8 1757 | L 7 1758 | U 17 1759 | D 9 1760 | L 10 1761 | U 16 1762 | D 13 1763 | U 15 1764 | D 12 1765 | L 6 1766 | D 9 1767 | L 3 1768 | R 17 1769 | U 16 1770 | L 6 1771 | D 11 1772 | R 11 1773 | L 11 1774 | U 2 1775 | R 15 1776 | D 11 1777 | R 10 1778 | U 2 1779 | D 18 1780 | U 18 1781 | D 18 1782 | L 4 1783 | U 1 1784 | R 1 1785 | L 7 1786 | U 7 1787 | L 12 1788 | U 10 1789 | R 13 1790 | D 16 1791 | R 1 1792 | D 11 1793 | L 12 1794 | R 7 1795 | D 13 1796 | L 10 1797 | D 6 1798 | U 1 1799 | L 14 1800 | R 13 1801 | D 14 1802 | L 3 1803 | D 18 1804 | L 2 1805 | U 9 1806 | L 7 1807 | R 18 1808 | L 11 1809 | U 16 1810 | R 9 1811 | U 8 1812 | D 5 1813 | L 15 1814 | R 16 1815 | D 17 1816 | U 16 1817 | L 10 1818 | U 4 1819 | R 1 1820 | L 10 1821 | U 4 1822 | L 8 1823 | U 5 1824 | L 5 1825 | R 18 1826 | U 11 1827 | R 18 1828 | U 12 1829 | D 18 1830 | R 9 1831 | L 2 1832 | D 10 1833 | L 15 1834 | D 2 1835 | R 7 1836 | D 16 1837 | L 4 1838 | R 13 1839 | L 4 1840 | R 2 1841 | L 14 1842 | D 4 1843 | R 15 1844 | D 14 1845 | R 13 1846 | L 9 1847 | D 1 1848 | U 7 1849 | R 17 1850 | L 6 1851 | U 1 1852 | L 6 1853 | D 6 1854 | U 5 1855 | L 5 1856 | R 10 1857 | U 1 1858 | R 9 1859 | U 3 1860 | D 2 1861 | L 4 1862 | U 1 1863 | D 12 1864 | R 5 1865 | U 3 1866 | R 15 1867 | L 18 1868 | R 3 1869 | D 1 1870 | L 6 1871 | D 16 1872 | U 15 1873 | D 6 1874 | R 8 1875 | D 4 1876 | R 14 1877 | U 10 1878 | R 10 1879 | D 5 1880 | L 14 1881 | U 6 1882 | L 15 1883 | R 10 1884 | D 17 1885 | R 7 1886 | L 13 1887 | R 12 1888 | D 4 1889 | R 11 1890 | D 2 1891 | L 1 1892 | R 13 1893 | U 6 1894 | D 16 1895 | R 5 1896 | D 17 1897 | U 17 1898 | D 11 1899 | R 15 1900 | L 4 1901 | D 13 1902 | L 11 1903 | U 16 1904 | L 3 1905 | D 5 1906 | U 1 1907 | R 16 1908 | L 10 1909 | U 7 1910 | D 9 1911 | R 10 1912 | L 4 1913 | D 4 1914 | L 7 1915 | D 12 1916 | U 5 1917 | D 10 1918 | R 2 1919 | L 9 1920 | D 6 1921 | U 14 1922 | R 4 1923 | U 2 1924 | L 19 1925 | R 15 1926 | L 13 1927 | R 12 1928 | L 8 1929 | D 15 1930 | U 13 1931 | L 4 1932 | U 13 1933 | D 3 1934 | U 7 1935 | L 10 1936 | R 8 1937 | D 14 1938 | R 3 1939 | L 10 1940 | D 3 1941 | U 5 1942 | L 15 1943 | R 5 1944 | L 2 1945 | R 10 1946 | D 5 1947 | R 13 1948 | L 18 1949 | R 7 1950 | L 6 1951 | U 12 1952 | D 16 1953 | R 3 1954 | L 11 1955 | D 7 1956 | R 1 1957 | U 9 1958 | R 9 1959 | D 6 1960 | L 1 1961 | D 13 1962 | U 10 1963 | L 17 1964 | R 10 1965 | L 12 1966 | R 8 1967 | D 10 1968 | R 12 1969 | U 12 1970 | D 14 1971 | U 1 1972 | D 4 1973 | U 2 1974 | L 9 1975 | R 3 1976 | U 2 1977 | R 19 1978 | D 1 1979 | L 4 1980 | R 6 1981 | L 4 1982 | D 4 1983 | R 16 1984 | D 17 1985 | R 3 1986 | D 9 1987 | L 8 1988 | R 15 1989 | D 4 1990 | U 13 1991 | D 4 1992 | U 17 1993 | D 15 1994 | L 17 1995 | D 1 1996 | R 14 1997 | L 18 1998 | U 2 1999 | R 11 2000 | U 5 2001 | -------------------------------------------------------------------------------- /day-10/README.md: -------------------------------------------------------------------------------- 1 | # Day 10: Cathode-Ray Tube 2 | 3 | You avoid the ropes, plunge into the river, and swim to shore. 4 | 5 | The Elves yell something about meeting back up with them upriver, but the river is too loud to tell exactly what they're saying. They finish crossing the bridge and disappear from view. 6 | 7 | Situations like this must be why the Elves prioritized getting the communication system on your handheld device working. You pull it out of your pack, but the amount of water slowly draining from a big crack in its screen tells you it probably won't be of much immediate use. 8 | 9 | _Unless_, that is, you can design a replacement for the device's video system! It seems to be some kind of [cathode-ray tube](https://en.wikipedia.org/wiki/Cathode-ray_tube) screen and simple CPU that are both driven by a precise _clock circuit_. The clock circuit ticks at a constant rate; each tick is called a _cycle_. 10 | 11 | Start by figuring out the signal being sent by the CPU. The CPU has a single register, `X`, which starts with the value `1`. It supports only two instructions: 12 | 13 | - `addx V` takes _two cycles_ to complete. _After_ two cycles, the `X` register is increased by the value `V`. (`V` can be negative.) 14 | - `noop` takes _one cycle_ to complete. It has no other effect. 15 | 16 | The CPU uses these instructions in a program (your puzzle input) to, somehow, tell the screen what to draw. 17 | 18 | Consider the following small program: 19 | 20 | ``` 21 | noop 22 | addx 3 23 | addx -5 24 | ``` 25 | 26 | Execution of this program proceeds as follows: 27 | 28 | - At the start of the first cycle, the `noop` instruction begins execution. During the first cycle, `X` is `1`. After the first cycle, the `noop` instruction finishes execution, doing nothing. 29 | - At the start of the second cycle, the `addx 3` instruction begins execution. During the second cycle, `X` is still `1`. 30 | - During the third cycle, `X` is still `1`. After the third cycle, the `addx 3` instruction finishes execution, setting `X` to `4`. 31 | - At the start of the fourth cycle, the `addx -5` instruction begins execution. During the fourth cycle, `X` is still `4`. 32 | - During the fifth cycle, `X` is still `4`. After the fifth cycle, the `addx -5` instruction finishes execution, setting `X` to `-1`. 33 | 34 | Maybe you can learn something by looking at the value of the `X` register throughout execution. For now, consider the _signal strength_ (the cycle number multiplied by the value of the `X` register) _during_ the 20th cycle and every 40 cycles after that (that is, during the 20th, 60th, 100th, 140th, 180th, and 220th cycles). 35 | 36 | For example, consider this larger program: 37 | 38 | ``` 39 | addx 15 40 | addx -11 41 | addx 6 42 | addx -3 43 | addx 5 44 | addx -1 45 | addx -8 46 | addx 13 47 | addx 4 48 | noop 49 | addx -1 50 | addx 5 51 | addx -1 52 | addx 5 53 | addx -1 54 | addx 5 55 | addx -1 56 | addx 5 57 | addx -1 58 | addx -35 59 | addx 1 60 | addx 24 61 | addx -19 62 | addx 1 63 | addx 16 64 | addx -11 65 | noop 66 | noop 67 | addx 21 68 | addx -15 69 | noop 70 | noop 71 | addx -3 72 | addx 9 73 | addx 1 74 | addx -3 75 | addx 8 76 | addx 1 77 | addx 5 78 | noop 79 | noop 80 | noop 81 | noop 82 | noop 83 | addx -36 84 | noop 85 | addx 1 86 | addx 7 87 | noop 88 | noop 89 | noop 90 | addx 2 91 | addx 6 92 | noop 93 | noop 94 | noop 95 | noop 96 | noop 97 | addx 1 98 | noop 99 | noop 100 | addx 7 101 | addx 1 102 | noop 103 | addx -13 104 | addx 13 105 | addx 7 106 | noop 107 | addx 1 108 | addx -33 109 | noop 110 | noop 111 | noop 112 | addx 2 113 | noop 114 | noop 115 | noop 116 | addx 8 117 | noop 118 | addx -1 119 | addx 2 120 | addx 1 121 | noop 122 | addx 17 123 | addx -9 124 | addx 1 125 | addx 1 126 | addx -3 127 | addx 11 128 | noop 129 | noop 130 | addx 1 131 | noop 132 | addx 1 133 | noop 134 | noop 135 | addx -13 136 | addx -19 137 | addx 1 138 | addx 3 139 | addx 26 140 | addx -30 141 | addx 12 142 | addx -1 143 | addx 3 144 | addx 1 145 | noop 146 | noop 147 | noop 148 | addx -9 149 | addx 18 150 | addx 1 151 | addx 2 152 | noop 153 | noop 154 | addx 9 155 | noop 156 | noop 157 | noop 158 | addx -1 159 | addx 2 160 | addx -37 161 | addx 1 162 | addx 3 163 | noop 164 | addx 15 165 | addx -21 166 | addx 22 167 | addx -6 168 | addx 1 169 | noop 170 | addx 2 171 | addx 1 172 | noop 173 | addx -10 174 | noop 175 | noop 176 | addx 20 177 | addx 1 178 | addx 2 179 | addx 2 180 | addx -6 181 | addx -11 182 | noop 183 | noop 184 | noop 185 | ``` 186 | 187 | The interesting signal strengths can be determined as follows: 188 | 189 | - During the 20th cycle, register `X` has the value `21`, so the signal strength is 20 \* 21 = _420_. (The 20th cycle occurs in the middle of the second `addx -1`, so the value of register `X` is the starting value, `1`, plus all of the other `addx` values up to that point: 1 + 15 - 11 + 6 - 3 + 5 - 1 - 8 + 13 + 4 = 21.) 190 | - During the 60th cycle, register `X` has the value `19`, so the signal strength is 60 \* 19 = `1140`. 191 | - During the 100th cycle, register `X` has the value `18`, so the signal strength is 100 \* 18 = `1800`. 192 | - During the 140th cycle, register `X` has the value `21`, so the signal strength is 140 \* 21 = `2940`. 193 | - During the 180th cycle, register `X` has the value `16`, so the signal strength is 180 \* 16 = `2880`. 194 | - During the 220th cycle, register `X` has the value `18`, so the signal strength is 220 \* 18 = `3960`. 195 | 196 | The sum of these signal strengths is `13140`. 197 | 198 | Find the signal strength during the 20th, 60th, 100th, 140th, 180th, and 220th cycles. **What is the sum of these six signal strengths?** 199 | 200 | ## Part Two 201 | 202 | It seems like the `X` register controls the horizontal position of a [sprite](). Specifically, the sprite is 3 pixels wide, and the `X` register sets the horizontal position of the _middle_ of that sprite. (In this system, there is no such thing as "vertical position": if the sprite's horizontal position puts its pixels where the CRT is currently drawing, then those pixels will be drawn.) 203 | 204 | You count the pixels on the CRT: 40 wide and 6 high. This CRT screen draws the top row of pixels left-to-right, then the row below that, and so on. The left-most pixel in each row is in position `0`, and the right-most pixel in each row is in position `39`. 205 | 206 | Like the CPU, the CRT is tied closely to the clock circuit: the CRT draws _a single pixel during each cycle_. Representing each pixel of the screen as a `#`, here are the cycles during which the first and last pixel in each row are drawn: 207 | 208 | ``` 209 | Cycle 1 -> ######################################## <- Cycle 40 210 | Cycle 41 -> ######################################## <- Cycle 80 211 | Cycle 81 -> ######################################## <- Cycle 120 212 | Cycle 121 -> ######################################## <- Cycle 160 213 | Cycle 161 -> ######################################## <- Cycle 200 214 | Cycle 201 -> ######################################## <- Cycle 240 215 | ``` 216 | 217 | So, by [carefully](https://en.wikipedia.org/wiki/Racing_the_Beam) [timing](https://www.youtube.com/watch?v=sJFnWZH5FXc) the CPU instructions and the CRT drawing operations, you should be able to determine whether the sprite is visible the instant each pixel is drawn. If the sprite is positioned such that one of its three pixels is the pixel currently being drawn, the screen produces a _lit_ pixel (`#`); otherwise, the screen leaves the pixel _dark_ (`.`). 218 | 219 | The first few pixels from the larger example above are drawn as follows: 220 | 221 | ``` 222 | Sprite position: ###..................................... 223 | 224 | Start cycle 1: begin executing addx 15 225 | During cycle 1: CRT draws pixel in position 0 226 | Current CRT row: # 227 | 228 | During cycle 2: CRT draws pixel in position 1 229 | Current CRT row: ## 230 | End of cycle 2: finish executing addx 15 (Register X is now 16) 231 | Sprite position: ...............###...................... 232 | 233 | Start cycle 3: begin executing addx -11 234 | During cycle 3: CRT draws pixel in position 2 235 | Current CRT row: ##. 236 | 237 | During cycle 4: CRT draws pixel in position 3 238 | Current CRT row: ##.. 239 | End of cycle 4: finish executing addx -11 (Register X is now 5) 240 | Sprite position: ....###................................. 241 | 242 | Start cycle 5: begin executing addx 6 243 | During cycle 5: CRT draws pixel in position 4 244 | Current CRT row: ##..# 245 | 246 | During cycle 6: CRT draws pixel in position 5 247 | Current CRT row: ##..## 248 | End of cycle 6: finish executing addx 6 (Register X is now 11) 249 | Sprite position: ..........###........................... 250 | 251 | Start cycle 7: begin executing addx -3 252 | During cycle 7: CRT draws pixel in position 6 253 | Current CRT row: ##..##. 254 | 255 | During cycle 8: CRT draws pixel in position 7 256 | Current CRT row: ##..##.. 257 | End of cycle 8: finish executing addx -3 (Register X is now 8) 258 | Sprite position: .......###.............................. 259 | 260 | Start cycle 9: begin executing addx 5 261 | During cycle 9: CRT draws pixel in position 8 262 | Current CRT row: ##..##..# 263 | 264 | During cycle 10: CRT draws pixel in position 9 265 | Current CRT row: ##..##..## 266 | End of cycle 10: finish executing addx 5 (Register X is now 13) 267 | Sprite position: ............###......................... 268 | 269 | Start cycle 11: begin executing addx -1 270 | During cycle 11: CRT draws pixel in position 10 271 | Current CRT row: ##..##..##. 272 | 273 | During cycle 12: CRT draws pixel in position 11 274 | Current CRT row: ##..##..##.. 275 | End of cycle 12: finish executing addx -1 (Register X is now 12) 276 | Sprite position: ...........###.......................... 277 | 278 | Start cycle 13: begin executing addx -8 279 | During cycle 13: CRT draws pixel in position 12 280 | Current CRT row: ##..##..##..# 281 | 282 | During cycle 14: CRT draws pixel in position 13 283 | Current CRT row: ##..##..##..## 284 | End of cycle 14: finish executing addx -8 (Register X is now 4) 285 | Sprite position: ...###.................................. 286 | 287 | Start cycle 15: begin executing addx 13 288 | During cycle 15: CRT draws pixel in position 14 289 | Current CRT row: ##..##..##..##. 290 | 291 | During cycle 16: CRT draws pixel in position 15 292 | Current CRT row: ##..##..##..##.. 293 | End of cycle 16: finish executing addx 13 (Register X is now 17) 294 | Sprite position: ................###..................... 295 | 296 | Start cycle 17: begin executing addx 4 297 | During cycle 17: CRT draws pixel in position 16 298 | Current CRT row: ##..##..##..##..# 299 | 300 | During cycle 18: CRT draws pixel in position 17 301 | Current CRT row: ##..##..##..##..## 302 | End of cycle 18: finish executing addx 4 (Register X is now 21) 303 | Sprite position: ....................###................. 304 | 305 | Start cycle 19: begin executing noop 306 | During cycle 19: CRT draws pixel in position 18 307 | Current CRT row: ##..##..##..##..##. 308 | End of cycle 19: finish executing noop 309 | 310 | Start cycle 20: begin executing addx -1 311 | During cycle 20: CRT draws pixel in position 19 312 | Current CRT row: ##..##..##..##..##.. 313 | 314 | During cycle 21: CRT draws pixel in position 20 315 | Current CRT row: ##..##..##..##..##..# 316 | End of cycle 21: finish executing addx -1 (Register X is now 20) 317 | Sprite position: ...................###.................. 318 | ``` 319 | 320 | Allowing the program to run to completion causes the CRT to produce the following image: 321 | 322 | ``` 323 | ##..##..##..##..##..##..##..##..##..##.. 324 | ###...###...###...###...###...###...###. 325 | ####....####....####....####....####.... 326 | #####.....#####.....#####.....#####..... 327 | ######......######......######......#### 328 | #######.......#######.......#######..... 329 | ``` 330 | 331 | Render the image given by your program. **What eight capital letters appear on your CRT?** 332 | -------------------------------------------------------------------------------- /day-10/__snapshots__/index.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`renderImage should render eight capital letters 1`] = ` 4 | "██░░██░░██░░██░░██░░██░░██░░██░░██░░██░░ 5 | ███░░░███░░░███░░░███░░░███░░░███░░░███░ 6 | ████░░░░████░░░░████░░░░████░░░░████░░░░ 7 | █████░░░░░█████░░░░░█████░░░░░█████░░░░░ 8 | ██████░░░░░░██████░░░░░░██████░░░░░░████ 9 | ███████░░░░░░░███████░░░░░░░███████░░░░░ 10 | " 11 | `; 12 | -------------------------------------------------------------------------------- /day-10/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, splitLines } from '../utils/index.js'; 2 | 3 | const CHARS_PER_ROW = 40; 4 | 5 | function processInput(input, callback) { 6 | const lines = splitLines(input); 7 | let cycle = 1; 8 | let x = 1; 9 | 10 | for (const line of lines) { 11 | const [command, arg] = line.split(' '); 12 | const cycles = command === 'addx' ? 2 : 1; 13 | 14 | for (let i = 0; i < cycles; i++, cycle++) { 15 | callback(cycle, x); 16 | } 17 | 18 | x += Number(arg) || 0; 19 | } 20 | } 21 | 22 | export function getSumOfSignalStrengths(input) { 23 | let sum = 0; 24 | 25 | processInput(input, (cycle, x) => { 26 | if ((cycle - 20) % CHARS_PER_ROW === 0) { 27 | const signalStrength = cycle * x; 28 | sum += signalStrength; 29 | } 30 | }); 31 | 32 | return sum; 33 | } 34 | 35 | export function renderImage(input) { 36 | const PIXEL_DARK = '░'; 37 | const PIXEL_LIT = '█'; 38 | let result = ''; 39 | 40 | processInput(input, (cycle, x) => { 41 | const column = (cycle - 1) % CHARS_PER_ROW; 42 | const isPixelLit = x - 1 <= column && column <= x + 1; 43 | 44 | result += isPixelLit ? PIXEL_LIT : PIXEL_DARK; 45 | 46 | if (column === CHARS_PER_ROW - 1) { 47 | result += '\n'; 48 | } 49 | }); 50 | 51 | return result; 52 | } 53 | 54 | if (process.env.NODE_ENV !== 'test') { 55 | const input = getInput(import.meta.url); 56 | const answer1 = getSumOfSignalStrengths(input); 57 | const answer2 = renderImage(input); 58 | 59 | console.log(` 60 | #1 What is the sum of these six signal strengths? 61 | ${answer1} 62 | 63 | #2 What eight capital letters appear on your CRT? 64 | ${answer2} 65 | `); 66 | } 67 | -------------------------------------------------------------------------------- /day-10/index.test.js: -------------------------------------------------------------------------------- 1 | import { getSumOfSignalStrengths, renderImage } from './index.js'; 2 | 3 | const input = ` 4 | addx 15 5 | addx -11 6 | addx 6 7 | addx -3 8 | addx 5 9 | addx -1 10 | addx -8 11 | addx 13 12 | addx 4 13 | noop 14 | addx -1 15 | addx 5 16 | addx -1 17 | addx 5 18 | addx -1 19 | addx 5 20 | addx -1 21 | addx 5 22 | addx -1 23 | addx -35 24 | addx 1 25 | addx 24 26 | addx -19 27 | addx 1 28 | addx 16 29 | addx -11 30 | noop 31 | noop 32 | addx 21 33 | addx -15 34 | noop 35 | noop 36 | addx -3 37 | addx 9 38 | addx 1 39 | addx -3 40 | addx 8 41 | addx 1 42 | addx 5 43 | noop 44 | noop 45 | noop 46 | noop 47 | noop 48 | addx -36 49 | noop 50 | addx 1 51 | addx 7 52 | noop 53 | noop 54 | noop 55 | addx 2 56 | addx 6 57 | noop 58 | noop 59 | noop 60 | noop 61 | noop 62 | addx 1 63 | noop 64 | noop 65 | addx 7 66 | addx 1 67 | noop 68 | addx -13 69 | addx 13 70 | addx 7 71 | noop 72 | addx 1 73 | addx -33 74 | noop 75 | noop 76 | noop 77 | addx 2 78 | noop 79 | noop 80 | noop 81 | addx 8 82 | noop 83 | addx -1 84 | addx 2 85 | addx 1 86 | noop 87 | addx 17 88 | addx -9 89 | addx 1 90 | addx 1 91 | addx -3 92 | addx 11 93 | noop 94 | noop 95 | addx 1 96 | noop 97 | addx 1 98 | noop 99 | noop 100 | addx -13 101 | addx -19 102 | addx 1 103 | addx 3 104 | addx 26 105 | addx -30 106 | addx 12 107 | addx -1 108 | addx 3 109 | addx 1 110 | noop 111 | noop 112 | noop 113 | addx -9 114 | addx 18 115 | addx 1 116 | addx 2 117 | noop 118 | noop 119 | addx 9 120 | noop 121 | noop 122 | noop 123 | addx -1 124 | addx 2 125 | addx -37 126 | addx 1 127 | addx 3 128 | noop 129 | addx 15 130 | addx -21 131 | addx 22 132 | addx -6 133 | addx 1 134 | noop 135 | addx 2 136 | addx 1 137 | noop 138 | addx -10 139 | noop 140 | noop 141 | addx 20 142 | addx 1 143 | addx 2 144 | addx 2 145 | addx -6 146 | addx -11 147 | noop 148 | noop 149 | noop 150 | `; 151 | 152 | describe('getSumOfSignalStrengths', () => { 153 | it('should return the sum of the six signal strengths', () => { 154 | expect(getSumOfSignalStrengths(input)).toEqual(13140); 155 | }); 156 | }); 157 | 158 | describe('renderImage', () => { 159 | it('should render eight capital letters', () => { 160 | expect(renderImage(input)).toMatchSnapshot(); 161 | }); 162 | }); 163 | -------------------------------------------------------------------------------- /day-10/input.txt: -------------------------------------------------------------------------------- 1 | addx 1 2 | noop 3 | noop 4 | addx 4 5 | addx 5 6 | addx -2 7 | addx 19 8 | addx -12 9 | addx 3 10 | addx -2 11 | addx 4 12 | noop 13 | noop 14 | noop 15 | addx 3 16 | addx -8 17 | addx 15 18 | addx 1 19 | noop 20 | noop 21 | addx 6 22 | addx -1 23 | noop 24 | addx -38 25 | noop 26 | addx 10 27 | addx -5 28 | noop 29 | addx 3 30 | addx 2 31 | addx 7 32 | noop 33 | noop 34 | addx 3 35 | noop 36 | addx 2 37 | addx 3 38 | addx -2 39 | addx 2 40 | addx 7 41 | noop 42 | noop 43 | addx 9 44 | noop 45 | addx -12 46 | noop 47 | addx 11 48 | addx -38 49 | noop 50 | noop 51 | noop 52 | addx 5 53 | addx 5 54 | noop 55 | noop 56 | noop 57 | addx 3 58 | addx -12 59 | addx 14 60 | noop 61 | addx 1 62 | addx 3 63 | addx 1 64 | addx 5 65 | addx 4 66 | addx 1 67 | noop 68 | noop 69 | noop 70 | noop 71 | noop 72 | addx -9 73 | addx 17 74 | addx -39 75 | addx 38 76 | addx -8 77 | addx -26 78 | addx 3 79 | addx 4 80 | addx 16 81 | noop 82 | addx -11 83 | addx 3 84 | noop 85 | addx 2 86 | addx 3 87 | addx -2 88 | addx 2 89 | noop 90 | addx 13 91 | addx -8 92 | noop 93 | addx 7 94 | addx -5 95 | addx 8 96 | addx -40 97 | addx 16 98 | addx -9 99 | noop 100 | addx -7 101 | addx 8 102 | addx 2 103 | addx 7 104 | noop 105 | noop 106 | addx -15 107 | addx 16 108 | addx 2 109 | addx 5 110 | addx 2 111 | addx -20 112 | addx 12 113 | addx 11 114 | addx 8 115 | addx -1 116 | addx 3 117 | noop 118 | addx -39 119 | addx 2 120 | noop 121 | addx 5 122 | noop 123 | noop 124 | noop 125 | addx 4 126 | addx 1 127 | noop 128 | noop 129 | addx 2 130 | addx 5 131 | addx 2 132 | addx 1 133 | addx 4 134 | addx -1 135 | addx 2 136 | noop 137 | addx 2 138 | noop 139 | addx 8 140 | noop 141 | noop 142 | noop 143 | addx -10 144 | noop 145 | noop 146 | -------------------------------------------------------------------------------- /day-11/README.md: -------------------------------------------------------------------------------- 1 | ## Day 11: Monkey in the Middle 2 | 3 | As you finally start making your way upriver, you realize your pack is much lighter than you remember. Just then, one of the items from your pack goes flying overhead. Monkeys are playing [Keep Away](https://en.wikipedia.org/wiki/Keep_away) with your missing things! 4 | 5 | To get your stuff back, you need to be able to predict where the monkeys will throw your items. After some careful observation, you realize the monkeys operate based on _how worried you are about each item_. 6 | 7 | You take some notes (your puzzle input) on the items each monkey currently has, how worried you are about those items, and how the monkey makes decisions based on your worry level. For example: 8 | 9 | Monkey 0: 10 | Starting items: 79, 98 11 | Operation: new = old * 19 12 | Test: divisible by 23 13 | If true: throw to monkey 2 14 | If false: throw to monkey 3 15 | 16 | Monkey 1: 17 | Starting items: 54, 65, 75, 74 18 | Operation: new = old + 6 19 | Test: divisible by 19 20 | If true: throw to monkey 2 21 | If false: throw to monkey 0 22 | 23 | Monkey 2: 24 | Starting items: 79, 60, 97 25 | Operation: new = old * old 26 | Test: divisible by 13 27 | If true: throw to monkey 1 28 | If false: throw to monkey 3 29 | 30 | Monkey 3: 31 | Starting items: 74 32 | Operation: new = old + 3 33 | Test: divisible by 17 34 | If true: throw to monkey 0 35 | If false: throw to monkey 1 36 | 37 | Each monkey has several attributes: 38 | 39 | - `Starting items` lists your _worry level_ for each item the monkey is currently holding in the order they will be inspected. 40 | - `Operation` shows how your worry level changes as that monkey inspects an item. (An operation like `new = old * 5` means that your worry level after the monkey inspected the item is five times whatever your worry level was before inspection.) 41 | - `Test` shows how the monkey uses your worry level to decide where to throw an item next. 42 | - `If true` shows what happens with an item if the `Test` was true. 43 | - `If false` shows what happens with an item if the `Test` was false. 44 | 45 | After each monkey inspects an item but before it tests your worry level, your relief that the monkey's inspection didn't damage the item causes your worry level to be _divided by three_ and rounded down to the nearest integer. 46 | 47 | The monkeys take turns inspecting and throwing items. On a single monkey's _turn_, it inspects and throws all of the items it is holding one at a time and in the order listed. Monkey `0` goes first, then monkey `1`, and so on until each monkey has had one turn. The process of each monkey taking a single turn is called a _round_. 48 | 49 | When a monkey throws an item to another monkey, the item goes on the _end_ of the recipient monkey's list. A monkey that starts a round with no items could end up inspecting and throwing many items by the time its turn comes around. If a monkey is holding no items at the start of its turn, its turn ends. 50 | 51 | In the above example, the first round proceeds as follows: 52 | 53 | Monkey 0: 54 | Monkey inspects an item with a worry level of 79. 55 | Worry level is multiplied by 19 to 1501. 56 | Monkey gets bored with item. Worry level is divided by 3 to 500. 57 | Current worry level is not divisible by 23. 58 | Item with worry level 500 is thrown to monkey 3. 59 | Monkey inspects an item with a worry level of 98. 60 | Worry level is multiplied by 19 to 1862. 61 | Monkey gets bored with item. Worry level is divided by 3 to 620. 62 | Current worry level is not divisible by 23. 63 | Item with worry level 620 is thrown to monkey 3. 64 | Monkey 1: 65 | Monkey inspects an item with a worry level of 54. 66 | Worry level increases by 6 to 60. 67 | Monkey gets bored with item. Worry level is divided by 3 to 20. 68 | Current worry level is not divisible by 19. 69 | Item with worry level 20 is thrown to monkey 0. 70 | Monkey inspects an item with a worry level of 65. 71 | Worry level increases by 6 to 71. 72 | Monkey gets bored with item. Worry level is divided by 3 to 23. 73 | Current worry level is not divisible by 19. 74 | Item with worry level 23 is thrown to monkey 0. 75 | Monkey inspects an item with a worry level of 75. 76 | Worry level increases by 6 to 81. 77 | Monkey gets bored with item. Worry level is divided by 3 to 27. 78 | Current worry level is not divisible by 19. 79 | Item with worry level 27 is thrown to monkey 0. 80 | Monkey inspects an item with a worry level of 74. 81 | Worry level increases by 6 to 80. 82 | Monkey gets bored with item. Worry level is divided by 3 to 26. 83 | Current worry level is not divisible by 19. 84 | Item with worry level 26 is thrown to monkey 0. 85 | Monkey 2: 86 | Monkey inspects an item with a worry level of 79. 87 | Worry level is multiplied by itself to 6241. 88 | Monkey gets bored with item. Worry level is divided by 3 to 2080. 89 | Current worry level is divisible by 13. 90 | Item with worry level 2080 is thrown to monkey 1. 91 | Monkey inspects an item with a worry level of 60. 92 | Worry level is multiplied by itself to 3600. 93 | Monkey gets bored with item. Worry level is divided by 3 to 1200. 94 | Current worry level is not divisible by 13. 95 | Item with worry level 1200 is thrown to monkey 3. 96 | Monkey inspects an item with a worry level of 97. 97 | Worry level is multiplied by itself to 9409. 98 | Monkey gets bored with item. Worry level is divided by 3 to 3136. 99 | Current worry level is not divisible by 13. 100 | Item with worry level 3136 is thrown to monkey 3. 101 | Monkey 3: 102 | Monkey inspects an item with a worry level of 74. 103 | Worry level increases by 3 to 77. 104 | Monkey gets bored with item. Worry level is divided by 3 to 25. 105 | Current worry level is not divisible by 17. 106 | Item with worry level 25 is thrown to monkey 1. 107 | Monkey inspects an item with a worry level of 500. 108 | Worry level increases by 3 to 503. 109 | Monkey gets bored with item. Worry level is divided by 3 to 167. 110 | Current worry level is not divisible by 17. 111 | Item with worry level 167 is thrown to monkey 1. 112 | Monkey inspects an item with a worry level of 620. 113 | Worry level increases by 3 to 623. 114 | Monkey gets bored with item. Worry level is divided by 3 to 207. 115 | Current worry level is not divisible by 17. 116 | Item with worry level 207 is thrown to monkey 1. 117 | Monkey inspects an item with a worry level of 1200. 118 | Worry level increases by 3 to 1203. 119 | Monkey gets bored with item. Worry level is divided by 3 to 401. 120 | Current worry level is not divisible by 17. 121 | Item with worry level 401 is thrown to monkey 1. 122 | Monkey inspects an item with a worry level of 3136. 123 | Worry level increases by 3 to 3139. 124 | Monkey gets bored with item. Worry level is divided by 3 to 1046. 125 | Current worry level is not divisible by 17. 126 | Item with worry level 1046 is thrown to monkey 1. 127 | 128 | After round 1, the monkeys are holding items with these worry levels: 129 | 130 | Monkey 0: 20, 23, 27, 26 131 | Monkey 1: 2080, 25, 167, 207, 401, 1046 132 | Monkey 2: 133 | Monkey 3: 134 | 135 | Monkeys 2 and 3 aren't holding any items at the end of the round; they both inspected items during the round and threw them all before the round ended. 136 | 137 | This process continues for a few more rounds: 138 | 139 | After round 2, the monkeys are holding items with these worry levels: 140 | Monkey 0: 695, 10, 71, 135, 350 141 | Monkey 1: 43, 49, 58, 55, 362 142 | Monkey 2: 143 | Monkey 3: 144 | 145 | After round 3, the monkeys are holding items with these worry levels: 146 | Monkey 0: 16, 18, 21, 20, 122 147 | Monkey 1: 1468, 22, 150, 286, 739 148 | Monkey 2: 149 | Monkey 3: 150 | 151 | After round 4, the monkeys are holding items with these worry levels: 152 | Monkey 0: 491, 9, 52, 97, 248, 34 153 | Monkey 1: 39, 45, 43, 258 154 | Monkey 2: 155 | Monkey 3: 156 | 157 | After round 5, the monkeys are holding items with these worry levels: 158 | Monkey 0: 15, 17, 16, 88, 1037 159 | Monkey 1: 20, 110, 205, 524, 72 160 | Monkey 2: 161 | Monkey 3: 162 | 163 | After round 6, the monkeys are holding items with these worry levels: 164 | Monkey 0: 8, 70, 176, 26, 34 165 | Monkey 1: 481, 32, 36, 186, 2190 166 | Monkey 2: 167 | Monkey 3: 168 | 169 | After round 7, the monkeys are holding items with these worry levels: 170 | Monkey 0: 162, 12, 14, 64, 732, 17 171 | Monkey 1: 148, 372, 55, 72 172 | Monkey 2: 173 | Monkey 3: 174 | 175 | After round 8, the monkeys are holding items with these worry levels: 176 | Monkey 0: 51, 126, 20, 26, 136 177 | Monkey 1: 343, 26, 30, 1546, 36 178 | Monkey 2: 179 | Monkey 3: 180 | 181 | After round 9, the monkeys are holding items with these worry levels: 182 | Monkey 0: 116, 10, 12, 517, 14 183 | Monkey 1: 108, 267, 43, 55, 288 184 | Monkey 2: 185 | Monkey 3: 186 | 187 | After round 10, the monkeys are holding items with these worry levels: 188 | Monkey 0: 91, 16, 20, 98 189 | Monkey 1: 481, 245, 22, 26, 1092, 30 190 | Monkey 2: 191 | Monkey 3: 192 | 193 | ... 194 | 195 | After round 15, the monkeys are holding items with these worry levels: 196 | Monkey 0: 83, 44, 8, 184, 9, 20, 26, 102 197 | Monkey 1: 110, 36 198 | Monkey 2: 199 | Monkey 3: 200 | 201 | ... 202 | 203 | After round 20, the monkeys are holding items with these worry levels: 204 | Monkey 0: 10, 12, 14, 26, 34 205 | Monkey 1: 245, 93, 53, 199, 115 206 | Monkey 2: 207 | Monkey 3: 208 | 209 | Chasing all of the monkeys at once is impossible; you're going to have to focus on the _two most active_ monkeys if you want any hope of getting your stuff back. Count the _total number of times each monkey inspects items_ over 20 rounds: 210 | 211 | Monkey 0 inspected items 101 times. 212 | Monkey 1 inspected items 95 times. 213 | Monkey 2 inspected items 7 times. 214 | Monkey 3 inspected items 105 times. 215 | 216 | In this example, the two most active monkeys inspected items 101 and 105 times. The level of _monkey business_ in this situation can be found by multiplying these together: `10605`. 217 | 218 | Figure out which monkeys to chase by counting how many items they inspect over 20 rounds. **What is the level of monkey business after 20 rounds of stuff-slinging simian shenanigans?** 219 | 220 | ## Part Two 221 | 222 | You're worried you might not ever get your items back. So worried, in fact, that your relief that a monkey's inspection didn't damage an item _no longer causes your worry level to be divided by three_. 223 | 224 | Unfortunately, that relief was all that was keeping your worry levels from reaching _ridiculous levels_. You'll need to _find another way to keep your worry levels manageable_. 225 | 226 | At this rate, you might be putting up with these monkeys for a _very long time_ \- possibly _`10000` rounds_! 227 | 228 | With these new rules, you can still figure out the monkey business after 10000 rounds. Using the same example above: 229 | 230 | == After round 1 == 231 | Monkey 0 inspected items 2 times. 232 | Monkey 1 inspected items 4 times. 233 | Monkey 2 inspected items 3 times. 234 | Monkey 3 inspected items 6 times. 235 | 236 | == After round 20 == 237 | Monkey 0 inspected items 99 times. 238 | Monkey 1 inspected items 97 times. 239 | Monkey 2 inspected items 8 times. 240 | Monkey 3 inspected items 103 times. 241 | 242 | == After round 1000 == 243 | Monkey 0 inspected items 5204 times. 244 | Monkey 1 inspected items 4792 times. 245 | Monkey 2 inspected items 199 times. 246 | Monkey 3 inspected items 5192 times. 247 | 248 | == After round 2000 == 249 | Monkey 0 inspected items 10419 times. 250 | Monkey 1 inspected items 9577 times. 251 | Monkey 2 inspected items 392 times. 252 | Monkey 3 inspected items 10391 times. 253 | 254 | == After round 3000 == 255 | Monkey 0 inspected items 15638 times. 256 | Monkey 1 inspected items 14358 times. 257 | Monkey 2 inspected items 587 times. 258 | Monkey 3 inspected items 15593 times. 259 | 260 | == After round 4000 == 261 | Monkey 0 inspected items 20858 times. 262 | Monkey 1 inspected items 19138 times. 263 | Monkey 2 inspected items 780 times. 264 | Monkey 3 inspected items 20797 times. 265 | 266 | == After round 5000 == 267 | Monkey 0 inspected items 26075 times. 268 | Monkey 1 inspected items 23921 times. 269 | Monkey 2 inspected items 974 times. 270 | Monkey 3 inspected items 26000 times. 271 | 272 | == After round 6000 == 273 | Monkey 0 inspected items 31294 times. 274 | Monkey 1 inspected items 28702 times. 275 | Monkey 2 inspected items 1165 times. 276 | Monkey 3 inspected items 31204 times. 277 | 278 | == After round 7000 == 279 | Monkey 0 inspected items 36508 times. 280 | Monkey 1 inspected items 33488 times. 281 | Monkey 2 inspected items 1360 times. 282 | Monkey 3 inspected items 36400 times. 283 | 284 | == After round 8000 == 285 | Monkey 0 inspected items 41728 times. 286 | Monkey 1 inspected items 38268 times. 287 | Monkey 2 inspected items 1553 times. 288 | Monkey 3 inspected items 41606 times. 289 | 290 | == After round 9000 == 291 | Monkey 0 inspected items 46945 times. 292 | Monkey 1 inspected items 43051 times. 293 | Monkey 2 inspected items 1746 times. 294 | Monkey 3 inspected items 46807 times. 295 | 296 | == After round 10000 == 297 | Monkey 0 inspected items 52166 times. 298 | Monkey 1 inspected items 47830 times. 299 | Monkey 2 inspected items 1938 times. 300 | Monkey 3 inspected items 52013 times. 301 | 302 | After 10000 rounds, the two most active monkeys inspected items 52166 and 52013 times. Multiplying these together, the level of _monkey business_ in this situation is now `_2713310158_`. 303 | 304 | Worry levels are no longer divided by three after each item is inspected; you'll need to find another way to keep your worry levels manageable. Starting again from the initial state in your puzzle input, **what is the level of monkey business after 10000 rounds?** 305 | -------------------------------------------------------------------------------- /day-11/index.js: -------------------------------------------------------------------------------- 1 | import { getInput, getLCM, splitLines } from '../utils/index.js'; 2 | 3 | function parseInput(input) { 4 | const monkeys = input 5 | .trim() 6 | .split('\n\n') 7 | .map((data) => { 8 | const lines = splitLines(data); 9 | const regexNumber = /\d+/g; 10 | const regexOperation = 11 | /new = old (?[\*\+]) (?\d+|old)/; 12 | 13 | return { 14 | items: lines[1].match(regexNumber).map((n) => parseInt(n)), 15 | getWorryLevel(prev) { 16 | let { operator, operand } = lines[2].match(regexOperation).groups; 17 | operand = operand === 'old' ? prev : parseInt(operand); 18 | 19 | return operator === '*' ? prev * operand : prev + operand; 20 | }, 21 | divisibleBy: parseInt(lines[3].match(regexNumber)[0]), 22 | getNextMonkey(worryLevel) { 23 | const block = 24 | worryLevel % this.divisibleBy === 0 ? lines[4] : lines[5]; 25 | return block.match(regexNumber)[0]; 26 | }, 27 | inspectedItems: 0, 28 | }; 29 | }); 30 | 31 | return monkeys; 32 | } 33 | 34 | export function getMonkeyBusiness(input, rounds) { 35 | const monkeys = parseInput(input); 36 | const lcm = getLCM(monkeys.map((x) => x.divisibleBy)); 37 | 38 | for (let i = 0; i < rounds; i++) { 39 | for (let monkey of monkeys) { 40 | for (let item of monkey.items) { 41 | let worryLevel = monkey.getWorryLevel(item); 42 | worryLevel = 43 | rounds === 20 ? Math.floor(worryLevel / 3) : worryLevel % lcm; 44 | const nextMonkey = monkey.getNextMonkey(worryLevel); 45 | 46 | monkeys[nextMonkey].items.push(worryLevel); 47 | } 48 | monkey.inspectedItems += monkey.items.length; 49 | monkey.items = []; 50 | } 51 | } 52 | 53 | const inspectedItems = monkeys 54 | .map((monkey) => monkey.inspectedItems) 55 | .sort((a, b) => b - a); 56 | 57 | return inspectedItems[0] * inspectedItems[1]; 58 | } 59 | 60 | if (process.env.NODE_ENV !== 'test') { 61 | const input = getInput(import.meta.url); 62 | const answer1 = getMonkeyBusiness(input, 20); 63 | const answer2 = getMonkeyBusiness(input, 10_000); 64 | 65 | console.log(` 66 | #1 What is the level of monkey business after 20 rounds of 67 | stuff-slinging simian shenanigans? 68 | ${answer1} 69 | 70 | #2 what is the level of monkey business after 10000 rounds? 71 | ${answer2} 72 | `); 73 | } 74 | -------------------------------------------------------------------------------- /day-11/index.test.js: -------------------------------------------------------------------------------- 1 | import { getMonkeyBusiness } from './index.js'; 2 | 3 | let input = ` 4 | Monkey 0: 5 | Starting items: 79, 98 6 | Operation: new = old * 19 7 | Test: divisible by 23 8 | If true: throw to monkey 2 9 | If false: throw to monkey 3 10 | 11 | Monkey 1: 12 | Starting items: 54, 65, 75, 74 13 | Operation: new = old + 6 14 | Test: divisible by 19 15 | If true: throw to monkey 2 16 | If false: throw to monkey 0 17 | 18 | Monkey 2: 19 | Starting items: 79, 60, 97 20 | Operation: new = old * old 21 | Test: divisible by 13 22 | If true: throw to monkey 1 23 | If false: throw to monkey 3 24 | 25 | Monkey 3: 26 | Starting items: 74 27 | Operation: new = old + 3 28 | Test: divisible by 17 29 | If true: throw to monkey 0 30 | If false: throw to monkey 1 31 | `; 32 | 33 | describe('getMonkeyBusiness', () => { 34 | it('should return the level of monkey business after 20 rounds', () => { 35 | expect(getMonkeyBusiness(input, 20)).toEqual(10605); 36 | }); 37 | 38 | it('should return the level of monkey business after 10,000 rounds', () => { 39 | expect(getMonkeyBusiness(input, 10_000)).toEqual(2713310158); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /day-11/input.txt: -------------------------------------------------------------------------------- 1 | Monkey 0: 2 | Starting items: 64, 89, 65, 95 3 | Operation: new = old * 7 4 | Test: divisible by 3 5 | If true: throw to monkey 4 6 | If false: throw to monkey 1 7 | 8 | Monkey 1: 9 | Starting items: 76, 66, 74, 87, 70, 56, 51, 66 10 | Operation: new = old + 5 11 | Test: divisible by 13 12 | If true: throw to monkey 7 13 | If false: throw to monkey 3 14 | 15 | Monkey 2: 16 | Starting items: 91, 60, 63 17 | Operation: new = old * old 18 | Test: divisible by 2 19 | If true: throw to monkey 6 20 | If false: throw to monkey 5 21 | 22 | Monkey 3: 23 | Starting items: 92, 61, 79, 97, 79 24 | Operation: new = old + 6 25 | Test: divisible by 11 26 | If true: throw to monkey 2 27 | If false: throw to monkey 6 28 | 29 | Monkey 4: 30 | Starting items: 93, 54 31 | Operation: new = old * 11 32 | Test: divisible by 5 33 | If true: throw to monkey 1 34 | If false: throw to monkey 7 35 | 36 | Monkey 5: 37 | Starting items: 60, 79, 92, 69, 88, 82, 70 38 | Operation: new = old + 8 39 | Test: divisible by 17 40 | If true: throw to monkey 4 41 | If false: throw to monkey 0 42 | 43 | Monkey 6: 44 | Starting items: 64, 57, 73, 89, 55, 53 45 | Operation: new = old + 1 46 | Test: divisible by 19 47 | If true: throw to monkey 0 48 | If false: throw to monkey 5 49 | 50 | Monkey 7: 51 | Starting items: 62 52 | Operation: new = old + 4 53 | Test: divisible by 7 54 | If true: throw to monkey 3 55 | If false: throw to monkey 2 56 | -------------------------------------------------------------------------------- /day-13/README.md: -------------------------------------------------------------------------------- 1 | # Day 13: Distress Signal 2 | 3 | You climb the hill and again try contacting the Elves. However, you instead receive a signal you weren't expecting: a _distress signal_. 4 | 5 | Your handheld device must still not be working properly; the packets from the distress signal got decoded _out of order_. You'll need to re-order the list of received packets (your puzzle input) to decode the message. 6 | 7 | Your list consists of pairs of packets; pairs are separated by a blank line. You need to identify _how many pairs of packets are in the right order_. 8 | 9 | For example: 10 | 11 | [1,1,3,1,1] 12 | [1,1,5,1,1] 13 | 14 | [[1],[2,3,4]] 15 | [[1],4] 16 | 17 | [9] 18 | [[8,7,6]] 19 | 20 | [[4,4],4,4] 21 | [[4,4],4,4,4] 22 | 23 | [7,7,7,7] 24 | [7,7,7] 25 | 26 | [] 27 | [3] 28 | 29 | [[[]]] 30 | [[]] 31 | 32 | [1,[2,[3,[4,[5,6,7]]]],8,9] 33 | [1,[2,[3,[4,[5,6,0]]]],8,9] 34 | 35 | Packet data consists of lists and integers. Each list starts with `[`, ends with `]`, and contains zero or more comma-separated values (either integers or other lists). Each packet is always a list and appears on its own line. 36 | 37 | When comparing two values, the first value is called _left_ and the second value is called _right_. Then: 38 | 39 | - If _both values are integers_, the _lower integer_ should come first. If the left integer is lower than the right integer, the inputs are in the right order. If the left integer is higher than the right integer, the inputs are not in the right order. Otherwise, the inputs are the same integer; continue checking the next part of the input. 40 | - If _both values are lists_, compare the first value of each list, then the second value, and so on. If the left list runs out of items first, the inputs are in the right order. If the right list runs out of items first, the inputs are not in the right order. If the lists are the same length and no comparison makes a decision about the order, continue checking the next part of the input. 41 | - If _exactly one value is an integer_, convert the integer to a list which contains that integer as its only value, then retry the comparison. For example, if comparing `[0,0,0]` and `2`, convert the right value to `[2]` (a list containing `2`); the result is then found by instead comparing `[0,0,0]` and `[2]`. 42 | 43 | Using these rules, you can determine which of the pairs in the example are in the right order: 44 | 45 | == Pair 1 == 46 | - Compare [1,1,3,1,1] vs [1,1,5,1,1] 47 | - Compare 1 vs 1 48 | - Compare 1 vs 1 49 | - Compare 3 vs 5 50 | - Left side is smaller, so inputs are in the right order 51 | 52 | == Pair 2 == 53 | - Compare [[1],[2,3,4]] vs [[1],4] 54 | - Compare [1] vs [1] 55 | - Compare 1 vs 1 56 | - Compare [2,3,4] vs 4 57 | - Mixed types; convert right to [4] and retry comparison 58 | - Compare [2,3,4] vs [4] 59 | - Compare 2 vs 4 60 | - Left side is smaller, so inputs are in the right order 61 | 62 | == Pair 3 == 63 | - Compare [9] vs [[8,7,6]] 64 | - Compare 9 vs [8,7,6] 65 | - Mixed types; convert left to [9] and retry comparison 66 | - Compare [9] vs [8,7,6] 67 | - Compare 9 vs 8 68 | - Right side is smaller, so inputs are not in the right order 69 | 70 | == Pair 4 == 71 | - Compare [[4,4],4,4] vs [[4,4],4,4,4] 72 | - Compare [4,4] vs [4,4] 73 | - Compare 4 vs 4 74 | - Compare 4 vs 4 75 | - Compare 4 vs 4 76 | - Compare 4 vs 4 77 | - Left side ran out of items, so inputs are in the right order 78 | 79 | == Pair 5 == 80 | - Compare [7,7,7,7] vs [7,7,7] 81 | - Compare 7 vs 7 82 | - Compare 7 vs 7 83 | - Compare 7 vs 7 84 | - Right side ran out of items, so inputs are not in the right order 85 | 86 | == Pair 6 == 87 | - Compare [] vs [3] 88 | - Left side ran out of items, so inputs are in the right order 89 | 90 | == Pair 7 == 91 | - Compare [[[]]] vs [[]] 92 | - Compare [[]] vs [] 93 | - Right side ran out of items, so inputs are not in the right order 94 | 95 | == Pair 8 == 96 | - Compare [1,[2,[3,[4,[5,6,7]]]],8,9] vs [1,[2,[3,[4,[5,6,0]]]],8,9] 97 | - Compare 1 vs 1 98 | - Compare [2,[3,[4,[5,6,7]]]] vs [2,[3,[4,[5,6,0]]]] 99 | - Compare 2 vs 2 100 | - Compare [3,[4,[5,6,7]]] vs [3,[4,[5,6,0]]] 101 | - Compare 3 vs 3 102 | - Compare [4,[5,6,7]] vs [4,[5,6,0]] 103 | - Compare 4 vs 4 104 | - Compare [5,6,7] vs [5,6,0] 105 | - Compare 5 vs 5 106 | - Compare 6 vs 6 107 | - Compare 7 vs 0 108 | - Right side is smaller, so inputs are not in the right order 109 | 110 | What are the indices of the pairs that are already _in the right order_? (The first pair has index 1, the second pair has index 2, and so on.) In the above example, the pairs in the right order are 1, 2, 4, and 6; the sum of these indices is `13`. 111 | 112 | Determine which pairs of packets are already in the right order. **What is the sum of the indices of those pairs?** 113 | 114 | ## Part Two 115 | 116 | Now, you just need to put _all_ of the packets in the right order. Disregard the blank lines in your list of received packets. 117 | 118 | The distress signal protocol also requires that you include two additional _divider packets_: 119 | 120 | [[2]] 121 | [[6]] 122 | 123 | Using the same rules as before, organize all packets - the ones in your list of received packets as well as the two divider packets - into the correct order. 124 | 125 | For the example above, the result of putting the packets in the correct order is: 126 | 127 | [] 128 | [[]] 129 | [[[]]] 130 | [1,1,3,1,1] 131 | [1,1,5,1,1] 132 | [[1],[2,3,4]] 133 | [1,[2,[3,[4,[5,6,0]]]],8,9] 134 | [1,[2,[3,[4,[5,6,7]]]],8,9] 135 | [[1],4] 136 | [[2]] 137 | [3] 138 | [[4,4],4,4] 139 | [[4,4],4,4,4] 140 | [[6]] 141 | [7,7,7] 142 | [7,7,7,7] 143 | [[8,7,6]] 144 | [9] 145 | 146 | Afterward, locate the divider packets. To find the _decoder key_ for this distress signal, you need to determine the indices of the two divider packets and multiply them together. (The first packet is at index 1, the second packet is at index 2, and so on.) In this example, the divider packets are _10th_ and _14th_, and so the decoder key is `140`. 147 | 148 | Organize all of the packets into the correct order. **What is the decoder key for the distress signal?** 149 | -------------------------------------------------------------------------------- /day-13/index.js: -------------------------------------------------------------------------------- 1 | import { getInput } from '../utils/index.js'; 2 | 3 | function parseInput(input) { 4 | return input 5 | .trim() 6 | .split('\n\n') 7 | .map((block) => block.split('\n').map((line) => JSON.parse(line))); 8 | } 9 | 10 | const arrayify = (x) => (Array.isArray(x) ? x : [x]); 11 | const isNumber = (x) => typeof x === 'number'; 12 | 13 | function compareSides(left, right) { 14 | if (isNumber(left) && isNumber(right)) { 15 | return left === right ? 0 : left < right ? -1 : +1; 16 | } 17 | 18 | if (isNumber(left) || isNumber(right)) { 19 | return compareSides(arrayify(left), arrayify(right)); 20 | } 21 | 22 | const min = Math.min(left.length, right.length); 23 | 24 | for (let i = 0; i < min; i++) { 25 | const result = compareSides(left[i], right[i]); 26 | 27 | if (result) return result; 28 | } 29 | 30 | return left.length - right.length; 31 | } 32 | 33 | function isInRightOrder(pair) { 34 | return compareSides(...pair) < 0; 35 | } 36 | 37 | export function getSumOfIndices(input) { 38 | return parseInput(input).reduce( 39 | (sum, pair, i) => (isInRightOrder(pair) ? sum + i + 1 : sum), 40 | 0, 41 | ); 42 | } 43 | 44 | export function getDecoderKey(input) { 45 | const dividerPackets = [[[2]], [[6]]]; 46 | const isDividerPacket = (packet) => 47 | dividerPackets 48 | .map((x) => JSON.stringify(x)) 49 | .includes(JSON.stringify(packet)); 50 | const packets = [...parseInput(input).flat(), ...dividerPackets].sort( 51 | compareSides, 52 | ); 53 | 54 | return packets.reduce( 55 | (product, packet, i) => 56 | isDividerPacket(packet) ? product * (i + 1) : product, 57 | 1, 58 | ); 59 | } 60 | 61 | if (process.env.NODE_ENV !== 'test') { 62 | const input = getInput(import.meta.url); 63 | const answer1 = getSumOfIndices(input); 64 | const answer2 = getDecoderKey(input); 65 | 66 | console.log(` 67 | #1 Determine which pairs of packets are already in the right order. 68 | What is the sum of the indices of those pairs? 69 | ${answer1} 70 | 71 | #2 What is the decoder key for the distress signal? 72 | ${answer2} 73 | `); 74 | } 75 | -------------------------------------------------------------------------------- /day-13/index.test.js: -------------------------------------------------------------------------------- 1 | import { getDecoderKey, getSumOfIndices } from './index.js'; 2 | 3 | const input = `[1,1,3,1,1] 4 | [1,1,5,1,1] 5 | 6 | [[1],[2,3,4]] 7 | [[1],4] 8 | 9 | [9] 10 | [[8,7,6]] 11 | 12 | [[4,4],4,4] 13 | [[4,4],4,4,4] 14 | 15 | [7,7,7,7] 16 | [7,7,7] 17 | 18 | [] 19 | [3] 20 | 21 | [[[]]] 22 | [[]] 23 | 24 | [1,[2,[3,[4,[5,6,7]]]],8,9] 25 | [1,[2,[3,[4,[5,6,0]]]],8,9] 26 | `; 27 | 28 | describe('getSumOfIndices', () => { 29 | it('should return the sum of the indices of the pairs already in the right order', () => { 30 | expect(getSumOfIndices(input)).toEqual(13); 31 | }); 32 | }); 33 | 34 | describe('getDecoderKey', () => { 35 | it('should return the decoder key for the distress signal', () => { 36 | expect(getDecoderKey(input)).toEqual(140); 37 | }); 38 | }); 39 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "advent-of-code-2022", 3 | "version": "0.1.0", 4 | "description": "", 5 | "main": "index.js", 6 | "type": "module", 7 | "scripts": { 8 | "start": "func() { node ./day-${1:-01}/index.js; }; func", 9 | "test": "cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest --verbose", 10 | "test:watch": "cross-env NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 jest --watch" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "git+https://github.com/zsoltime/advent-of-code-2022.git" 15 | }, 16 | "keywords": [], 17 | "author": "Zsolt Meszaros", 18 | "license": "MIT", 19 | "bugs": { 20 | "url": "https://github.com/zsoltime/advent-of-code-2022/issues" 21 | }, 22 | "homepage": "https://github.com/zsoltime/advent-of-code-2022#readme", 23 | "devDependencies": { 24 | "cross-env": "^7.0.3", 25 | "jest": "^29.3.1" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /utils/index.js: -------------------------------------------------------------------------------- 1 | import { readFileSync } from 'fs'; 2 | import { dirname, resolve } from 'path'; 3 | import { fileURLToPath } from 'url'; 4 | 5 | export function getInput(moduleUrl) { 6 | const __filename = fileURLToPath(moduleUrl); 7 | const __dirname = dirname(__filename); 8 | 9 | return readFileSync(resolve(__dirname, './input.txt'), { 10 | encoding: 'utf-8', 11 | }); 12 | } 13 | 14 | export function getLCM(divisors) { 15 | const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b)); 16 | let lcm = 1; 17 | 18 | for (const divisor of divisors) { 19 | lcm = (lcm * divisor) / gcd(lcm, divisor); 20 | } 21 | 22 | return lcm; 23 | } 24 | 25 | export function splitLines(input) { 26 | return input.trim().split('\n'); 27 | } 28 | 29 | export class Stack { 30 | constructor() { 31 | this.items = []; 32 | } 33 | 34 | push(item) { 35 | this.items.push(item); 36 | } 37 | 38 | pop() { 39 | if (!this.items.length) { 40 | return null; 41 | } 42 | return this.items.pop(); 43 | } 44 | 45 | peek() { 46 | if (!this.items.length) { 47 | return null; 48 | } 49 | return this.items[this.items.length - 1]; 50 | } 51 | 52 | isEmpty() { 53 | return this.items.length === 0; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /utils/index.test.js: -------------------------------------------------------------------------------- 1 | import { getLCM, splitLines, Stack } from './index.js'; 2 | 3 | describe('getLCM', () => { 4 | it('returns the expected LCM for two numbers', () => { 5 | expect(getLCM([2, 4])).toBe(4); 6 | }); 7 | 8 | it('returns the expected LCM for three or more numbers', () => { 9 | expect(getLCM([2, 4, 6])).toBe(12); 10 | }); 11 | 12 | it('returns 1 when given an empty array or an array of zeros', () => { 13 | expect(getLCM([])).toBe(1); 14 | }); 15 | 16 | it('returns the expected LCM for a large number of numbers', () => { 17 | expect(getLCM([2, 4, 6, 8, 10])).toBe(120); 18 | }); 19 | 20 | it('returns the expected LCM when given a mixture of positive and negative numbers, and zero', () => { 21 | expect(getLCM([2, -4, 6, 0, -8, 10])).toBe(0); 22 | }); 23 | 24 | it('returns the expected LCM when given an array of prime numbers', () => { 25 | expect(getLCM([2, 3, 5, 7, 11])).toBe(2310); 26 | }); 27 | 28 | it('returns the expected LCM when given an array of numbers that are all multiples of a common number', () => { 29 | expect(getLCM([6, 12, 18, 24, 30])).toBe(360); 30 | }); 31 | }); 32 | 33 | describe('splitLines', () => { 34 | it('should return an array of lines from the input', () => { 35 | const input = `line 1 36 | line 2 37 | line 3`; 38 | expect(splitLines(input)).toEqual(['line 1', 'line 2', 'line 3']); 39 | }); 40 | 41 | it('should remove leading and trailing empty lines', () => { 42 | const input = ` 43 | 44 | line 1 45 | 46 | line 3 47 | 48 | `; 49 | expect(splitLines(input)).toEqual(['line 1', '', 'line 3']); 50 | }); 51 | }); 52 | 53 | describe('Stack', () => { 54 | let stack; 55 | 56 | beforeEach(() => { 57 | stack = new Stack(); 58 | }); 59 | 60 | test('push()', () => { 61 | stack.push(1); 62 | expect(stack.items).toEqual([1]); 63 | 64 | stack.push(2); 65 | expect(stack.items).toEqual([1, 2]); 66 | }); 67 | 68 | test('pop()', () => { 69 | stack.push(1); 70 | stack.push(2); 71 | 72 | expect(stack.pop()).toEqual(2); 73 | expect(stack.items).toEqual([1]); 74 | 75 | expect(stack.pop()).toEqual(1); 76 | expect(stack.items).toEqual([]); 77 | 78 | expect(stack.pop()).toBeNull(); 79 | expect(stack.items).toEqual([]); 80 | }); 81 | 82 | test('peek()', () => { 83 | stack.push(1); 84 | stack.push(2); 85 | 86 | expect(stack.peek()).toEqual(2); 87 | expect(stack.items).toEqual([1, 2]); 88 | 89 | expect(stack.pop()).toEqual(2); 90 | expect(stack.items).toEqual([1]); 91 | }); 92 | 93 | test('isEmpty()', () => { 94 | expect(stack.isEmpty()).toBeTruthy(); 95 | 96 | stack.push(1); 97 | expect(stack.isEmpty()).toBeFalsy(); 98 | 99 | stack.pop(); 100 | expect(stack.isEmpty()).toBeTruthy(); 101 | }); 102 | }); 103 | --------------------------------------------------------------------------------