Skip to content

Update merge #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Jun 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
d57b725
chore: ignore .DS_Store in git (#65)
tiendq Jun 13, 2018
c3a9618
Fix BST removal method.
trekhleb Jun 13, 2018
8d3f83c
Simplify combineWithoutRepetition algorithm.
trekhleb Jun 13, 2018
b0c55ec
add recursive solution to permutations with repetitions problem (#52)
mmapplebeck Jun 13, 2018
19f4cc7
Add recursive way of generating permutations with repetitions.
trekhleb Jun 13, 2018
d154015
Code style fixes.
trekhleb Jun 14, 2018
6d413d8
Update javascript-algorithms-and-data-structures version.
trekhleb Jun 18, 2018
8c206a9
fix unbound knapsack problem with items more than 1(default value) (#73)
shsina Jun 18, 2018
98092ee
Code style fixes.
trekhleb Jun 18, 2018
9311735
Correct a comment (#66)
m-maksyutin Jun 18, 2018
87e59bf
Add algorithms complexity to README.
trekhleb Jun 18, 2018
d74234d
Update README.
trekhleb Jun 19, 2018
9e210ae
Z algorithm implementation (#77)
hariv Jun 21, 2018
5bdcbb3
Code style fixes.
trekhleb Jun 21, 2018
81d17bc
Add comments.
trekhleb Jun 21, 2018
e558231
Add comments.
trekhleb Jun 21, 2018
bd5a16b
Fix BST removal method (#74)
m-maksyutin Jun 22, 2018
2334583
Add setValue and nodeCopy methods to binary tree node.
trekhleb Jun 22, 2018
16b6ea5
Corrected explanations and included an example (#75)
Nnadozie Jun 22, 2018
831ce89
Update README for integer partition.
trekhleb Jun 22, 2018
e53f5f9
Added Complexity of Each Algorithm in Sorting/ directory. (#76)
mj-z-ali Jun 22, 2018
b65a992
Update READMEs.
trekhleb Jun 22, 2018
413c134
Update READMEs.
trekhleb Jun 22, 2018
110cc01
Update READMEs.
trekhleb Jun 22, 2018
3123cef
Update READMEs.
trekhleb Jun 22, 2018
5ac8bc9
Update READMEs.
trekhleb Jun 22, 2018
619c58e
Update READMEs.
trekhleb Jun 22, 2018
6b67ca7
Update READMEs.
trekhleb Jun 22, 2018
571d036
Update READMEs.
trekhleb Jun 22, 2018
42c7a15
Update READMEs.
trekhleb Jun 22, 2018
a950285
Update READMEs.
trekhleb Jun 23, 2018
89fb0e6
Add Levenshtein Distance algorithm explanations.
trekhleb Jun 23, 2018
88d038b
Fix the findEdge method of the graph (#80)
m-maksyutin Jun 25, 2018
c96bbdf
Code style fix.
trekhleb Jun 25, 2018
d69199e
Add regular expression matching algorithm.
trekhleb Jun 25, 2018
36e0bfe
Fix the value returned by DisjointSet union (#81)
m-maksyutin Jun 27, 2018
792f490
Add bit manipulation section.
trekhleb Jun 27, 2018
c268203
Add more bit manipulation functions.
trekhleb Jun 27, 2018
933848b
Add more bit manipulation functions.
trekhleb Jun 27, 2018
55ecc0b
Fix typo.
trekhleb Jun 27, 2018
e5a06e6
Simplify combineWithoutRepetitions function.
trekhleb Jun 28, 2018
65f08db
Simplify combineWithRepetitions function.
trekhleb Jun 28, 2018
c5ed81d
Add recursive factorial function (#85)
m-maksyutin Jun 28, 2018
db7ab9e
Simplify permutateWithRepetitions algorithm.
trekhleb Jun 28, 2018
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ node_modules
.idea
coverage
.vscode
.DS_Store
228 changes: 118 additions & 110 deletions README.md

Large diffs are not rendered by default.

180 changes: 90 additions & 90 deletions README.zh-CN.md

Large diffs are not rendered by default.

180 changes: 90 additions & 90 deletions README.zh-TW.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

99 changes: 99 additions & 0 deletions src/algorithms/math/bits/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Bit Manipulation

#### Get Bit

This method shifts `1` over by `bitPosition` bits, creating a
value that looks like `00100`. Then we perform `AND` operation
that clears all bits from the original number except the
`bitPosition` one. Then we compare the result with zero. If
result is zero that would mean that original number has `0` at
position `bitPosition`.

> See `getBit` function for further details.

#### Set Bit

This method shifts `1` over by `bitPosition` bits, creating a
value that looks like `00100`. Then we perform `OR` operation
that sets specific bit into `1` but it does not affect on
other bits of the number.

> See `setBit` function for further details.

#### Clear Bit

This method shifts `1` over by `bitPosition` bits, creating a
value that looks like `00100`. Than it inverts this mask to get
the number that looks like `11011`. Then `AND` operation is
being applied to both the number and the mask. That operation
unsets the bit.

> See `clearBit` function for further details.

#### Update Bit

This method is a combination of "Clear Bit" and "Set Bit" methods.

> See `updateBit` function for further details.

#### Multiply By Two

This method shifts original number by one bit to the left.
Thus all binary number components (powers of two) are being
multiplying by two and thus the number itself is being
multiplied by two.

```
Before the shift
Number: 0b0101 = 5
Powers of two: 0 + 2^2 + 0 + 2^0

After the shift
Number: 0b1010 = 10
Powers of two: 2^3 + 0 + 2^1 + 0
```

> See `multiplyByTwo` function for further details.

#### Divide By Two

This method shifts original number by one bit to the right.
Thus all binary number components (powers of two) are being
divided by two and thus the number itself is being
divided by two without remainder.

```
Before the shift
Number: 0b0101 = 5
Powers of two: 0 + 2^2 + 0 + 2^0

After the shift
Number: 0b0010 = 2
Powers of two: 0 + 0 + 2^1 + 0
```

> See `divideByTwo` function for further details.

#### Switch Sign

This method make positive numbers to be negative and backwards.
To do so it uses "Twos Complement" approach which does it by
inverting all of the bits of the number and adding 1 to it.

```
1101 -3
1110 -2
1111 -1
0000 0
0001 1
0010 2
0011 3
```

> See `switchSign` function for further details.

## References

- [Bit Manipulation on YouTube](https://www.youtube.com/watch?v=NLKQEOgBAnw&t=0s&index=28&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
- [Negative Numbers in binary on YouTube](https://www.youtube.com/watch?v=4qH4unVtJkE&t=0s&index=30&list=PLLXdhg_r2hKA7DPDsunoDZ-Z769jWn4R8)
- [Bit Hacks on stanford.edu](https://graphics.stanford.edu/~seander/bithacks.html)
15 changes: 15 additions & 0 deletions src/algorithms/math/bits/__test__/clearBit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import clearBit from '../clearBit';

describe('clearBit', () => {
it('should clear bit at specific position', () => {
// 1 = 0b0001
expect(clearBit(1, 0)).toBe(0);
expect(clearBit(1, 1)).toBe(1);
expect(clearBit(1, 2)).toBe(1);

// 10 = 0b1010
expect(clearBit(10, 0)).toBe(10);
expect(clearBit(10, 1)).toBe(8);
expect(clearBit(10, 3)).toBe(2);
});
});
12 changes: 12 additions & 0 deletions src/algorithms/math/bits/__test__/divideByTwo.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import divideByTwo from '../divideByTwo';

describe('divideByTwo', () => {
it('should divide numbers by two using bitwise operations', () => {
expect(divideByTwo(0)).toBe(0);
expect(divideByTwo(1)).toBe(0);
expect(divideByTwo(3)).toBe(1);
expect(divideByTwo(10)).toBe(5);
expect(divideByTwo(17)).toBe(8);
expect(divideByTwo(125)).toBe(62);
});
});
23 changes: 23 additions & 0 deletions src/algorithms/math/bits/__test__/getBit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import getBit from '../getBit';

describe('getBit', () => {
it('should get bit at specific position', () => {
// 1 = 0b0001
expect(getBit(1, 0)).toBe(1);
expect(getBit(1, 1)).toBe(0);

// 2 = 0b0010
expect(getBit(2, 0)).toBe(0);
expect(getBit(2, 1)).toBe(1);

// 3 = 0b0011
expect(getBit(3, 0)).toBe(1);
expect(getBit(3, 1)).toBe(1);

// 10 = 0b1010
expect(getBit(10, 0)).toBe(0);
expect(getBit(10, 1)).toBe(1);
expect(getBit(10, 2)).toBe(0);
expect(getBit(10, 3)).toBe(1);
});
});
12 changes: 12 additions & 0 deletions src/algorithms/math/bits/__test__/multiplyByTwo.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import multiplyByTwo from '../multiplyByTwo';

describe('multiplyByTwo', () => {
it('should multiply numbers by two using bitwise operations', () => {
expect(multiplyByTwo(0)).toBe(0);
expect(multiplyByTwo(1)).toBe(2);
expect(multiplyByTwo(3)).toBe(6);
expect(multiplyByTwo(10)).toBe(20);
expect(multiplyByTwo(17)).toBe(34);
expect(multiplyByTwo(125)).toBe(250);
});
});
15 changes: 15 additions & 0 deletions src/algorithms/math/bits/__test__/setBit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import setBit from '../setBit';

describe('setBit', () => {
it('should set bit at specific position', () => {
// 1 = 0b0001
expect(setBit(1, 0)).toBe(1);
expect(setBit(1, 1)).toBe(3);
expect(setBit(1, 2)).toBe(5);

// 10 = 0b1010
expect(setBit(10, 0)).toBe(11);
expect(setBit(10, 1)).toBe(10);
expect(setBit(10, 2)).toBe(14);
});
});
13 changes: 13 additions & 0 deletions src/algorithms/math/bits/__test__/switchSign.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import switchSign from '../switchSign';

describe('switchSign', () => {
it('should switch the sign of the number using twos complement approach', () => {
expect(switchSign(0)).toBe(0);
expect(switchSign(1)).toBe(-1);
expect(switchSign(-1)).toBe(1);
expect(switchSign(32)).toBe(-32);
expect(switchSign(-32)).toBe(32);
expect(switchSign(23)).toBe(-23);
expect(switchSign(-23)).toBe(23);
});
});
19 changes: 19 additions & 0 deletions src/algorithms/math/bits/__test__/updateBit.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import updateBit from '../updateBit';

describe('updateBit', () => {
it('should update bit at specific position', () => {
// 1 = 0b0001
expect(updateBit(1, 0, 1)).toBe(1);
expect(updateBit(1, 0, 0)).toBe(0);
expect(updateBit(1, 1, 1)).toBe(3);
expect(updateBit(1, 2, 1)).toBe(5);

// 10 = 0b1010
expect(updateBit(10, 0, 1)).toBe(11);
expect(updateBit(10, 0, 0)).toBe(10);
expect(updateBit(10, 1, 1)).toBe(10);
expect(updateBit(10, 1, 0)).toBe(8);
expect(updateBit(10, 2, 1)).toBe(14);
expect(updateBit(10, 2, 0)).toBe(10);
});
});
10 changes: 10 additions & 0 deletions src/algorithms/math/bits/clearBit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* @param {number} number
* @param {number} bitPosition - zero based.
* @return {number}
*/
export default function clearBit(number, bitPosition) {
const mask = ~(1 << bitPosition);

return number & mask;
}
7 changes: 7 additions & 0 deletions src/algorithms/math/bits/divideByTwo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @param {number} number
* @return {number}
*/
export default function divideByTwo(number) {
return number >> 1;
}
8 changes: 8 additions & 0 deletions src/algorithms/math/bits/getBit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* @param {number} number
* @param {number} bitPosition - zero based.
* @return {number}
*/
export default function getBit(number, bitPosition) {
return (number & (1 << bitPosition)) === 0 ? 0 : 1;
}
7 changes: 7 additions & 0 deletions src/algorithms/math/bits/multiplyByTwo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @param {number} number
* @return {number}
*/
export default function multiplyByTwo(number) {
return number << 1;
}
8 changes: 8 additions & 0 deletions src/algorithms/math/bits/setBit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* @param {number} number
* @param {number} bitPosition - zero based.
* @return {number}
*/
export default function setBit(number, bitPosition) {
return number | (1 << bitPosition);
}
8 changes: 8 additions & 0 deletions src/algorithms/math/bits/switchSign.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/**
* Switch the sign of the number using "Twos Complement" approach.
* @param {number} number
* @return {number}
*/
export default function switchSign(number) {
return ~number + 1;
}
16 changes: 16 additions & 0 deletions src/algorithms/math/bits/updateBit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @param {number} number
* @param {number} bitPosition - zero based.
* @param {number} bitValue - 0 or 1.
* @return {number}
*/
export default function updateBit(number, bitPosition, bitValue) {
// Normalized bit value.
const bitValueNormalized = bitValue ? 1 : 0;

// Init clear mask.
const clearMask = ~(1 << bitPosition);

// Clear bit value and then set it up to required value.
return (number & clearMask) | (bitValueNormalized << bitPosition);
}
11 changes: 11 additions & 0 deletions src/algorithms/math/factorial/__test__/factorialRecursive.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import factorialRecursive from '../factorialRecursive';

describe('factorialRecursive', () => {
it('should calculate factorial', () => {
expect(factorialRecursive(0)).toBe(1);
expect(factorialRecursive(1)).toBe(1);
expect(factorialRecursive(5)).toBe(120);
expect(factorialRecursive(8)).toBe(40320);
expect(factorialRecursive(10)).toBe(3628800);
});
});
7 changes: 7 additions & 0 deletions src/algorithms/math/factorial/factorialRecursive.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* @param {number} number
* @return {number}
*/
export default function factorialRecursive(number) {
return number > 1 ? number * factorialRecursive(number - 1) : 1;
}
2 changes: 1 addition & 1 deletion src/algorithms/math/fibonacci/fibonacci.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export default function fibonacci(n) {

while (iterationsCounter) {
currentValue += previousValue;
previousValue = (currentValue - previousValue);
previousValue = currentValue - previousValue;

fibSequence.push(currentValue);

Expand Down
2 changes: 1 addition & 1 deletion src/algorithms/math/fibonacci/fibonacciNth.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function fibonacciNth(n) {

while (iterationsCounter) {
currentValue += previousValue;
previousValue = (currentValue - previousValue);
previousValue = currentValue - previousValue;

iterationsCounter -= 1;
}
Expand Down
21 changes: 15 additions & 6 deletions src/algorithms/math/integer-partition/integerPartition.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ export default function integerPartition(number) {
partitionMatrix[0][numberIndex] = 0;
}

// Let's fill the first row. It represents the number of way of how we can form
// number zero out of numbers 0, 1, 2, ... Obviously there is only one way we could
// form number 0 and it is with number 0 itself.
// Let's fill the first column. It represents the number of ways we can form
// number zero out of numbers 0, 0 and 1, 0 and 1 and 2, 0 and 1 and 2 and 3, ...
// Obviously there is only one way we could form number 0
// and it is with number 0 itself.
for (let summandIndex = 0; summandIndex <= number; summandIndex += 1) {
partitionMatrix[summandIndex][0] = 1;
}
Expand All @@ -33,9 +34,17 @@ export default function integerPartition(number) {
// any new ways of forming the number. Thus we may just copy the number from row above.
partitionMatrix[summandIndex][numberIndex] = partitionMatrix[summandIndex - 1][numberIndex];
} else {
// The number of combinations would equal to number of combinations of forming the same
// number but WITHOUT current summand number plus number of combinations of forming the
// previous number but WITH current summand.
/*
* The number of combinations would equal to number of combinations of forming the same
* number but WITHOUT current summand number PLUS number of combinations of forming the
* <current number - current summand> number but WITH current summand.
*
* Example:
* Number of ways to form 5 using summands {0, 1, 2} would equal the SUM of:
* - number of ways to form 5 using summands {0, 1} (we've excluded summand 2)
* - number of ways to form 3 (because 5 - 2 = 3) using summands {0, 1, 2}
* (we've included summand 2)
*/
const combosWithoutSummand = partitionMatrix[summandIndex - 1][numberIndex];
const combosWithSummand = partitionMatrix[summandIndex][numberIndex - summandIndex];

Expand Down
Loading