Skip to content

Commit aa6d530

Browse files
committed
[AOC2023][Typescript] Added solutions for Day 8.
1 parent 5bd293b commit aa6d530

File tree

5 files changed

+75
-1
lines changed

5 files changed

+75
-1
lines changed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
| [05 - If You Give A Seed A Fertilizer](https://adventofcode.com/2023/day/5) | [Day 05 TypeScript](/typescript/src/2023/day05.ts) |
2727
| [06 - Wait For It](https://adventofcode.com/2023/day/6) | [Day 06 TypeScript](/typescript/src/2023/day06.ts) |
2828
| [07 - Camel Cards](https://adventofcode.com/2023/day/7) | [Day 07 TypeScript](/typescript/src/2023/day07.ts) |
29+
| [08 - Haunted Wasteland](https://adventofcode.com/2023/day/8) | [Day 08 TypeScript](/typescript/src/2023/day08.ts) |
2930

3031
### AoC 2022
3132
| Day | Kotlin | TypeScript |

Diff for: typescript/src/2023/day08.ts

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import {AocDay, AocDayDecorator, SolutionParts} from "../aoc";
2+
import {Maths} from "../aoc/math";
3+
4+
@AocDayDecorator('2023', '8')
5+
export class Day08 extends AocDay {
6+
7+
solveImpl(): SolutionParts {
8+
type RLInstruction = "R" | "L"
9+
type Node = string;
10+
type DirectionEntry = Record<RLInstruction, Node>;
11+
12+
const [rightLeftInstructionsRow, directionsStr] = this.input.split("\n\n");
13+
14+
const rightLeftInstructions = rightLeftInstructionsRow.trim().split("") as RLInstruction[];
15+
const directionMap: Record<Node, DirectionEntry> = Object.fromEntries(directionsStr.split("\n").map(row => {
16+
const [start, endsPart] = row.split("=").map(p => p.trim());
17+
const [left, right] = endsPart.replaceAll(/[()]/g, "").split(",").map(p => p.trim());
18+
return [start, {'L': left, 'R': right}];
19+
}));
20+
21+
const traverseMap = (startNode: Node, isEndNodePredicate: (node: Node) => boolean): number => {
22+
let node = startNode;
23+
let turns = 0;
24+
do{
25+
node = directionMap[node][rightLeftInstructions[turns%rightLeftInstructions.length]];
26+
turns++;
27+
} while (!isEndNodePredicate(node));
28+
return turns;
29+
};
30+
31+
const part1 = () => traverseMap("AAA", (n) => n === "ZZZ");
32+
const part2 = () => Maths.Arithmetics.lcm(
33+
Object.keys(directionMap)
34+
.filter(node => node.endsWith("A"))
35+
.map(startNode => traverseMap(startNode, (n) => n.endsWith("Z")))
36+
);
37+
38+
return {
39+
part1: part1(),
40+
part2: part2()
41+
};
42+
}
43+
}

Diff for: typescript/src/2023/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ export * from './day03';
44
export * from './day04';
55
export * from './day05';
66
export * from './day06';
7-
export * from './day07';
7+
export * from './day07';
8+
export * from './day08';

Diff for: typescript/src/aoc/math/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./maths";
2+
export * from "./point";

Diff for: typescript/src/aoc/math/maths.ts

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export namespace Maths {
2+
export namespace Arithmetics {
3+
export function gcd(a: number, b: number): number {
4+
let aCopy = a;
5+
let bCopy = b;
6+
while (bCopy !== 0) {
7+
const temp = bCopy;
8+
bCopy = aCopy % bCopy;
9+
aCopy = temp;
10+
}
11+
return aCopy;
12+
}
13+
14+
export function lcm(numbers: number[]): number {
15+
if (numbers.length < 2) {
16+
throw new Error("At least two numbers are required to find the LCM.");
17+
}
18+
const lcmImpl = (a: number, b: number) => (a * b) / gcd(a, b);
19+
20+
let tempLcm = numbers[0];
21+
for (let i = 1; i < numbers.length; i++) {
22+
tempLcm = lcmImpl(tempLcm, numbers[i]);
23+
}
24+
return tempLcm;
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)