🍿 5 min. read

Advent of Code - Day 01 2022

Monica Powell

'Tis the season of Advent of Code which is an annual challenge of holiday-themed puzzles to solve with code. I usually attempt a few of the problems each year; the puzzles tend to get progressively more challenging each day and sometimes build on top of solutions from puzzles on earlier days. Each day you can earn up to ⭐️⭐️ (two stars) by solving both Part 1 and Part 2 (which adds a twist to part 1).

To keep things interesting, Advent of Code gives different users different values in their input files to test their solution. Once you feel that you've solved a problem you can run the function against the input file that AoC provided and then see if the output matches what AoC expected. They'll generally tell you if your answer is too high/too low to help nudge you in the right direction.

Helper Functions

I find that because Advent of Code gives large input files it's helpful to have helper functions to parse the input into your solution. Three of the helper functions I've used in previous years are

1// Splits the input into an array of strings
2export const strInput = (data) => data.split("\n");

This converts a file of

11
22
33
44

into an array of strings like ['1',2',3',4'].

1// Splits the input into an array of numbers
2export const numInput = (data) => data.split("\n").map(Number);

This converts a file of

11
22
33
44

into an array of numbers like [1,2,3,4].

Day One: Part One

For Day One: Part One of Advent of Code we are tasked with determining which elf is carrying the highest number of calories (check out the official AoC prompt for a more fun description of the problem) and the calories are provided as a list of integers in a text file and each group (a.k.a set of numbers with a blank space) belongs to a different elf.

1/*example input*/
21000
32000
43000
5
64000
7
85000
96000
10
117000
128000
139000
14
1510000

This list represents the Calories of the food carried by five Elves: The first Elf is carrying food with 1000, 2000, and 3000 Calories, a total of 6000 Calories. The second Elf is carrying one food item with 4000 Calories. The third Elf is carrying food with 5000 and 6000 Calories, a total of 11000 Calories. The fourth Elf is carrying food with 7000, 8000, and 9000 Calories, a total of 24000 Calories. The fifth Elf is carrying one food item with 10000 Calories. (Source: https://adventofcode.com/2022/day/1 )

Reading the data

Once we're ready to solve the problem we need access to our input data in a format that is easy to manipulate with JavaScript. We'll be using Node's File System API to read our locally downloaded input text file and will convert the file from a list of numbers to an an array of numbers with the help of the numInput() helper function.

1/* node boilerplate to access file system*/
2import { createRequire } from "module";
3const require = createRequire(import.meta.url);
4const fs = require("fs");
5
6/* import helper functions for parsing our text file into an array in order to use JavaScript array methods*/
7import * as h from "../helpers.js";
8
9function getHighestCalorieCount() {
10 /* use Node File System API to store output of local txt file in a string variable */
11 const data = fs.readFileSync("../2022/inputs/day_1.txt").toString();
12
13 /* convert our string input into an array with numerical data*/
14 const caloriesForElves = h.numInput(data);
15}

Finding Highest Number of Calories Carried by an Elf

We can find the Elf with the highest calories by iterating through the list of calories and keeping track of the current total for each elf. We'll know that we've finished counting the calories for an individual elf when the current calorie value is 0, as that is what the value the helper function converts the blank spaces for grouping in the original file to. If the current elf's total is higher than the highest total that we've seen then we should store that value in highestTotal where it will persist until we encounter a higher total. If the current elf's total is lower than the highest total when we're ready to move onto the next elf then we'll no longer track that total as we know that isn't the highest total number of calories.

1// part 1
2function getHighestCalorieCount() {
3
4 const data = fs.readFileSync("../2022/inputs/day_1.txt").toString();
5
6 const caloriesForElves = h.numInput(data);
7
8 let currentTotal = 0; // tracks total for current elf
9 let highestTotal = 0; // tracks highest total seen so far
10
11 for (let entry of caloriesForElves) {
12 /* when we reach a new elf's list of calories the value is == 0 and we should update the highestTotal seen so far if the current elf's total is higher than the highest total we've seen so far and then always reset the currentTotal to 0 before moving onto the next elf.*/
13 if (entry == 0) {
14 if (currentTotal > highestTotal) {
15 highestTotal = currentTotal;
16 }
17 currentTotal = 0;
18 }
19 /* increase currentTotal for the current elf */
20 currentTotal += entry;
21 }
22
23 /* return the highest value between the currentTotal and highestTotal. This is necessary in case the currentTotal in the last iteration is the highest, because the line to update the highestTotal is called before the next group that is iterated through and is last called before the second to last group. */
24 return Math.max(currentTotal, highestTotal)
25}

Day One: Part Two

Finding The Three Highest Number of Calories Carried by the Elves

Part two is a variation of Part One, and in my case required a different approach to storing the highest 3 totals vs. the approach I took for finding the 1 highest total. With this approach I decided to store the total for each elf in an array and then after iterating through all of the calorie values, sort the array from highest to lowest value and then return the sum of the 3 highest values. In the first solution, I opted to avoid an unnecessary sort but though sorting made the second problem easier to approach. However, I did carry over the logic of how the currentTotal is reset when encountering a new Elf (i.e., entry == 0)

1// part 2
2function getTopThreeHighestCalorieCounts() {
3
4 const data = fs.readFileSync("../2022/inputs/day_1.txt").toString();
5
6 const caloriesForElves = h.numInput(data);
7
8 let currentTotal = 0;
9 let totalsForEachElf = [] /* stores sum of calories for each elf */
10
11 for (let entry of caloriesForElves) {
12 if (entry == 0) {
13 totalsForEachElf.push(currentTotal)
14 currentTotal = 0;
15 }
16 currentTotal += entry;
17 }
18
19 // grab the first second and third value from the computed totals
20 const [first, second, third] = totalsForEachElf.sort((a, b) => b - a);
21
22 // reduce the array of first,second and third values to sum up their values; equivalent to first + second + third
23 return [first, second, third].reduce((acc, count) => {
24 return acc + count
25 }, 0)
26}

Full Source Code in my AoC GitHub Repository: https://github.com/M0nica/advent-of-code/blob/main/2022/day_1_calorie_counting.js

This article was published on December 04, 2022.


Don't be a stranger! 👋🏾

Thanks for reading "Advent of Code - Day 01 2022". Join my mailing list to be the first to receive my newest web development content, my thoughts on the web and learn about exclusive opportunities.

     

    I won’t send you spam. Unsubscribe at any time.