Skip to content

Commit 56a3e34

Browse files
committed
day1-3: favor functional approach
1 parent b9a85aa commit 56a3e34

6 files changed

+229
-264
lines changed

day01/day-01-sonar-sweep.spec.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,17 @@
1-
import { DeeperMeasurementsCounter } from './day-01-sonar-sweep';
1+
import { countDeeperMeasurements, countSlidingWindowDeeperMeasurements } from './day-01-sonar-sweep';
22
import { depthReadings } from './day-01-sonar-sweep.input';
33

44
describe('Day 1 - Sonar Sweep', () => {
55
test('should return 0 for empty reading', () => {
6-
const measurer = new DeeperMeasurementsCounter([]);
7-
expect(measurer.countDeeperMeasurements()).toBe(0);
6+
expect(countDeeperMeasurements([])).toBe(0);
87
});
98
test('should return 0 for one reading', () => {
10-
const measurer = new DeeperMeasurementsCounter([200]);
11-
expect(measurer.countDeeperMeasurements()).toBe(0);
9+
expect(countDeeperMeasurements([200])).toBe(0);
1210
});
1311
test('should return 1466 for puzzle part 1', () => {
14-
const measurer = new DeeperMeasurementsCounter(depthReadings);
15-
expect(measurer.countDeeperMeasurements()).toBe(1466);
12+
expect(countDeeperMeasurements(depthReadings)).toBe(1466);
1613
});
1714
test('should return 1491 for puzzle part 2', () => {
18-
const measurer = new DeeperMeasurementsCounter(depthReadings);
19-
expect(measurer.countSlidingWindowDeeperMeasurements()).toBe(1491);
15+
expect(countSlidingWindowDeeperMeasurements(depthReadings)).toBe(1491);
2016
});
2117
});

day01/day-01-sonar-sweep.ts

Lines changed: 95 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,107 +1,99 @@
1-
export class DeeperMeasurementsCounter {
2-
private depthReadings: number[] = [];
3-
4-
constructor(depthReadings: number[]) {
5-
this.depthReadings = depthReadings;
6-
}
7-
8-
/* --- Day 1: Sonar Sweep ---
9-
https://adventofcode.com/2021/day/1
10-
11-
You're minding your own business on a ship at sea when the overboard alarm goes off! You rush to see if you can help. Apparently, one of the Elves tripped and accidentally sent the sleigh keys flying into the ocean!
12-
13-
Before you know it, you're inside a submarine the Elves keep ready for situations like this. It's covered in Christmas lights (because of course it is), and it even has an experimental antenna that should be able to track the keys if you can boost its signal strength high enough; there's a little meter that indicates the antenna's signal strength by displaying 0-50 stars.
14-
15-
Your instincts tell you that in order to save Christmas, you'll need to get all fifty stars by December 25th.
16-
17-
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!
18-
19-
As the submarine drops below the surface of the ocean, it automatically performs a sonar sweep of the nearby sea floor. On a small screen, the sonar sweep report (your puzzle input) appears: each line is a measurement of the sea floor depth as the sweep looks further and further away from the submarine.
20-
21-
For example, suppose you had the following report:
22-
23-
199
24-
200
25-
208
26-
210
27-
200
28-
207
29-
240
30-
269
31-
260
32-
263
33-
This report indicates that, scanning outward from the submarine, the sonar sweep found depths of 199, 200, 208, 210, and so on.
34-
35-
The first order of business is to figure out how quickly the depth increases, just so you know what you're dealing with - you never know if the keys will get carried into deeper water by an ocean current or a fish or something.
36-
37-
To do this, count the number of times a depth measurement increases from the previous measurement. (There is no measurement before the first measurement.) In the example above, the changes are as follows:
38-
39-
199 (N/A - no previous measurement)
40-
200 (increased)
41-
208 (increased)
42-
210 (increased)
43-
200 (decreased)
44-
207 (increased)
45-
240 (increased)
46-
269 (increased)
47-
260 (decreased)
48-
263 (increased)
49-
In this example, there are 7 measurements that are larger than the previous measurement.
50-
51-
How many measurements are larger than the previous measurement?
52-
*/
53-
countDeeperMeasurements(): number {
54-
let deeperMeasurements = 0;
55-
for (let i = 1; i < this.depthReadings.length; i++) {
56-
if (this.depthReadings[i] > this.depthReadings[i - 1]) {
57-
deeperMeasurements++;
58-
}
1+
/* --- Day 1: Sonar Sweep ---
2+
https://adventofcode.com/2021/day/1
3+
4+
You're minding your own business on a ship at sea when the overboard alarm goes off! You rush to see if you can help. Apparently, one of the Elves tripped and accidentally sent the sleigh keys flying into the ocean!
5+
6+
Before you know it, you're inside a submarine the Elves keep ready for situations like this. It's covered in Christmas lights (because of course it is), and it even has an experimental antenna that should be able to track the keys if you can boost its signal strength high enough; there's a little meter that indicates the antenna's signal strength by displaying 0-50 stars.
7+
8+
Your instincts tell you that in order to save Christmas, you'll need to get all fifty stars by December 25th.
9+
10+
Collect stars by solving puzzles. Two puzzles will be made available on each day in the Advent calendar; the second puzzle is unlocked when you complete the first. Each puzzle grants one star. Good luck!
11+
12+
As the submarine drops below the surface of the ocean, it automatically performs a sonar sweep of the nearby sea floor. On a small screen, the sonar sweep report (your puzzle input) appears: each line is a measurement of the sea floor depth as the sweep looks further and further away from the submarine.
13+
14+
For example, suppose you had the following report:
15+
16+
199
17+
200
18+
208
19+
210
20+
200
21+
207
22+
240
23+
269
24+
260
25+
263
26+
This report indicates that, scanning outward from the submarine, the sonar sweep found depths of 199, 200, 208, 210, and so on.
27+
28+
The first order of business is to figure out how quickly the depth increases, just so you know what you're dealing with - you never know if the keys will get carried into deeper water by an ocean current or a fish or something.
29+
30+
To do this, count the number of times a depth measurement increases from the previous measurement. (There is no measurement before the first measurement.) In the example above, the changes are as follows:
31+
32+
199 (N/A - no previous measurement)
33+
200 (increased)
34+
208 (increased)
35+
210 (increased)
36+
200 (decreased)
37+
207 (increased)
38+
240 (increased)
39+
269 (increased)
40+
260 (decreased)
41+
263 (increased)
42+
In this example, there are 7 measurements that are larger than the previous measurement.
43+
44+
How many measurements are larger than the previous measurement?
45+
*/
46+
export let countDeeperMeasurements = function (depthReadings: number[]): number {
47+
let deeperMeasurements = 0;
48+
for (let i = 1; i < depthReadings.length; i++) {
49+
if (depthReadings[i] > depthReadings[i - 1]) {
50+
deeperMeasurements++;
5951
}
60-
return deeperMeasurements;
6152
}
62-
63-
/*--- Part Two ---
64-
Considering every single measurement isn't as useful as you expected: there's just too much noise in the data.
65-
66-
Instead, consider sums of a three-measurement sliding window. Again considering the above example:
67-
68-
199 A
69-
200 A B
70-
208 A B C
71-
210 B C D
72-
200 E C D
73-
207 E F D
74-
240 E F G
75-
269 F G H
76-
260 G H
77-
263 H
78-
Start by comparing the first and second three-measurement windows. The measurements in the first window are marked A (199, 200, 208); their sum is 199 + 200 + 208 = 607. The second window is marked B (200, 208, 210); its sum is 618. The sum of measurements in the second window is larger than the sum of the first, so this first comparison increased.
79-
80-
Your goal now is to count the number of times the sum of measurements in this sliding window increases from the previous sum. So, compare A with B, then compare B with C, then C with D, and so on. Stop when there aren't enough measurements left to create a new three-measurement sum.
81-
82-
In the above example, the sum of each three-measurement window is as follows:
83-
84-
A: 607 (N/A - no previous sum)
85-
B: 618 (increased)
86-
C: 618 (no change)
87-
D: 617 (decreased)
88-
E: 647 (increased)
89-
F: 716 (increased)
90-
G: 769 (increased)
91-
H: 792 (increased)
92-
In this example, there are 5 sums that are larger than the previous sum.
93-
94-
Consider sums of a three-measurement sliding window. How many sums are larger than the previous sum?
95-
*/
96-
countSlidingWindowDeeperMeasurements(): number {
97-
let deeperMeasurements = 0;
98-
for (let i = 3; i < this.depthReadings.length; i++) {
99-
const window1Sum = this.depthReadings.slice(i - 3, i).reduce((sum, depth) => sum + depth, 0);
100-
const window2Sum = this.depthReadings.slice(i - 2, i + 1).reduce((sum, depth) => sum + depth, 0);
101-
if (window2Sum > window1Sum) {
102-
deeperMeasurements++;
103-
}
53+
return deeperMeasurements;
54+
};
55+
56+
/*--- Part Two ---
57+
Considering every single measurement isn't as useful as you expected: there's just too much noise in the data.
58+
59+
Instead, consider sums of a three-measurement sliding window. Again considering the above example:
60+
61+
199 A
62+
200 A B
63+
208 A B C
64+
210 B C D
65+
200 E C D
66+
207 E F D
67+
240 E F G
68+
269 F G H
69+
260 G H
70+
263 H
71+
Start by comparing the first and second three-measurement windows. The measurements in the first window are marked A (199, 200, 208); their sum is 199 + 200 + 208 = 607. The second window is marked B (200, 208, 210); its sum is 618. The sum of measurements in the second window is larger than the sum of the first, so this first comparison increased.
72+
73+
Your goal now is to count the number of times the sum of measurements in this sliding window increases from the previous sum. So, compare A with B, then compare B with C, then C with D, and so on. Stop when there aren't enough measurements left to create a new three-measurement sum.
74+
75+
In the above example, the sum of each three-measurement window is as follows:
76+
77+
A: 607 (N/A - no previous sum)
78+
B: 618 (increased)
79+
C: 618 (no change)
80+
D: 617 (decreased)
81+
E: 647 (increased)
82+
F: 716 (increased)
83+
G: 769 (increased)
84+
H: 792 (increased)
85+
In this example, there are 5 sums that are larger than the previous sum.
86+
87+
Consider sums of a three-measurement sliding window. How many sums are larger than the previous sum?
88+
*/
89+
export let countSlidingWindowDeeperMeasurements = function (depthReadings: number[]): number {
90+
let deeperMeasurements = 0;
91+
for (let i = 3; i < depthReadings.length; i++) {
92+
const window1Sum = depthReadings.slice(i - 3, i).reduce((sum, depth) => sum + depth, 0);
93+
const window2Sum = depthReadings.slice(i - 2, i + 1).reduce((sum, depth) => sum + depth, 0);
94+
if (window2Sum > window1Sum) {
95+
deeperMeasurements++;
10496
}
105-
return deeperMeasurements;
10697
}
107-
}
98+
return deeperMeasurements;
99+
};

day02/day-02-dive.spec.ts

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,22 @@
1-
import DiverCommandsInterpreter from './day-02-dive';
1+
import { computeOffsetFromCommands, computeOffsetFromCommandsWithAim } from './day-02-dive';
22
import { commands } from './day-02-dive.input';
33

44
describe('Day 2 - Dive', () => {
55
test('should throw Error for unknown commands', () => {
66
expect(() => {
7-
const measurer = new DiverCommandsInterpreter([['unknown', 1]]);
8-
measurer.computeOffsetFromCommands();
7+
computeOffsetFromCommands([['unknown', 1]]);
98
}).toThrowError();
109
});
1110
test('should return [0, 0] for no commands', () => {
12-
const measurer = new DiverCommandsInterpreter([]);
13-
expect(measurer.computeOffsetFromCommands()).toEqual([0, 0]);
11+
expect(computeOffsetFromCommands([])).toEqual([0, 0]);
1412
});
1513
test('should return 1488669 for puzzle part 1 answer', () => {
16-
const measurer = new DiverCommandsInterpreter(commands);
17-
const offsets = measurer.computeOffsetFromCommands();
14+
const offsets = computeOffsetFromCommands(commands);
1815
const answer = offsets[0] * offsets[1];
1916
expect(answer).toEqual(1488669);
2017
});
2118
test('should return 1176514794 for puzzle part 2 answer', () => {
22-
const measurer = new DiverCommandsInterpreter(commands);
23-
const offsets = measurer.computeOffsetFromCommandsWithAim();
19+
const offsets = computeOffsetFromCommandsWithAim(commands);
2420
const answer = offsets[0] * offsets[1];
2521
expect(answer).toEqual(1176514794);
2622
});

day02/day-02-dive.ts

Lines changed: 42 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,7 @@ export const enum Commands {
66
down = 'down',
77
}
88

9-
export default class DiverCommandsInterpreter {
10-
private commands: [string, number][] = [];
11-
12-
constructor(commands: [string, number][]) {
13-
this.commands = commands;
14-
}
15-
16-
/* --- Day 2: Dive! ---
9+
/* --- Day 2: Dive! ---
1710
https://adventofcode.com/2021/day/2
1811
1912
Now, you need to figure out how to pilot this thing.
@@ -45,29 +38,29 @@ export default class DiverCommandsInterpreter {
4538
4639
Calculate the horizontal position and depth you would have after following the planned course. What do you get if you multiply your final horizontal position by your final depth?
4740
*/
48-
computeOffsetFromCommands(): [offsetX: number, depth: number] {
49-
let offsetX = 0;
50-
let offsetY = 0;
51-
for (let i = 0; i < this.commands.length; i++) {
52-
switch (this.commands[i][0]) {
53-
case Commands.forward:
54-
offsetX += this.commands[i][1];
55-
break;
56-
case Commands.up:
57-
offsetY -= this.commands[i][1];
58-
break;
59-
case Commands.down:
60-
offsetY += this.commands[i][1];
61-
break;
62-
63-
default:
64-
throw UNNEXPECTED_COMMAND_ERROR;
65-
}
41+
export let computeOffsetFromCommands = function (commands: [string, number][]): [offsetX: number, depth: number] {
42+
let offsetX = 0;
43+
let offsetY = 0;
44+
for (let i = 0; i < commands.length; i++) {
45+
switch (commands[i][0]) {
46+
case Commands.forward:
47+
offsetX += commands[i][1];
48+
break;
49+
case Commands.up:
50+
offsetY -= commands[i][1];
51+
break;
52+
case Commands.down:
53+
offsetY += commands[i][1];
54+
break;
55+
56+
default:
57+
throw UNNEXPECTED_COMMAND_ERROR;
6658
}
67-
return [offsetX, offsetY];
6859
}
60+
return [offsetX, offsetY];
61+
};
6962

70-
/* --- Part Two ---
63+
/* --- Part Two ---
7164
Based on your calculations, the planned course doesn't seem to make any sense. You find the submarine manual and discover that the process is actually slightly more complicated.
7265
7366
In addition to horizontal position and depth, you'll also need to track a third value, aim, which also starts at 0. The commands also mean something entirely different than you first thought:
@@ -90,27 +83,26 @@ export default class DiverCommandsInterpreter {
9083
After following these new instructions, you would have a horizontal position of 15 and a depth of 60. (Multiplying these produces 900.)
9184
*/
9285

93-
computeOffsetFromCommandsWithAim(): [offsetX: number, depth: number] {
94-
let offsetX = 0;
95-
let offsetY = 0;
96-
let aim = 0;
97-
for (let i = 0; i < this.commands.length; i++) {
98-
switch (this.commands[i][0]) {
99-
case Commands.down:
100-
aim += this.commands[i][1];
101-
break;
102-
case Commands.up:
103-
aim -= this.commands[i][1];
104-
break;
105-
case Commands.forward:
106-
offsetX += this.commands[i][1];
107-
offsetY += aim * this.commands[i][1];
108-
break;
109-
110-
default:
111-
throw UNNEXPECTED_COMMAND_ERROR;
112-
}
86+
export let computeOffsetFromCommandsWithAim = function (commands: [string, number][]): [offsetX: number, depth: number] {
87+
let offsetX = 0;
88+
let offsetY = 0;
89+
let aim = 0;
90+
for (let i = 0; i < commands.length; i++) {
91+
switch (commands[i][0]) {
92+
case Commands.down:
93+
aim += commands[i][1];
94+
break;
95+
case Commands.up:
96+
aim -= commands[i][1];
97+
break;
98+
case Commands.forward:
99+
offsetX += commands[i][1];
100+
offsetY += aim * commands[i][1];
101+
break;
102+
103+
default:
104+
throw UNNEXPECTED_COMMAND_ERROR;
113105
}
114-
return [offsetX, offsetY];
115106
}
116-
}
107+
return [offsetX, offsetY];
108+
};

0 commit comments

Comments
 (0)