Inital attempt and Commit
This commit is contained in:
commit
b2c5dec784
5 changed files with 343 additions and 0 deletions
149
js/dialer.js
Normal file
149
js/dialer.js
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
export default {
|
||||
reachableKeys,
|
||||
countPaths,
|
||||
listAcyclicPaths
|
||||
};
|
||||
//-------------------//
|
||||
// Constants //
|
||||
//-------------------//
|
||||
|
||||
const reachableKeysMap = new Map([
|
||||
[0, [4, 6]], // From key 0, you can reach keys 4 and 6
|
||||
[1, [6, 8]], // From key 1, you can reach keys 6 and 8
|
||||
[2, [9, 7]], // From key 2, you can reach keys 9 and 7
|
||||
[3, [8, 4]], // From key 3, you can reach keys 8 and 4
|
||||
[4, [3, 9, 0]], // From key 4, you can reach keys 3, 9, and 0
|
||||
[6, [1, 7, 0]], // From key 6, you can reach keys 1, 7, and 0
|
||||
[7, [2, 6]], // From key 7, you can reach keys 2 and 6
|
||||
[8, [1, 3]], // From key 8, you can reach keys 1 and 3
|
||||
[9, [2, 4]], // From key 9, you can reach keys 2 and 4
|
||||
]);
|
||||
|
||||
|
||||
//-------------------//
|
||||
// Utility Functions //
|
||||
//-------------------//
|
||||
|
||||
//TODO: P:1 Combine cyclic/acyclic DFS :ODOT//
|
||||
|
||||
// Helper function to traverse nodes
|
||||
function traverseDFS(currentDigit, processNode, endCondition, visited = new Set(), path = []) {
|
||||
if (endCondition(currentDigit)) {
|
||||
return processNode();
|
||||
}
|
||||
|
||||
let count = 0;
|
||||
let reachable = reachableKeys(currentDigit);
|
||||
|
||||
for (let nextDigit of reachable) {
|
||||
if (visited.has(nextDigit)) continue;
|
||||
|
||||
// Mark the node as visited for acyclic paths
|
||||
if (visited !== null) visited.add(nextDigit);
|
||||
|
||||
// Add node to path for acyclic paths
|
||||
if (path !== null) path.push(nextDigit);
|
||||
|
||||
// Process node and/or count results
|
||||
count += traverseDFS(nextDigit, processNode, endCondition, visited, path);
|
||||
|
||||
// Backtrack for acyclic paths
|
||||
if (path !== null) path.pop();
|
||||
if (visited !== null) visited.delete(nextDigit);
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// Recursive DFS function for cyclic paths
|
||||
function cyclicDFS(currentDigit, remainingHops) {
|
||||
return traverseDFS(
|
||||
currentDigit,
|
||||
() => remainingHops === 0 ? 1 : 0,
|
||||
() => remainingHops === 0,
|
||||
null, // No visited nodes needed
|
||||
null // No path needed
|
||||
);
|
||||
}
|
||||
|
||||
// Recursive DFS function for acyclic paths
|
||||
function asyclicDFS(currentDigit, visited, path) {
|
||||
return traverseDFS(
|
||||
currentDigit,
|
||||
() => {
|
||||
if (path.length > 1) {
|
||||
allPaths.push([...path]);
|
||||
}
|
||||
return 0; // Count not needed for acyclic paths
|
||||
},
|
||||
() => false, // No end condition, continue until all paths are explored
|
||||
visited,
|
||||
path
|
||||
);
|
||||
}
|
||||
|
||||
// Quick Sort implementation to sort paths for acyclic path listing
|
||||
function quickSort(arr, compareFn) {
|
||||
if (arr.length <= 1) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
const pivot = arr[Math.floor(arr.length / 2)];
|
||||
const left = [];
|
||||
const right = [];
|
||||
const middle = [];
|
||||
|
||||
for (const element of arr) {
|
||||
if (compareFn(element, pivot) < 0) {
|
||||
left.push(element);
|
||||
} else if (compareFn(element, pivot) > 0) {
|
||||
right.push(element);
|
||||
} else {
|
||||
middle.push(element);
|
||||
}
|
||||
}
|
||||
|
||||
return [...quickSort(left, compareFn), ...middle, ...quickSort(right, compareFn)];
|
||||
}
|
||||
|
||||
// Comparator function to compare path lengths
|
||||
function comparePathLength(pathA, pathB) {
|
||||
return pathA.length - pathB.length;
|
||||
}
|
||||
|
||||
//-------------------//
|
||||
// Export Functions //
|
||||
//-------------------//
|
||||
|
||||
// Function to validate starting digit input and retrive the reachable values from the reachableKeysMap
|
||||
function reachableKeys(startingDigit) {
|
||||
//Check if startingDigit is an invalid digit or 5
|
||||
if (!reachableKeysMap.has(startingDigit)){
|
||||
return [];
|
||||
}
|
||||
//return the mapped values for startingDigit
|
||||
return reachableKeysMap.get(startingDigit);
|
||||
}
|
||||
|
||||
// Function to build a list of all acyclic paths
|
||||
function listAcyclicPaths(startingDigit) {
|
||||
// Handle invalid cases
|
||||
if (!reachableKeysMap.has(startingDigit)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
let allPaths = [];
|
||||
asyclicDFS(startingDigit, new Set(), []);
|
||||
|
||||
// Sort paths using Quick Sort based on their lengths
|
||||
return quickSort(allPaths, comparePathLength);
|
||||
}
|
||||
|
||||
// Function to count number of total paths given a startingDigit and a hopCount
|
||||
function countPaths(startingDigit, hopCount) {
|
||||
// Handle invalid cases
|
||||
if (!reachableKeysMap.has(startingDigit) || hopCount < 0) {
|
||||
return 0;
|
||||
}
|
||||
return cyclicDFS(startingDigit, hopCount);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue