Advent Of Code 2022
It’s that time of year again! and this time I’m going to have a right good go and completing the advent of code! I’m not promising I'll have it all done…but I’ll have a go.
I’m going to be doing these in TypeScript as I often forget the intricacies of this language and thought this would be a good way of remembering them.
All my code for this will be available here
Day 1
Ok, so going through all the usual elf story nonsense and extracting the good stuff! essentially the task is:
Given a list of numbers:
1000
2000
3000
4000
5000
6000
7000
8000
9000
10000
Each section of this list is separated by a new line, the task is to sum up all sections and output the highest value. So in this example:
- The first section is
1000
,2000
, and3000
, a total of6000
. - The second section is a total of
4000
. - The third section is
5000
and6000
, a total of11000
. - The fourth section is
7000
,8000
, and9000
, a total of24000
. - The fifth section is
10000
.
So the fourth sections total is the highest and that's the number we output. Easy.
Attempt for first star
First of all I tried with a fetch but I got the message “Puzzle inputs differ by user. Please log in to get your puzzle input.” ugh…fine.. so I just had to copy it all to a text file.
My thought process was to split the data where there is a new line followed by a new line. This would give me an array containing each section. Then I would split each section and convert to a Number
array using a map
, and then use reduce
to sum up each individual array. Finally I would add each of these results to a result array and using Math.max
get the highest value.
I know the inline functions are hard to read but this is just how it came out in my head. In production code I would refactor this.
import fs from "fs";
fs.readFile("input_day1.txt", "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
const results: number[] = [];
data.split("\n\n").forEach((group) => {
results.push(
group
.split("\n")
.map((str) => {
return Number(str);
})
.reduce((sum, current) => sum + current, 0)
);
});
console.log(Math.max(...results));
});
Attempt for second star
So the second part of this task is very much the same as the first, only difference is we want a total of the 3 highest values.
This is basically the same code but I’ve sorted the results into lowest→highest value and then using pop()
(which helpfully returns and removes the highest value from the array) I’ve summed up my three totals.
fs.readFile("input_day1.txt", "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
const results: number[] = [];
data.split("\n\n").forEach((group) => {
results.push(
group
.split("\n")
.map((str) => {
return Number(str);
})
.reduce((sum, current) => sum + current, 0)
);
});
const sorted = results.sort((n1, n2) => n1 - n2);
console.log(sorted.pop() + sorted.pop() + sorted.pop());
});
Boom! Day 1 done! Let’s see if i can keep this motivation going!
Day 2
Hello! so today the elves are playing Rock Paper Scissors… but apparently I have been given the outcomes by some evil elf or something…I dunno..
I have been given a file which looks like:
A Y
B X
C Z
My opponent will choose Rock paper scissors based on the letters in the first column:
A
for RockB
for PaperC
for Scissors
and I will choose mine based on the letters i the second column:
X
for RockY
for PaperZ
for Scissors
I need to get the total score from the file I’ve been given.
The 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).
So for the above file:
A Y
= (2 because I chose Paper + 6 because I won) 8B X
= (1 because chose Rock + 0 because I lost ) 1C Z
= (This is a draw because we both chose scissors, so 3 + 3) 6
Total = (8 + 1 + 6) 15
Simple.
Attempt for first star
My thinking here is work out how many different combinations there could be.
Then generate a score for each one of those combinations using the logic above. I can then put those in a switch and pass each line from the text file into the switch which will then append a score variable.
There are 9 different combinations:
A X
- (Score: 4)A Y
- (Score: 8)A Z
- (Score: 3)B X
- (Score: 1)B Y
- (Score: 5)B Z
- (Score: 9)C X
- (Score: 7)C Y
- (Score: 2)C Z
- (Score: 6)
Now its just a case of slapping all that together:
import fs from "fs";
let score = 0;
function generateScore(line: String) {
switch (line) {
case "A X":
score += 4;
break;
case "A Y":
score += 8;
break;
case "A Z":
score += 3;
break;
case "B X":
score += 1;
break;
case "B Y":
score += 5;
break;
case "B Z":
score += 9;
break;
case "C X":
score += 7;
break;
case "C Y":
score += 2;
break;
case "C Z":
score += 6;
break;
}
}
function day2Task() {
fs.readFile("resources/input_day2.txt", "utf8", (err, data) => {
if (err) {
console.error(err);
return;
}
const lines = data.split("\n");
lines.forEach((line) => {
generateScore(line);
});
console.log(score);
});
}
day2Task();
Attempt for second star
Ok so I was a bit too quick of the mark, turns out this evil elf forgot to tell me something, turns out the X Y Z
tell me how the match will end…not what hand I should play.
X
means I need to lose.
Y
means I need to end the round in a draw.
Z
means I need to win.
So this changes the scorings really.. I need to remember this part:
outcome of the round(0 if you lost, 3 if the round was a draw, and 6 if you won).
A Y
= (I need to draw, so because they used Rock (A), I also should use Rock(A). 3 + 1) 4B X
= (I need to lose, they chose Paper(B), so I should chose Rock(A). 1 + 0 ) 1C Z
= (I need to win, they chose Scissors(C), so I’ll chose Rock(A) 1 + 6) 7
Total = (4 + 1 + 7) 12
makes sense I guess..
All I need to do is change some of the score points in my switch statement. I don’t want to break my first attempt so instead I’m going to add in a task
parameter to my generateScore
function and use ternary operators to switch between the scores. If I pass a 1
in there it will work as it did before. If I pass a 2
in there it will use out new scoring system defined by the logic above:
function generateScore(task: number, line: String) {
switch (line) {
case "A X":
task === 1 ? (score += 4) : (score += 3);
break;
case "A Y":
task === 1 ? (score += 8) : (score += 4);
break;
case "A Z":
task === 1 ? (score += 3) : (score += 8);
break;
case "B X":
score += 1;
break;
case "B Y":
score += 5;
break;
case "B Z":
score += 9;
break;
case "C X":
task === 1 ? (score += 7) : (score += 2);
break;
case "C Y":
task === 1 ? (score += 2) : (score += 6);
break;
case "C Z":
task === 1 ? (score += 6) : (score += 7);
break;
}
}
Boom! another day done! 😄
Day 3
Back again! Today the elves are having some issues packing bags or something...
The basic goal here is, given an input such as:
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
Split each row in half, and then compare to two halves to find which letters they have in common.
- The first row is
vJrwpWtwJgWrhcsFMMfFFhFp
, its first half isvJrwpWtwJgWr
, and its second half ishcsFMMfFFhFp
. The only letter that appears in both strings is lowercasep
. - The second string when spilt is
jqHRNqRjqzjGDLGL
andrsFMfFZSrLrFZsSL
. The only letter that appears in both strings is uppercaseL
. - The third string split is
PmmdzqPrV
andvPwwTWBwg
; the only common letter is uppercaseP
. - The fourth string, when split, only shares the letter
v
. - The fifth string, when split, only shares the letter
t
. - The sixth string, when split, only shares the letter
s
.
Each of of these letters has a priority value that I need to add up at the end. The rules are:
- Lowercase item types
a
throughz
have priorities 1 through 26. - Uppercase item types
A
throughZ
have priorities 27 through 52.
so in the above example, the priority of the letter that appears in both parts of the strings are:
p
= 16L
= 38P
= 42v
= 22t
= 20s
= 19
the sum of these is 157
My first thought it how to get the right numerical value for the letter. To do that we can take a look at an ASCII table, specifically the part I'm showing below:
You can see here that a
= 97 so to get its position in the alphabet all I have to do is - 96
and for capital letters, all I need to do is something like:
if (c >= 65 && c <= 90) {
return c - 38;
}
sounds simple.. famous last words
Attempt for first star
I realized that my previous answers are not very TypeScripty.. so I’m leaning into TypeScript today.
So I need to half each row, find the shared letters and value them, then move onto the next.
const fs = require("fs");
const input = fs.readFileSync("resources/input_day3.txt", "utf8");
const row = input.split("\n") as string[];
function getHalves(items: string): [string, string] {
const length = items.length;
return [items.substring(0, length / 2), items.substring(length / 2)];
}
function getShared(first: string, second: string): string | null {
const lettersInFirst = new Set();
const lettersInSecond = new Set();
for (let i = 0; i < first.length; i++) {
if (first[i] === second[i]) {
return first[i];
}
lettersInFirst.add(first[i]);
lettersInSecond.add(second[i]);
if (lettersInSecond.has(first[i])) {
return first[i];
}
if (lettersInFirst.has(second[i])) {
return second[i];
}
}
return null;
}
function getValue(char: string): number {
const c = char.charCodeAt(0);
if (c >= 65 && c <= 90) {
return c - 38;
} else {
return c - 96;
}
}
const result = row.reduce((currentSum, rucksack) => {
const shared = getShared(...getHalves(rucksack));
if (!shared) {
return currentSum;
}
return currentSum + getValue(shared);
}, 0);
console.log(result);
I’ve made use of TypeScript much more in this one I think. And I’ve refactored it for readability.
The functions should be self explanatory really, getValue
is implementing the logic I described before so that should make sense.
Attempt for second star
Ok so now we have to group every three lines together and total up the priority of those three, then the next three etc etc, and then return a total.
so in our example above, this is one group:
vJrwpWtwJgWrhcsFMMfFFhFp
jqHRNqRjqzjGDLGLrsFMfFZSrLrFZsSL
PmmdzqPrVvPwwTWBwg
and this is another:
wMqvLMZHhHMvwLHjbvcjnnSBnvTQFn
ttgJtRGJQctTZtZT
CrZsJsPPZsGzwwsLwLmpwMDw
r
is the only letter that appears on each line in the first group
Z
is the only letter that appears on each line in the second group
r
= 18
Z
= 52
total = 70
I think here we just need to change the getShared
function to take a group of three rather than two. Not too difficult really. Lets delete the getHalves
function and instead just pass through the three strings, then we will do what we did before and loop over the number of characters to find the shared.
const fs = require("fs");
const input = fs.readFileSync("resources/input_day3.txt", "utf8");
const row = input.split("\n") as string[];
function getShared(one: string, two: string, three: string): string | null {
const first = new Set();
const second = new Set();
const third = new Set();
for (let i = 0; i < Math.max(one.length, two.length, three.length); i++) {
const letterInFirst = one[i];
const letterInSecond = two[i];
const letterInThird = three[i];
if (letterInFirst === letterInSecond && letterInSecond === letterInThird) {
return letterInFirst;
}
if (letterInFirst) first.add(letterInFirst);
if (letterInSecond) second.add(letterInSecond);
if (letterInThird) third.add(letterInThird);
if (second.has(letterInFirst) && third.has(letterInFirst)) {
return letterInFirst;
}
if (first.has(letterInSecond) && third.has(letterInSecond)) {
return letterInSecond;
}
if (first.has(letterInThird) && second.has(letterInThird)) {
return letterInThird;
}
return null;
}
function getValue(char: string): number {
const charCode = char.charCodeAt(0);
if (charCode >= 65 && charCode <= 90) {
return charCode - 38;
} else {
return charCode - 96;
}
}
let result = 0;
for (let i = 0; i < row.length; i += 3) {
const shared = getShared(row[i], row[i + 1], row[i + 2]);
if (!shared) {
continue;
}
result += getValue(shared);
}
console.log(result);
Yeah that did it. Apologies for the bad variable names, naming is hard.
Bring on Day 4!
Day 4
Day 4! its a Sunday today so I’m a bit later than usual but here goes.
So, the elves are cleaning.. and they have all be assigned areas to clean but for some reason some elves have ben given the same areas to clean as others.. so we have to identify that.
The data I’m given looks like:
2-4,6-8
2-3,4-5
5-7,7-9
2-8,3-7
6-6,4-6
2-6,4-8
Each row is a pair of elves and a range of numbers which show the assigned areas for that elves to clean.
- The first row, the first Elf was assigned sections
2-4
(sections2
,3
, and4
), while the second Elf was assigned sections6-8
(sections6
,7
,8
). - The second row shows no overlap at all, so thats fine.
- The third row shows each elf was assigned three sections: one got sections
5
,6
, and7
, while the other also got7
, plus8
and9
some of these rows we can see that one elves duties fully contains another's, for example
2-8,3-7
The second guy is cleaning an area the first guy has already cleaned. We need to identify those cases, so basically count how many of these there are.
Attempt for first star
So I’m using a Type
for this solution! Maybe an Interface
would be the more appropriate, I’m not sure it matters all that much though… The idea I have is to create a Pair Type
containing from
and to
to collected all my pairs. Then ill just compare the pairs against each other with ≥
and ≤
…seems quite simple..
import fs from "fs";
const input = fs.readFileSync("resources/input_day4.txt", "utf8");
const lines = input.split("\n") as string[];
type Pair = {
from: number;
to: number;
};
function createPairs(line: string): [Pair, Pair] {
const splitted = line.split(",");
const first = splitted[0].split("-");
const second = splitted[1].split("-");
const firstPair: Pair = { from: Number(first[0]), to: Number(first[1]) };
const secondPair: Pair = { from: Number(second[0]), to: Number(second[1]) };
return [firstPair, secondPair];
}
let sum1 = 0;
lines.forEach((line) => {
const [first, second] = createPairs(line);
if (first.from >= second.from && first.to <= second.to) {
sum1++;
} else if (second.from >= first.from && second.to <= first.to) {
sum1++;
}
});
console.log(sum1);
So this was quite easy really, although in my head it always seems like a lot more code…maybe its because I think in Java. 😄
Attempt for second star
For the second part I need to find pairs that overlap in any way, and count those, so thats simple enough. I think I’ll generate the missing numbers between for each Pair
and then just do an includes? yeah that sounds about right, I’ll give that a go.
import fs from "fs";
const input = fs.readFileSync("resources/input_day4.txt", "utf8");
const lines = input.split("\n") as string[];
type Pair = {
from: number;
to: number;
};
function createPairs(line: string): [Pair, Pair] {
const splitted = line.split(",");
const first = splitted[0].split("-");
const second = splitted[1].split("-");
const firstPair: Pair = { from: Number(first[0]), to: Number(first[1]) };
const secondPair: Pair = { from: Number(second[0]), to: Number(second[1]) };
return [firstPair, secondPair];
}
function generateMissingNumbers(start: number, end: number): number[] {
let numbers: number[] = [];
for (start; start <= end; start++) {
numbers.push(start);
}
return numbers;
}
let sum2 = 0;
lines.forEach((line) => {
const [first, second] = createPairs(line);
const firstNumbers = generateMissingNumbers(first.from, first.to);
const secondNumbers = generateMissingNumbers(second.from, second.to);
firstNumbers.every((num) => {
if (secondNumbers.includes(num)) {
sum2++;
return false;
}
return true;
});
});
console.log(sum2);
Yeah, so again quite simple. Good challenge for a Sunday though!
Day 5
Oooo it’s getting difficult now!
So this one is about moving crates. We have a crane that is capable of moving crates between stacks. All the crates are going to be moved about and I need to find out which crates are on the top of the piles.
Im given a starting drawing of how the crates currently look and some instructions of what to move where:
[D]
[N] [C]
[Z] [M] [P]
1 2 3
move 1 from 2 to 1
move 3 from 1 to 3
move 2 from 2 to 1
move 1 from 1 to 2
So the instructions here are saying I need to move 1 create from stack 2 to stack 1, I only have access to the top crates so thats moving create [D]
to the top of stack 1.
Then I need to move the 3 creates now on stack 1 ([Z]
,[N]
,[D]
) to stack three..also can only move one at a time so the end result would be:
[Z]
[N]
[C] [D]
[M] [P]
1 2 3
Then I need to move 2 creates from stack 2 to stack 1. So we end up with
[Z]
[N]
[M] [D]
[C] [P]
1 2 3
Then move 1 stack from stack 1 to stack 2:
[Z]
[N]
[D]
[C] [M] [P]
1 2 3
and the result were after is [C]
,[M]
,[Z]
Attempt for first star
This is a head scratcher… theres a lot to do. We need to parse the input into two sections, the crates and the instructions.. Then we need to put the stacks into arrays…I’m a visual learner and it helps me more if I turn the input on its side, so above would become:
1 [C]
2 [M]
3 [P][D][N][Z]
so if i build up the stacks into arrays like above I can then extract the numbers from the instructions and preform the logic
I think we need to use some regex to parse the instructions move X from X to X
then move 2 from 3 to 1
would result in extracting the top two from stack 3 [N][Z]
reversing them and putting them onto stack 1..
1 [C][N][Z]
2 [M]
3 [P][D]
Ok lets give this a go
import fs from "fs";
const input = fs.readFileSync("resources/input_day5.txt", "utf8");
function day5Task() {
const lines = input.split("\n");
const { crates, instructions } = parseInput(lines);
const stacks = buildStacks(crates);
doTheThing(instructions, stacks);
console.log(stacks.map((stack) => stack[0]).join(""));
}
function parseInput(lines: string[]) {
const crates = [];
const instructions = [];
for (let i = 0; i < lines.length; i++) {
if (lines[i] === "") {
continue;
}
if (lines[i].includes("[") || lines[i][0] === " ") {
crates.push(lines[i]);
} else if (lines[i].startsWith("move")) {
instructions.push(lines[i]);
}
}
return { crates, instructions };
}
function buildStacks(lines: string[]): string[][] {
const stacks = [];
const stackNumbers = lines[lines.length - 1];
const stackIndex = [];
for (let i = 0; i < stackNumbers.length; i++) {
if (stackNumbers[i] !== " ") {
stackIndex.push(i);
stacks.push([]);
}
}
for (let l = 0; l < lines.length - 1; l++) {
const line = lines[l];
for (let i = 0; i < stackIndex.length; i++) {
if (line[stackIndex[i]] !== " ") {
stacks[i].push(line[stackIndex[i]]);
}
}
}
return stacks;
}
function doTheThing(instructions: string[], stacks: string[][]): string[][] {
const reg = /move (\d+) from (\d+) to (\d+)/;
for (const instruction of instructions) {
const matches = reg.exec(instruction);
const move = parseInt(matches[1]);
const from = parseInt(matches[2]) - 1;
const to = parseInt(matches[3]) - 1;
for (let a = 0; a < move; a++) {
const crate = stacks[from].shift();
stacks[to].unshift(crate);
}
}
return stacks;
}
day5Task();
Ok that took more power then I’m happy to admit to.. few little gotchas in there but I did it! it's done! well…the first part is
Attempt for second star
Ok so it turns the crane is not a model 9000 but a 9001 which means it can pick up multiple crates at once…would have been nice to know this before 😄.
This basically means we don’t need to do the unshift
we did earlier in our well named doTheThing
function (I’m sorry, I’m so bad at naming..) and I think that might be it…
Yeah so this is the only change:
for (let a = 0; a < times; a++) {
const crate = stacks[from].shift();
if (task === 1) {
stacks[to].unshift(crate);
} else {
stacks[to].splice(a, 0, crate);
}
}
if we’re running task 1 use unshift and if not then a splice is all thats needed. Boom!
Day 5 done! (worried because they’re getting difficult now though..)
Day 6
Hello again, Day 6 is here and the elves are having some communication issues. I’ve been given a broken communication device that needs sorting..
I’ve been given a big datastream buffer that I need to parse. I need to find the start of a packet by identifying the first sequence of 4 unique characters in the datastream.
Attempt for first star
Sounds easy enough, I’m going to loop through each char in the data, then I’m going to to get the next 3 chars, add them all to a set and then check the length of the set. If the Set length is 3 then go again and start from the next char in the data.
Im not to happy with creating a new Set each time, but there is no add all option…I could use a filter on the array to check for unique values but I think this will be fine really…might refactor later
import { day6 } from "../../data";
const data = day6.split("");
for (let i = 0; i < data.length; i++) {
let results = new Set(data.slice(i, i + 4));
if (results.size === 4) {
console.log(i + 4);
break;
}
}
This was really simple, especially compared to yesterdays task…
Attempt for second star
now that we’ve identified the start of the package in the data, we now also need to find the start of the message marker. A start-of-message marker is just like a start-of-packet marker, except it consists of 14 distinct characters rather than 4.
so basically the same code as above but with 14 rather than 4 😄
import { day6 } from "../../data";
const data = day6.split("");
for (let i = 0; i < data.length; i++) {
let results = new Set(data.slice(i, i + 14));
if (results.size === 14) {
console.log(i + 14);
break;
}
}
wow, this was easy… its nice to have an easy one after yesterdays though.
See you tomorrow!
Day 7
I knew this one would be a hard one 😞
The communications device we were given yesterday requires a systems update…but we cant update the system because Error: No space left on device
you can see where this one is going…
I need to look through the device and find the total file size of each directory, then I need to find all the directories with a total size of at most 100000
and then calculate the sum of their total sizes.. 🤦🏻♂️
This is difficult (for me) to think about because I’m just thinking of crazy nested directories.. all gets a bit like inception in my head…
The example they give is an input which looks like this:
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k
These are the commands I’m running on my communication device (denoted with a $
, everything else is the result of the command). Using these commands we can see what the file system looks like:
- / (dir)
- a (dir)
- e (dir)
- i (file, size=584)
- f (file, size=29116)
- g (file, size=2557)
- h.lst (file, size=62596)
- b.txt (file, size=14848514)
- c.dat (file, size=8504156)
- d (dir)
- j (file, size=4060174)
- d.log (file, size=8033020)
- d.ext (file, size=5626152)
- k (file, size=7214296)
The answer for this input would be 95437
as directories a = 94853
and e = 584
everything else is over 100000
in size
I guess I should take it one step at a time.
Attempt for first star
I’m going to read the input, and choose an action depending of whether it starts with a $
, cd
, ls
or dir
.
if it’s $
then look for cd
or ls
and change the directory or get the files.
if it’s dir
then set a new current directory.
I’m going to use Types
again here for the file size and the directory.
and I think I’m probably going to use the reduce
function for the directory size..
The rest (i think) is just fiddly logic so thens get on with it!
import { day7 } from "../../data";
type File = {
size: number;
};
type Directory = {
parent: Directory | null;
subDirs: Map<string, Directory>;
files: Map<string, File>;
};
const sizes: number[] = [];
function changeDir(currDir: Directory, name: string): Directory {
if (name === "/") {
let dir = currDir;
while (dir.parent !== null) dir = dir.parent;
return dir;
} else if (name === "..") {
return currDir.parent!;
} else {
return currDir.subDirs.get(name)!;
}
}
function read() {
const root = { parent: null, subDirs: new Map(), files: new Map() };
let currDir: Directory = root;
const input = day7.split("\n");
input.forEach((line) => {
const parts = line.split(" ");
if (parts[0] === "$") {
if (parts[1] === "cd") {
currDir = changeDir(currDir, parts[2]);
}
} else {
if (parts[0] === "dir") {
const [_, name] = parts;
currDir.subDirs.set(name, {
parent: currDir,
subDirs: new Map(),
files: new Map(),
});
} else {
const [size, name] = parts;
currDir.files.set(name, { size: Number(size) });
}
}
});
return root;
}
function getSize(dir: Directory): number {
const dirsSize = Array.from(dir.subDirs.values()).reduce(
(size, dir) => size + getSize(dir),
0
);
const filesSize = Array.from(dir.files.values()).reduce(
(size, file) => size + file.size,
0
);
const totalSize = dirsSize + filesSize;
sizes.push(totalSize);
return totalSize;
}
// const root = read();
getSize(read());
const sumSmallDirs = sizes
.filter((s) => s <= 100000)
.reduce((sum, size) => sum + size, 0);
console.log(sumSmallDirs);
Ok I’m tired because its quite early in the morn ing while writing this, but that was quite irritating to write…maybe i should’t do these so early..
Attempt for second star
Part one was finding the files to delete, and this is the part where I actually do the deleting.
The total disk space available to me on the filesystem is 70000000
I need at least 30000000
**of unused space
In the first example the total space used was 48381165
which means the current unused space is 21618835
which isn’t quite enough for this system update we want to do… so i need to free up at least 8381165
worth of space.
So I have the following options:
- Delete directory
e
, which would increase unused space by584
. - Delete directory
a
, which would increase unused space by94853
. - Delete directory
d
, which would increase unused space by24933642
. - Delete directory
/
, which would increase unused space by48381165
.
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
.
So I need to find the smallest directory that, if deleted, would free up enough space on the filesystem to run the update.
I can just use a reduce
here again I think as I already have a sizes
array, first calculate how much space I need then use that to find the smallest directory that gives me enough room for the update:
const root = read();
const rootDirSize = getSize(root);
const neededSpace = 30000000 + rootDirSize - 70000000;
const smallest = sizes.reduce(
(smallest, size) => (size > neededSpace && size < smallest ? size : smallest),
rootDirSize
);
console.log(smallest);
Difficult! maybe I’m just grumpy because it’s very early… anyway see you tomorrow!