-
Notifications
You must be signed in to change notification settings - Fork 0
/
12-8_p1-2.js
125 lines (105 loc) · 3.56 KB
/
12-8_p1-2.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
// File: 12-8_p1-2.js
// Author: TryFailTryAgain
// Copyright (c) 2023. All rights reserved. For use in Open-Source projects this
// may be freely copied or excerpted with credit to the author.
// Advent of Code 2023 Day 8 Question 1-2
/* Data structure */
// Reads in the data from the text file
const fs = require('fs');
const inputData = fs.readFileSync('12-8.txt', 'utf8');
// Split the data into each section
let data = inputData.split('\n');
/* End Data structure */
/* Main */
solveP1(data);
solveP2(data);
/* End Main */
/* Functions */
function extractPath(data) {
//console.log(data[0]);
return data[0].split('');
}
function extractNodes(data) {
// Grabs just the nodes from the data
let map = {};
nodes = data.slice(2, data.length - 1);
nodes.forEach(line => {
if (line == '') return;
let key = line.match(/\w+/g)[0];
let left = line.match(/\w+/g)[1];
let right = line.match(/\w+/g)[2];
// Inserts the node into the map
addNode(map, key, left, right);
});
//console.log(map);
return map;
}
function addNode(map, key, left, right) {
// If the node doesn't exist, add it to the map
if (!map[key]) {
map[key] = {
left: left,
right: right
};
} else {
console.error('---Node already exists!---');
}
}
// Navigates the map we constructed using the directions provided by the path
function navigateMap(map, path, startNode, endSequence) {
let currentNode = startNode;
let pathIndex = 0;
// Create a regex based on endSequence
let endSequenceRegex;
if (endSequence.length < 3) {
endSequenceRegex = new RegExp('.'.repeat(3 - endSequence.length) + endSequence);
} else {
endSequenceRegex = new RegExp(endSequence);
}
// As long as the current node isn't the end node, keep going
while (!currentNode.match(endSequenceRegex)) {
// The current direction is the index we are on modulo the length of the path. This allows
// us to loop through the path repeatedly while keeping track of how many steps we've taken
let direction = path[pathIndex % path.length];
if (direction == 'L') {
currentNode = map[currentNode].left;
} else {
currentNode = map[currentNode].right;
}
pathIndex++;
}
//console.log(pathIndex);
return pathIndex;
}
// Finds the least common multiple of an array of numbers
function lcm(arr) {
function gcd(a, b) {
if (b === 0) return a;
return gcd(b, a % b);
}
let res = arr[0];
for (let i = 1; i < arr.length; i++) {
res = (res * arr[i]) / gcd(res, arr[i]);
}
//console.log(res);
return res;
}
function solveP1(data) {
// Builds a map object
const path = extractPath(data);
const fullMap = extractNodes(data);
const totalSteps = navigateMap(fullMap, path, 'AAA', 'ZZZ');
console.log('Total steps taken for Part 1: ' + totalSteps);
}
function solveP2() {
// Builds a map object
const path = extractPath(data);
const fullMap = extractNodes(data);
// Gets all the 'A' starting nodes
const startNodes = Object.keys(fullMap).filter(key => key.match(/..A/g));
// Finds each starting nodes steps to 'Z' individually and returns an array of those values
const stepsToEachZ = startNodes.map(node => navigateMap(fullMap, path, node, 'Z'));
// Finds the least common multiple of each number of steps to 'Z' from each starting node
console.log('Total steps taken for Part 2: ' + lcm(stepsToEachZ));
}
/* End Functions */