Skip to content

Commit d3ff2b0

Browse files
authored
Update merge (#1)
* chore: ignore .DS_Store in git (trekhleb#65) * Fix BST removal method. * Simplify combineWithoutRepetition algorithm. * add recursive solution to permutations with repetitions problem (trekhleb#52) * add recursive solution to permutations with repetitions problem * fix untested function, failing test * add comments * Add recursive way of generating permutations with repetitions. * Code style fixes. * Update javascript-algorithms-and-data-structures version. * fix unbound knapsack problem with items more than 1(default value) (trekhleb#73) * Code style fixes. * Correct a comment (trekhleb#66) * Fix LinkedList * Fix the prepend method for the LinkedList * Fix the remove method for the MinHeap * Correct a comment * Add algorithms complexity to README. * Update README. * Z algorithm implementation (trekhleb#77) * Implemented Z algorithm * Fixed bugs in implementation and added tests * Added README explaining z algorithm * Code style fixes. * Add comments. * Add comments. * Fix BST removal method (trekhleb#74) * Fix LinkedList * Fix the prepend method for the LinkedList * Fix the remove method for the MinHeap * Correct a comment * Fix BST removal method * Add setValue and nodeCopy methods to binary tree node. * Corrected explanations and included an example (trekhleb#75) * Update README for integer partition. * Added Complexity of Each Algorithm in Sorting/ directory. (trekhleb#76) * Added Complexity to Bubble Sort README.md * Added Complexity to Counting-Sort README.md * Italicized n in Bubble Sort README.md * Added Complexity to Heap Sort README.md * Added Complexity to Insertion Sort README.md * Added Complexity to Merge Sort README.md * Added Complexity to Quick Sort README.md * Added Complexity to Radix Sort README.md * Added Complexity to Selection Sort README.md * Added Complexity to SHell Sort README.md * Update READMEs. * Update READMEs. * Update READMEs. * Update READMEs. * Update READMEs. * Update READMEs. * Update READMEs. * Update READMEs. * Update READMEs. * Update READMEs. * Add Levenshtein Distance algorithm explanations. * Fix the findEdge method of the graph (trekhleb#80) * Fix LinkedList * Fix the prepend method for the LinkedList * Fix the remove method for the MinHeap * Correct a comment * Fix BST removal method * Fix the findEdge method of the graph * Code style fix. * Add regular expression matching algorithm. * Fix the value returned by DisjointSet union (trekhleb#81) * Fix LinkedList * Fix the prepend method for the LinkedList * Fix the remove method for the MinHeap * Correct a comment * Fix BST removal method * Fix the findEdge method of the graph * Fix the value returned by DisjointSet union * Add bit manipulation section. * Add more bit manipulation functions. * Add more bit manipulation functions. * Fix typo. * Simplify combineWithoutRepetitions function. * Simplify combineWithRepetitions function. * Add recursive factorial function (trekhleb#85) * Fix LinkedList * Fix the prepend method for the LinkedList * Fix the remove method for the MinHeap * Correct a comment * Fix BST removal method * Fix the findEdge method of the graph * Fix the value returned by DisjointSet union * Add recursive factorial function * Simplify permutateWithRepetitions algorithm.
1 parent ebfd527 commit d3ff2b0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1432
-447
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules
22
.idea
33
coverage
44
.vscode
5+
.DS_Store

README.md

Lines changed: 118 additions & 110 deletions
Large diffs are not rendered by default.

README.zh-CN.md

Lines changed: 90 additions & 90 deletions
Large diffs are not rendered by default.

README.zh-TW.md

Lines changed: 90 additions & 90 deletions
Large diffs are not rendered by default.

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/algorithms/math/bits/README.md

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Bit Manipulation
2+
3+
#### Get Bit
4+
5+
This method shifts `1` over by `bitPosition` bits, creating a
6+
value that looks like `00100`. Then we perform `AND` operation
7+
that clears all bits from the original number except the
8+
`bitPosition` one. Then we compare the result with zero. If
9+
result is zero that would mean that original number has `0` at
10+
position `bitPosition`.
11+
12+
> See `getBit` function for further details.
13+
14+
#### Set Bit
15+
16+
This method shifts `1` over by `bitPosition` bits, creating a
17+
value that looks like `00100`. Then we perform `OR` operation
18+
that sets specific bit into `1` but it does not affect on
19+
other bits of the number.
20+
21+
> See `setBit` function for further details.
22+
23+
#### Clear Bit
24+
25+
This method shifts `1` over by `bitPosition` bits, creating a
26+
value that looks like `00100`. Than it inverts this mask to get
27+
the number that looks like `11011`. Then `AND` operation is
28+
being applied to both the number and the mask. That operation
29+
unsets the bit.
30+
31+
> See `clearBit` function for further details.
32+
33+
#### Update Bit
34+
35+
This method is a combination of "Clear Bit" and "Set Bit" methods.
36+
37+
> See `updateBit` function for further details.
38+
39+
#### Multiply By Two
40+
41+
This method shifts original number by one bit to the left.
42+
Thus all binary number components (powers of two) are being
43+
multiplying by two and thus the number itself is being
44+
multiplied by two.
45+
46+
```
47+
Before the shift
48+
Number: 0b0101 = 5
49+
Powers of two: 0 + 2^2 + 0 + 2^0
50+
51+
After the shift
52+
Number: 0b1010 = 10
53+
Powers of two: 2^3 + 0 + 2^1 + 0
54+
```
55+
56+
> See `multiplyByTwo` function for further details.
57+
58+
#### Divide By Two
59+
60+
This method shifts original number by one bit to the right.
61+
Thus all binary number components (powers of two) are being
62+
divided by two and thus the number itself is being
63+
divided by two without remainder.
64+
65+
```
66+
Before the shift
67+
Number: 0b0101 = 5
68+
Powers of two: 0 + 2^2 + 0 + 2^0
69+
70+
After the shift
71+
Number: 0b0010 = 2
72+
Powers of two: 0 + 0 + 2^1 + 0
73+
```
74+
75+
> See `divideByTwo` function for further details.
76+
77+
#### Switch Sign
78+
79+
This method make positive numbers to be negative and backwards.
80+
To do so it uses "Twos Complement" approach which does it by
81+
inverting all of the bits of the number and adding 1 to it.
82+
83+
```
84+
1101 -3
85+
1110 -2
86+
1111 -1
87+
0000 0
88+
0001 1
89+
0010 2
90+
0011 3
91+
```
92+
93+
> See `switchSign` function for further details.
94+
95+
## References
96+
97+
- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
98+
- [Negative Numbers in binary on YouTube](https://www.youtube.com/watch?v=4qH4unVtJkE&t=0s&index=30&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
99+
- [Bit Hacks on stanford.edu](https://graphics.stanford.edu/~seander/bithacks.html)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import clearBit from '../clearBit';
2+
3+
describe('clearBit', () => {
4+
it('should clear bit at specific position', () => {
5+
// 1 = 0b0001
6+
expect(clearBit(1, 0)).toBe(0);
7+
expect(clearBit(1, 1)).toBe(1);
8+
expect(clearBit(1, 2)).toBe(1);
9+
10+
// 10 = 0b1010
11+
expect(clearBit(10, 0)).toBe(10);
12+
expect(clearBit(10, 1)).toBe(8);
13+
expect(clearBit(10, 3)).toBe(2);
14+
});
15+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import divideByTwo from '../divideByTwo';
2+
3+
describe('divideByTwo', () => {
4+
it('should divide numbers by two using bitwise operations', () => {
5+
expect(divideByTwo(0)).toBe(0);
6+
expect(divideByTwo(1)).toBe(0);
7+
expect(divideByTwo(3)).toBe(1);
8+
expect(divideByTwo(10)).toBe(5);
9+
expect(divideByTwo(17)).toBe(8);
10+
expect(divideByTwo(125)).toBe(62);
11+
});
12+
});
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import getBit from '../getBit';
2+
3+
describe('getBit', () => {
4+
it('should get bit at specific position', () => {
5+
// 1 = 0b0001
6+
expect(getBit(1, 0)).toBe(1);
7+
expect(getBit(1, 1)).toBe(0);
8+
9+
// 2 = 0b0010
10+
expect(getBit(2, 0)).toBe(0);
11+
expect(getBit(2, 1)).toBe(1);
12+
13+
// 3 = 0b0011
14+
expect(getBit(3, 0)).toBe(1);
15+
expect(getBit(3, 1)).toBe(1);
16+
17+
// 10 = 0b1010
18+
expect(getBit(10, 0)).toBe(0);
19+
expect(getBit(10, 1)).toBe(1);
20+
expect(getBit(10, 2)).toBe(0);
21+
expect(getBit(10, 3)).toBe(1);
22+
});
23+
});
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import multiplyByTwo from '../multiplyByTwo';
2+
3+
describe('multiplyByTwo', () => {
4+
it('should multiply numbers by two using bitwise operations', () => {
5+
expect(multiplyByTwo(0)).toBe(0);
6+
expect(multiplyByTwo(1)).toBe(2);
7+
expect(multiplyByTwo(3)).toBe(6);
8+
expect(multiplyByTwo(10)).toBe(20);
9+
expect(multiplyByTwo(17)).toBe(34);
10+
expect(multiplyByTwo(125)).toBe(250);
11+
});
12+
});
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import setBit from '../setBit';
2+
3+
describe('setBit', () => {
4+
it('should set bit at specific position', () => {
5+
// 1 = 0b0001
6+
expect(setBit(1, 0)).toBe(1);
7+
expect(setBit(1, 1)).toBe(3);
8+
expect(setBit(1, 2)).toBe(5);
9+
10+
// 10 = 0b1010
11+
expect(setBit(10, 0)).toBe(11);
12+
expect(setBit(10, 1)).toBe(10);
13+
expect(setBit(10, 2)).toBe(14);
14+
});
15+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import switchSign from '../switchSign';
2+
3+
describe('switchSign', () => {
4+
it('should switch the sign of the number using twos complement approach', () => {
5+
expect(switchSign(0)).toBe(0);
6+
expect(switchSign(1)).toBe(-1);
7+
expect(switchSign(-1)).toBe(1);
8+
expect(switchSign(32)).toBe(-32);
9+
expect(switchSign(-32)).toBe(32);
10+
expect(switchSign(23)).toBe(-23);
11+
expect(switchSign(-23)).toBe(23);
12+
});
13+
});
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import updateBit from '../updateBit';
2+
3+
describe('updateBit', () => {
4+
it('should update bit at specific position', () => {
5+
// 1 = 0b0001
6+
expect(updateBit(1, 0, 1)).toBe(1);
7+
expect(updateBit(1, 0, 0)).toBe(0);
8+
expect(updateBit(1, 1, 1)).toBe(3);
9+
expect(updateBit(1, 2, 1)).toBe(5);
10+
11+
// 10 = 0b1010
12+
expect(updateBit(10, 0, 1)).toBe(11);
13+
expect(updateBit(10, 0, 0)).toBe(10);
14+
expect(updateBit(10, 1, 1)).toBe(10);
15+
expect(updateBit(10, 1, 0)).toBe(8);
16+
expect(updateBit(10, 2, 1)).toBe(14);
17+
expect(updateBit(10, 2, 0)).toBe(10);
18+
});
19+
});

src/algorithms/math/bits/clearBit.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
/**
2+
* @param {number} number
3+
* @param {number} bitPosition - zero based.
4+
* @return {number}
5+
*/
6+
export default function clearBit(number, bitPosition) {
7+
const mask = ~(1 << bitPosition);
8+
9+
return number & mask;
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* @param {number} number
3+
* @return {number}
4+
*/
5+
export default function divideByTwo(number) {
6+
return number >> 1;
7+
}

src/algorithms/math/bits/getBit.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @param {number} number
3+
* @param {number} bitPosition - zero based.
4+
* @return {number}
5+
*/
6+
export default function getBit(number, bitPosition) {
7+
return (number & (1 << bitPosition)) === 0 ? 0 : 1;
8+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* @param {number} number
3+
* @return {number}
4+
*/
5+
export default function multiplyByTwo(number) {
6+
return number << 1;
7+
}

src/algorithms/math/bits/setBit.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* @param {number} number
3+
* @param {number} bitPosition - zero based.
4+
* @return {number}
5+
*/
6+
export default function setBit(number, bitPosition) {
7+
return number | (1 << bitPosition);
8+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Switch the sign of the number using "Twos Complement" approach.
3+
* @param {number} number
4+
* @return {number}
5+
*/
6+
export default function switchSign(number) {
7+
return ~number + 1;
8+
}

src/algorithms/math/bits/updateBit.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* @param {number} number
3+
* @param {number} bitPosition - zero based.
4+
* @param {number} bitValue - 0 or 1.
5+
* @return {number}
6+
*/
7+
export default function updateBit(number, bitPosition, bitValue) {
8+
// Normalized bit value.
9+
const bitValueNormalized = bitValue ? 1 : 0;
10+
11+
// Init clear mask.
12+
const clearMask = ~(1 << bitPosition);
13+
14+
// Clear bit value and then set it up to required value.
15+
return (number & clearMask) | (bitValueNormalized << bitPosition);
16+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import factorialRecursive from '../factorialRecursive';
2+
3+
describe('factorialRecursive', () => {
4+
it('should calculate factorial', () => {
5+
expect(factorialRecursive(0)).toBe(1);
6+
expect(factorialRecursive(1)).toBe(1);
7+
expect(factorialRecursive(5)).toBe(120);
8+
expect(factorialRecursive(8)).toBe(40320);
9+
expect(factorialRecursive(10)).toBe(3628800);
10+
});
11+
});
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* @param {number} number
3+
* @return {number}
4+
*/
5+
export default function factorialRecursive(number) {
6+
return number > 1 ? number * factorialRecursive(number - 1) : 1;
7+
}

src/algorithms/math/fibonacci/fibonacci.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default function fibonacci(n) {
1818

1919
while (iterationsCounter) {
2020
currentValue += previousValue;
21-
previousValue = (currentValue - previousValue);
21+
previousValue = currentValue - previousValue;
2222

2323
fibSequence.push(currentValue);
2424

src/algorithms/math/fibonacci/fibonacciNth.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default function fibonacciNth(n) {
1616

1717
while (iterationsCounter) {
1818
currentValue += previousValue;
19-
previousValue = (currentValue - previousValue);
19+
previousValue = currentValue - previousValue;
2020

2121
iterationsCounter -= 1;
2222
}

src/algorithms/math/integer-partition/integerPartition.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@ export default function integerPartition(number) {
1717
partitionMatrix[0][numberIndex] = 0;
1818
}
1919

20-
// Let's fill the first row. It represents the number of way of how we can form
21-
// number zero out of numbers 0, 1, 2, ... Obviously there is only one way we could
22-
// form number 0 and it is with number 0 itself.
20+
// Let's fill the first column. It represents the number of ways we can form
21+
// number zero out of numbers 0, 0 and 1, 0 and 1 and 2, 0 and 1 and 2 and 3, ...
22+
// Obviously there is only one way we could form number 0
23+
// and it is with number 0 itself.
2324
for (let summandIndex = 0; summandIndex <= number; summandIndex += 1) {
2425
partitionMatrix[summandIndex][0] = 1;
2526
}
@@ -33,9 +34,17 @@ export default function integerPartition(number) {
3334
// any new ways of forming the number. Thus we may just copy the number from row above.
3435
partitionMatrix[summandIndex][numberIndex] = partitionMatrix[summandIndex - 1][numberIndex];
3536
} else {
36-
// The number of combinations would equal to number of combinations of forming the same
37-
// number but WITHOUT current summand number plus number of combinations of forming the
38-
// previous number but WITH current summand.
37+
/*
38+
* The number of combinations would equal to number of combinations of forming the same
39+
* number but WITHOUT current summand number PLUS number of combinations of forming the
40+
* <current number - current summand> number but WITH current summand.
41+
*
42+
* Example:
43+
* Number of ways to form 5 using summands {0, 1, 2} would equal the SUM of:
44+
* - number of ways to form 5 using summands {0, 1} (we've excluded summand 2)
45+
* - number of ways to form 3 (because 5 - 2 = 3) using summands {0, 1, 2}
46+
* (we've included summand 2)
47+
*/
3948
const combosWithoutSummand = partitionMatrix[summandIndex - 1][numberIndex];
4049
const combosWithSummand = partitionMatrix[summandIndex][numberIndex - summandIndex];
4150

0 commit comments

Comments
 (0)