Skip to content

Commit 964eb43

Browse files
committed
[Algorithm Design and Techniques]
1 parent f876dda commit 964eb43

12 files changed

+401
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
function isSafe(maze, x, y) {
2+
const n = maze.length;
3+
// check if x and y are in limits and cell is not blocked
4+
if (x >= 0 && y >= 0 && x < n && y < n && maze[x][y] !== 0) {
5+
return true;
6+
}
7+
return false;
8+
}
9+
10+
function findPath(maze, x, y, solution) {
11+
const n = maze.length;
12+
// check if maze[x][y] is feasible to move
13+
if (x === n - 1 && y === n - 1) {
14+
// we have reached
15+
solution[x][y] = 1;
16+
return true;
17+
}
18+
// Check if maze[x][y] is valid
19+
if (isSafe(maze, x, y) === true) {
20+
// mark x,y as part of solution path
21+
solution[x][y] = 1;
22+
/* Move forward in x direction */
23+
if (findPath(maze, x + 1, y, solution)) {
24+
return true;
25+
}
26+
/* If moving in x direction doesn't give
27+
solution then Move down in y direction */
28+
if (findPath(maze, x, y + 1, solution)) {
29+
return true;
30+
}
31+
/* If none of the above movements work then
32+
BACKTRACK: unmark x,y as part of solution
33+
path */
34+
solution[x][y] = 0;
35+
return false;
36+
}
37+
return false;
38+
}
39+
40+
export function ratInAMaze(maze) {
41+
const solution = [];
42+
for (let i = 0; i < maze.length; i++) {
43+
solution[i] = [];
44+
for (let j = 0; j < maze[i].length; j++) {
45+
solution[i][j] = 0;
46+
}
47+
}
48+
if (findPath(maze, 0, 0, solution) === false) {
49+
return solution;
50+
}
51+
return 'NO PATH FOUND';
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
const UNASSIGNED = 0;
2+
3+
/* Returns a boolean which indicates whether any assigned entry
4+
in the specified row matches the given number. */
5+
function usedInRow(grid, row, num) {
6+
for (let col = 0; col < grid.length; col++) {
7+
if (grid[row][col] === num) {
8+
return true;
9+
}
10+
}
11+
return false;
12+
}
13+
/* Returns a boolean which indicates whether any assigned entry
14+
in the specified column matches the given number. */
15+
function usedInCol(grid, col, num) {
16+
for (let row = 0; row < grid.length; row++) {
17+
if (grid[row][col] === num) {
18+
return true;
19+
}
20+
}
21+
return false;
22+
}
23+
/* Returns a boolean which indicates whether any assigned entry
24+
within the specified 3x3 box matches the given number. */
25+
function usedInBox(grid, boxStartRow, boxStartCol, num) {
26+
for (let row = 0; row < 3; row++) {
27+
for (let col = 0; col < 3; col++) {
28+
if (grid[row + boxStartRow][col + boxStartCol] === num) {
29+
return true;
30+
}
31+
}
32+
}
33+
return false;
34+
}
35+
36+
function isSafe(grid, row, col, num) {
37+
/* Check if 'num' is not already placed in current row,
38+
current column and current 3x3 box */
39+
return (
40+
!usedInRow(grid, row, num) &&
41+
!usedInCol(grid, col, num) &&
42+
!usedInBox(grid, row - (row % 3), col - (col % 3), num)
43+
);
44+
}
45+
function solveSudoku(grid) {
46+
let row = 0;
47+
let col = 0;
48+
let checkBlankSpaces = false;
49+
// If there is no unassigned location, we are done
50+
for (row = 0; row < grid.length; row++) {
51+
for (col = 0; col < grid[row].length; col++) {
52+
if (grid[row][col] === UNASSIGNED) {
53+
checkBlankSpaces = true;
54+
break;
55+
}
56+
}
57+
if (checkBlankSpaces === true) {
58+
break;
59+
}
60+
}
61+
if (checkBlankSpaces === false) {
62+
return true;
63+
} // success!
64+
// consider digits 1 to 9
65+
for (let num = 1; num <= 9; num++) {
66+
// if looks promising
67+
if (isSafe(grid, row, col, num)) {
68+
// make tentative assignment
69+
grid[row][col] = num;
70+
// return, if success, yay!
71+
if (solveSudoku(grid)) {
72+
return true;
73+
}
74+
// failure, unmake & try again
75+
grid[row][col] = UNASSIGNED;
76+
}
77+
}
78+
return false;
79+
}
80+
81+
export function sudokuSolver(grid) {
82+
if (solveSudoku(grid) === true) {
83+
return grid;
84+
}
85+
return 'NO SOLUTION EXISTS!';
86+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export function knapSack(capacity, weights, values, n) {
2+
if (n === 0 || capacity === 0) {
3+
return 0;
4+
}
5+
if (weights[n - 1] > capacity) {
6+
return knapSack(capacity, weights, values, n - 1);
7+
}
8+
const a = values[n - 1] + knapSack(capacity - weights[n - 1], weights, values, n - 1);
9+
const b = knapSack(capacity, weights, values, n - 1);
10+
return a > b ? a : b;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
function findValues(n, capacity, kS) {
2+
let i = n;
3+
let k = capacity;
4+
// console.log('Items that are part of the solution:');
5+
while (i > 0 && k > 0) {
6+
if (kS[i][k] !== kS[i - 1][k]) {
7+
/* console.log(
8+
'item ' + i + ' can be part of solution w,v: ' + weights[i - 1] + ',' + values[i - 1]
9+
); */
10+
i--;
11+
k -= kS[i][k];
12+
} else {
13+
i--;
14+
}
15+
}
16+
}
17+
18+
export function knapSack(capacity, weights, values, n) {
19+
const kS = [];
20+
for (let i = 0; i <= n; i++) {
21+
kS[i] = [];
22+
}
23+
for (let i = 0; i <= n; i++) {
24+
for (let w = 0; w <= capacity; w++) {
25+
if (i === 0 || w === 0) {
26+
kS[i][w] = 0;
27+
} else if (weights[i - 1] <= w) {
28+
const a = values[i - 1] + kS[i - 1][w - weights[i - 1]];
29+
const b = kS[i - 1][w];
30+
kS[i][w] = a > b ? a : b; // max(a,b)
31+
// console.log(a + ' can be part of the solution');
32+
} else {
33+
kS[i][w] = kS[i - 1][w];
34+
}
35+
}
36+
// console.log(kS[i].join());
37+
}
38+
// extra algorithm to find the items that are part of the solution
39+
findValues(n, capacity, kS);
40+
return kS[n][capacity];
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
function printSolution(solution, wordX, m, n) {
2+
let a = m;
3+
let b = n;
4+
let x = solution[a][b];
5+
let answer = '';
6+
while (x !== '0') {
7+
if (solution[a][b] === 'diagonal') {
8+
answer = wordX[a - 1] + answer;
9+
a--;
10+
b--;
11+
} else if (solution[a][b] === 'left') {
12+
b--;
13+
} else if (solution[a][b] === 'top') {
14+
a--;
15+
}
16+
x = solution[a][b];
17+
}
18+
// console.log('lcs: ' + answer);
19+
}
20+
export function lcs(wordX, wordY) {
21+
const m = wordX.length;
22+
const n = wordY.length;
23+
const l = [];
24+
const solution = [];
25+
for (let i = 0; i <= m; i++) {
26+
l[i] = [];
27+
solution[i] = [];
28+
for (let j = 0; j <= n; j++) {
29+
l[i][j] = 0;
30+
solution[i][j] = '0';
31+
}
32+
}
33+
for (let i = 0; i <= m; i++) {
34+
for (let j = 0; j <= n; j++) {
35+
if (i === 0 || j === 0) {
36+
l[i][j] = 0;
37+
} else if (wordX[i - 1] === wordY[j - 1]) {
38+
l[i][j] = l[i - 1][j - 1] + 1;
39+
solution[i][j] = 'diagonal';
40+
} else {
41+
const a = l[i - 1][j];
42+
const b = l[i][j - 1];
43+
l[i][j] = a > b ? a : b; // max(a,b)
44+
solution[i][j] = l[i][j] === l[i - 1][j] ? 'top' : 'left';
45+
}
46+
}
47+
// console.log(l[i].join());
48+
// console.log(solution[i].join());
49+
}
50+
printSolution(solution, wordX, m, n);
51+
return l[m][n];
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export function lcs(wordX, wordY) {
2+
const m = wordX.length;
3+
const n = wordY.length;
4+
const l = [];
5+
for (let i = 0; i <= m; i++) {
6+
l[i] = [];
7+
for (let j = 0; j <= n; j++) {
8+
l[i][j] = 0;
9+
}
10+
}
11+
for (let i = 0; i <= m; i++) {
12+
for (let j = 0; j <= n; j++) {
13+
if (i === 0 || j === 0) {
14+
l[i][j] = 0;
15+
} else if (wordX[i - 1] === wordY[j - 1]) {
16+
l[i][j] = l[i - 1][j - 1] + 1;
17+
} else {
18+
const a = l[i - 1][j];
19+
const b = l[i][j - 1];
20+
l[i][j] = a > b ? a : b; // max(a,b)
21+
}
22+
}
23+
// console.log(l[i].join());
24+
}
25+
return l[m][n];
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
function printOptimalParenthesis(s, i, j) {
2+
if (i === j) {
3+
// console.log('A[' + i + ']');
4+
} else {
5+
// console.log('(');
6+
printOptimalParenthesis(s, i, s[i][j]);
7+
printOptimalParenthesis(s, s[i][j] + 1, j);
8+
// console.log(')');
9+
}
10+
}
11+
12+
export function matrixChainOrder(p) {
13+
const n = p.length;
14+
const m = [];
15+
const s = [];
16+
for (let i = 1; i <= n; i++) {
17+
m[i] = [];
18+
m[i][i] = 0;
19+
}
20+
for (let i = 0; i <= n; i++) {
21+
// to help printing the optimal solution
22+
s[i] = []; // auxiliary
23+
for (let j = 0; j <= n; j++) {
24+
s[i][j] = 0;
25+
}
26+
}
27+
for (let l = 2; l < n; l++) {
28+
for (let i = 1; i <= (n - l) + 1; i++) {
29+
const j = (i + l) - 1;
30+
m[i][j] = Number.MAX_SAFE_INTEGER;
31+
for (let k = i; k <= j - 1; k++) {
32+
// q = cost/scalar multiplications
33+
const q = m[i][k] + m[k + 1][j] + ((p[i - 1] * p[k]) * p[j]);
34+
if (q < m[i][j]) {
35+
m[i][j] = q;
36+
s[i][j] = k; // s[i,j] = Second auxiliary table that stores k
37+
}
38+
}
39+
}
40+
}
41+
// console.log(m);
42+
// console.log(s);
43+
printOptimalParenthesis(s, 1, n - 1);
44+
return m[1][n - 1];
45+
}
46+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
export function minCoinChange(coins, amount) {
2+
const cache = [];
3+
4+
const makeChange = (value) => {
5+
if (!value) {
6+
return [];
7+
}
8+
if (cache[value]) {
9+
return cache[value];
10+
}
11+
let min = [];
12+
let newMin;
13+
let newAmount;
14+
for (let i = 0; i < coins.length; i++) {
15+
const coin = coins[i];
16+
newAmount = value - coin;
17+
if (newAmount >= 0) {
18+
newMin = makeChange(newAmount);
19+
}
20+
if (
21+
newAmount >= 0 &&
22+
(newMin.length < min.length - 1 || !min.length) &&
23+
(newMin.length || !newAmount)
24+
) {
25+
min = [coin].concat(newMin);
26+
// console.log('new Min ' + min + ' for ' + amount);
27+
}
28+
}
29+
return (cache[value] = min);
30+
};
31+
return makeChange(amount);
32+
}

src/js/algorithms/greedy/knapsack.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
export function knapSack(capacity, weights, values) {
2+
const n = values.length;
3+
let load = 0;
4+
let val = 0;
5+
for (let i = 0; i < n && load < capacity; i++) {
6+
if (weights[i] <= capacity - load) {
7+
val += values[i];
8+
load += weights[i];
9+
// console.log('using item ' + (i + 1) + ' for the solution');
10+
} else {
11+
const r = (capacity - load) / weights[i];
12+
val += r * values[i];
13+
load += weights[i];
14+
// console.log('using ratio of ' + r + ' for item ' + (i + 1) + ' for the solution');
15+
}
16+
}
17+
return val;
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
export function lcs(wordX, wordY, m = wordX.length, n = wordY.length) {
2+
if (m === 0 || n === 0) {
3+
return 0;
4+
}
5+
if (wordX[m - 1] === wordY[n - 1]) {
6+
return 1 + lcs(wordX, wordY, m - 1, n - 1);
7+
}
8+
const a = lcs(wordX, wordY, m, n - 1);
9+
const b = lcs(wordX, wordY, m - 1, n);
10+
return a > b ? a : b;
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
export function matrixChainOrder(p, i = 1, j = p.length - 1) {
2+
if (i === j) {
3+
return 0;
4+
}
5+
let min = Number.MAX_SAFE_INTEGER;
6+
for (let k = i; k < j; k++) {
7+
const count =
8+
matrixChainOrder(p, i, k) + matrixChainOrder(p, k + 1, j) + ((p[i - 1] * p[k]) * p[j]);
9+
if (count < min) {
10+
min = count;
11+
}
12+
}
13+
return min;
14+
}

0 commit comments

Comments
 (0)