Skip to content

Commit 211c72d

Browse files
committed
Merge branch 'master' into dp-abbrev
2 parents 6da05a2 + cafb343 commit 211c72d

25 files changed

+625
-86
lines changed

.github/workflows/Ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ jobs:
2525
run: npm run test
2626

2727
- name: 💄 Code style
28-
run: npm run style
28+
run: npm run check-style
2929

3030
codespell:
3131
name: Check for spelling errors
Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,28 @@
1-
/*
2-
Problem: Given two numbers, n and k, make all unique combinations of k numbers from 1 to n and in sorted order
3-
4-
What is combinations?
5-
- Combinations is selecting items from a collections without considering the order of selection
6-
7-
Example:
8-
- We have an apple, a banana, and a jackfruit
9-
- We have three objects, and need to choose two items, then combinations will be
10-
11-
1. Apple & Banana
12-
2. Apple & Jackfruit
13-
3. Banana & Jackfruit
14-
15-
To read more about combinations, you can visit the following link:
16-
- https://betterexplained.com/articles/easy-permutations-and-combinations/
17-
18-
Solution:
19-
- We will be using backtracking to solve this questions
20-
- Take one element, and make all them combinations for k-1 elements
21-
- Once we get all combinations of that element, pop it and do same for next element
22-
*/
23-
24-
class Combinations {
25-
constructor(n, k) {
26-
this.n = n
27-
this.k = k
28-
this.current = [] // will be used for storing current combination
29-
this.combinations = []
30-
}
31-
32-
findCombinations(high = this.n, total = this.k, low = 1) {
33-
if (total === 0) {
34-
this.combinations.push([...this.current])
35-
return this.combinations
1+
function generateCombinations(n, k) {
2+
let currentCombination = []
3+
let allCombinations = [] // will be used for storing all combinations
4+
let currentValue = 1
5+
6+
function findCombinations() {
7+
if (currentCombination.length === k) {
8+
// Add the array of size k to the allCombinations array
9+
allCombinations.push([...currentCombination])
10+
return
3611
}
37-
for (let i = low; i <= high; i++) {
38-
this.current.push(i)
39-
this.findCombinations(high, total - 1, i + 1)
40-
this.current.pop()
12+
if (currentValue > n) {
13+
// Check for exceeding the range
14+
return
4115
}
42-
return this.combinations
16+
currentCombination.push(currentValue++)
17+
findCombinations()
18+
currentCombination.pop()
19+
findCombinations()
20+
currentValue--
4321
}
22+
23+
findCombinations()
24+
25+
return allCombinations
4426
}
4527

46-
export { Combinations }
28+
export { generateCombinations }

Backtracking/KnightTour.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
class OpenKnightTour {
44
constructor(size) {
5+
// Constructor to initialize the chessboard and size
56
this.board = new Array(size).fill(0).map(() => new Array(size).fill(0))
67
this.size = size
78
}
89

910
getMoves([i, j]) {
10-
// helper function to get the valid moves of the knight from the current position
11+
// Helper function to get the valid moves of the knight from the current position
1112
const moves = [
1213
[i + 2, j - 1],
1314
[i + 2, j + 1],
@@ -19,18 +20,19 @@ class OpenKnightTour {
1920
[i - 1, j + 2]
2021
]
2122

23+
// Filter out moves that are within the board boundaries
2224
return moves.filter(
2325
([y, x]) => y >= 0 && y < this.size && x >= 0 && x < this.size
2426
)
2527
}
2628

2729
isComplete() {
28-
// helper function to check if the board is complete
30+
// Helper function to check if the board is complete
2931
return !this.board.map((row) => row.includes(0)).includes(true)
3032
}
3133

3234
solve() {
33-
// function to find the solution for the given board
35+
// Function to find the solution for the given board
3436
for (let i = 0; i < this.size; i++) {
3537
for (let j = 0; j < this.size; j++) {
3638
if (this.solveHelper([i, j], 0)) return true
@@ -40,22 +42,23 @@ class OpenKnightTour {
4042
}
4143

4244
solveHelper([i, j], curr) {
43-
// helper function for the main computation
45+
// Helper function for the main computation
4446
if (this.isComplete()) return true
4547

48+
// Iterate through possible moves and attempt to fill the board
4649
for (const [y, x] of this.getMoves([i, j])) {
4750
if (this.board[y][x] === 0) {
4851
this.board[y][x] = curr + 1
4952
if (this.solveHelper([y, x], curr + 1)) return true
50-
// backtracking
53+
// Backtracking: If the solution is not found, reset the cell to 0
5154
this.board[y][x] = 0
5255
}
5356
}
5457
return false
5558
}
5659

5760
printBoard(output = (value) => console.log(value)) {
58-
// utility function to display the board
61+
// Utility function to display the board
5962
for (const row of this.board) {
6063
let string = ''
6164
for (const elem of row) {

Backtracking/MColoringProblem.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Colors a graph using up to m colors such that no two adjacent vertices share the same color.
3+
* @param {number[][]} graph - Adjacency matrix of the graph, using 0 for no edge.
4+
* @param {number} m - The number of colors to use.
5+
* @returns {?Array.<number>} A valid M-coloring of the graph using colors 1 to m, or null if none exists.
6+
* @see https://en.wikipedia.org/wiki/Graph_coloring
7+
*/
8+
function mColoring(graph, m) {
9+
const colors = new Array(graph.length).fill(0)
10+
11+
// Check if it's safe to color a vertex with a given color.
12+
function isSafe(vertex, color) {
13+
for (let i = 0; i < graph.length; i++) {
14+
if (graph[vertex][i] && colors[i] === color) {
15+
return false
16+
}
17+
}
18+
return true
19+
}
20+
21+
// Use backtracking to try and color the graph.
22+
function solveColoring(vertex = 0) {
23+
if (vertex === graph.length) {
24+
return true
25+
}
26+
27+
for (let color = 1; color <= m; color++) {
28+
if (isSafe(vertex, color)) {
29+
colors[vertex] = color
30+
31+
if (solveColoring(vertex + 1)) {
32+
return true
33+
}
34+
35+
// If no solution, backtrack.
36+
colors[vertex] = 0
37+
}
38+
}
39+
return false
40+
}
41+
42+
// If coloring is possible, return the colors.
43+
if (solveColoring()) {
44+
return colors
45+
}
46+
return null
47+
}
48+
49+
export { mColoring }

Backtracking/tests/AllCombinationsOfSizeK.test.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
import { Combinations } from '../AllCombinationsOfSizeK'
1+
import { generateCombinations } from '../AllCombinationsOfSizeK'
22

33
describe('AllCombinationsOfSizeK', () => {
44
it('should return 3x2 matrix solution for n = 3 and k = 2', () => {
5-
const test1 = new Combinations(3, 2)
6-
expect(test1.findCombinations()).toEqual([
5+
const res = generateCombinations(3, 2)
6+
expect(res).toEqual([
77
[1, 2],
88
[1, 3],
99
[2, 3]
1010
])
1111
})
1212

1313
it('should return 6x2 matrix solution for n = 4 and k = 2', () => {
14-
const test2 = new Combinations(4, 2)
15-
expect(test2.findCombinations()).toEqual([
14+
const res = generateCombinations(4, 2)
15+
expect(res).toEqual([
1616
[1, 2],
1717
[1, 3],
1818
[1, 4],
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { mColoring } from '../MColoringProblem'
2+
3+
describe('MColoringProblem', () => {
4+
it('should color a triangle with 3 colors', () => {
5+
const graph = [
6+
[0, 1, 1],
7+
[1, 0, 1],
8+
[1, 1, 0]
9+
]
10+
const solution = mColoring(graph, 3)
11+
expect(solution).not.toBeNull()
12+
})
13+
14+
it('should not color a triangle with 2 colors', () => {
15+
const graph = [
16+
[0, 1, 1],
17+
[1, 0, 1],
18+
[1, 1, 0]
19+
]
20+
const solution = mColoring(graph, 2)
21+
expect(solution).toBeNull()
22+
})
23+
})

Bit-Manipulation/BinaryCountSetBits.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ function BinaryCountSetBits(a) {
1616

1717
let count = 0
1818
while (a) {
19-
a &= (a - 1)
19+
a &= a - 1
2020
count++
2121
}
2222

Bit-Manipulation/GenerateSubSets.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* @function generateSubSets
3+
* @param {Array} inputArray
4+
* @returns {Array}
5+
* @example [1,2] -> [[],[1],[2],[1,2]]
6+
*/
7+
8+
// The time complexity of this algorithm is BigO(2^n) where n is the length of array
9+
function generateSubSets(inputArray) {
10+
if (!Array.isArray(inputArray)) {
11+
throw new Error('Provided input is not an array')
12+
}
13+
if (inputArray.length > 32) {
14+
throw new RangeError('Error size should be less than equal to 32')
15+
}
16+
let arrayLength = inputArray.length
17+
let subSets = []
18+
// loop till (2^n) - 1
19+
for (let i = 0; i < 1 << arrayLength; i++) {
20+
let subSet = []
21+
for (let j = 0; j < arrayLength; j++) {
22+
// 1 << j it shifts binary digit 1 by j positions and then we perform
23+
// and by AND operation we are checking whetheer jth bit
24+
// in i is set to 1 if result is non zero just add into set
25+
if (i & (1 << j)) {
26+
subSet.push(inputArray[j])
27+
}
28+
}
29+
subSets.push(subSet)
30+
}
31+
return subSets
32+
}
33+
34+
export { generateSubSets }
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { generateSubSets } from '../GenerateSubSets'
2+
3+
describe('subSets', () => {
4+
it('find the subsets', () => {
5+
expect(generateSubSets([1, 2, 3])).toEqual([
6+
[],
7+
[1],
8+
[2],
9+
[1, 2],
10+
[3],
11+
[1, 3],
12+
[2, 3],
13+
[1, 2, 3]
14+
])
15+
expect(generateSubSets([1, 2])).toEqual([[], [1], [2], [1, 2]])
16+
expect(generateSubSets([1, 2, 3])).toEqual([
17+
[],
18+
[1],
19+
[2],
20+
[1, 2],
21+
[3],
22+
[1, 3],
23+
[2, 3],
24+
[1, 2, 3]
25+
])
26+
expect(() => generateSubSets('invalid')).toThrow(
27+
'Provided input is not an array'
28+
)
29+
expect(() =>
30+
generateSubSets([
31+
1, 2, 2, 1, 2, 3, 4, 3, 2, 3, 4, 3, 2, 2, 2, 3, 12, 11, 4, 2, 2, 2, 2,
32+
1, 2, 3, 5, 6, 7, 7, 8, 6, 5, 6, 7, 8, 9, 8, 0, 6
33+
])
34+
).toThrow('Error size should be less than equal to 32')
35+
})
36+
})

DIRECTORY.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
* [generateParentheses](Backtracking/generateParentheses.js)
44
* [GeneratePermutations](Backtracking/GeneratePermutations.js)
55
* [KnightTour](Backtracking/KnightTour.js)
6+
* [MColoringProblem](Backtracking/MColoringProblem.js)
67
* [NQueens](Backtracking/NQueens.js)
78
* [RatInAMaze](Backtracking/RatInAMaze.js)
89
* [Sudoku](Backtracking/Sudoku.js)
910
* [SumOfSubset](Backtracking/SumOfSubset.js)
1011
* **Bit-Manipulation**
1112
* [BinaryCountSetBits](Bit-Manipulation/BinaryCountSetBits.js)
13+
* [GenerateSubSets](Bit-Manipulation/GenerateSubSets.js)
1214
* [GrayCodes](Bit-Manipulation/GrayCodes.js)
1315
* [IsPowerofFour](Bit-Manipulation/IsPowerofFour.js)
1416
* [IsPowerOfTwo](Bit-Manipulation/IsPowerOfTwo.js)
@@ -166,6 +168,7 @@
166168
* [Area](Maths/Area.js)
167169
* [ArithmeticGeometricMean](Maths/ArithmeticGeometricMean.js)
168170
* [ArmstrongNumber](Maths/ArmstrongNumber.js)
171+
* [AutomorphicNumber](Maths/AutomorphicNumber.js)
169172
* [AverageMean](Maths/AverageMean.js)
170173
* [AverageMedian](Maths/AverageMedian.js)
171174
* [BinaryConvert](Maths/BinaryConvert.js)
@@ -308,6 +311,7 @@
308311
* [LinearSearch](Search/LinearSearch.js)
309312
* [Minesweeper](Search/Minesweeper.js)
310313
* [QuickSelectSearch](Search/QuickSelectSearch.js)
314+
* [RabinKarp](Search/RabinKarp.js)
311315
* [SlidingWindow](Search/SlidingWindow.js)
312316
* [StringSearch](Search/StringSearch.js)
313317
* [TernarySearch](Search/TernarySearch.js)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy