mirror of
https://github.com/trekhleb/javascript-algorithms.git
synced 2025-04-08 07:01:50 +08:00
Upgrade dependencies and fix ESLint issues.
This commit is contained in:
parent
4d8baf87db
commit
63f5a27152
5967
package-lock.json
generated
5967
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -35,15 +35,15 @@
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.10.5",
|
||||
"@babel/preset-env": "^7.10.4",
|
||||
"@types/jest": "^24.9.1",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-airbnb": "^17.1.1",
|
||||
"@types/jest": "^26.0.7",
|
||||
"eslint": "^7.5.0",
|
||||
"eslint-config-airbnb": "^18.2.0",
|
||||
"eslint-plugin-import": "^2.22.0",
|
||||
"eslint-plugin-jest": "^22.21.0",
|
||||
"eslint-plugin-jest": "^23.18.2",
|
||||
"eslint-plugin-jsx-a11y": "^6.3.1",
|
||||
"eslint-plugin-react": "^7.20.3",
|
||||
"husky": "^2.7.0",
|
||||
"jest": "^24.9.0"
|
||||
"husky": "^4.2.5",
|
||||
"jest": "^26.1.0"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ export default class PolynomialHash {
|
||||
* @return {number}
|
||||
*/
|
||||
hash(word) {
|
||||
const charCodes = Array.from(word).map(char => this.charToNumber(char));
|
||||
const charCodes = Array.from(word).map((char) => this.charToNumber(char));
|
||||
|
||||
let hash = 0;
|
||||
for (let charIndex = 0; charIndex < charCodes.length; charIndex += 1) {
|
||||
|
@ -66,7 +66,7 @@ export default function articulationPoints(graph) {
|
||||
// Get minimum low discovery time from all neighbors.
|
||||
/** @param {GraphVertex} neighbor */
|
||||
visitedSet[currentVertex.getKey()].lowDiscoveryTime = currentVertex.getNeighbors()
|
||||
.filter(earlyNeighbor => earlyNeighbor.getKey() !== previousVertex.getKey())
|
||||
.filter((earlyNeighbor) => earlyNeighbor.getKey() !== previousVertex.getKey())
|
||||
/**
|
||||
* @param {number} lowestDiscoveryTime
|
||||
* @param {GraphVertex} neighbor
|
||||
|
@ -53,7 +53,7 @@ export default function graphBridges(graph) {
|
||||
|
||||
// Check if current node is connected to any early node other then previous one.
|
||||
visitedSet[currentVertex.getKey()].lowDiscoveryTime = currentVertex.getNeighbors()
|
||||
.filter(earlyNeighbor => earlyNeighbor.getKey() !== previousVertex.getKey())
|
||||
.filter((earlyNeighbor) => earlyNeighbor.getKey() !== previousVertex.getKey())
|
||||
.reduce(
|
||||
/**
|
||||
* @param {number} lowestDiscoveryTime
|
||||
|
@ -8,9 +8,9 @@ import DisjointSet from '../../../data-structures/disjoint-set/DisjointSet';
|
||||
export default function detectUndirectedCycleUsingDisjointSet(graph) {
|
||||
// Create initial singleton disjoint sets for each graph vertex.
|
||||
/** @param {GraphVertex} graphVertex */
|
||||
const keyExtractor = graphVertex => graphVertex.getKey();
|
||||
const keyExtractor = (graphVertex) => graphVertex.getKey();
|
||||
const disjointSet = new DisjointSet(keyExtractor);
|
||||
graph.getAllVertices().forEach(graphVertex => disjointSet.makeSet(graphVertex));
|
||||
graph.getAllVertices().forEach((graphVertex) => disjointSet.makeSet(graphVertex));
|
||||
|
||||
// Go trough all graph edges one by one and check if edge vertices are from the
|
||||
// different sets. In this case joint those sets together. Do this until you find
|
||||
|
@ -75,7 +75,7 @@ export default function eulerianPath(graph) {
|
||||
[edgeToDelete] = currentEdges;
|
||||
} else {
|
||||
// If there are many edges left then we need to peek any of those except bridges.
|
||||
[edgeToDelete] = currentEdges.filter(edge => !bridges[edge.getKey()]);
|
||||
[edgeToDelete] = currentEdges.filter((edge) => !bridges[edge.getKey()]);
|
||||
}
|
||||
|
||||
// Detect next current vertex.
|
||||
|
@ -20,7 +20,7 @@ function isSafe(adjacencyMatrix, verticesIndices, cycle, vertexCandidate) {
|
||||
}
|
||||
|
||||
// Check if vertexCandidate is being added to the path for the first time.
|
||||
const candidateDuplicate = cycle.find(vertex => vertex.getKey() === vertexCandidate.getKey());
|
||||
const candidateDuplicate = cycle.find((vertex) => vertex.getKey() === vertexCandidate.getKey());
|
||||
|
||||
return !candidateDuplicate;
|
||||
}
|
||||
@ -61,7 +61,7 @@ function hamiltonianCycleRecursive({
|
||||
cycle,
|
||||
}) {
|
||||
// Clone cycle in order to prevent it from modification by other DFS branches.
|
||||
const currentCycle = [...cycle].map(vertex => new GraphVertex(vertex.value));
|
||||
const currentCycle = [...cycle].map((vertex) => new GraphVertex(vertex.value));
|
||||
|
||||
if (vertices.length === currentCycle.length) {
|
||||
// Hamiltonian path is found.
|
||||
|
@ -33,7 +33,7 @@ export default function kruskal(graph) {
|
||||
const sortedEdges = new QuickSort(sortingCallbacks).sort(graph.getAllEdges());
|
||||
|
||||
// Create disjoint sets for all graph vertices.
|
||||
const keyCallback = graphVertex => graphVertex.getKey();
|
||||
const keyCallback = (graphVertex) => graphVertex.getKey();
|
||||
const disjointSet = new DisjointSet(keyCallback);
|
||||
|
||||
graph.getAllVertices().forEach((graphVertex) => {
|
||||
|
@ -21,7 +21,6 @@ describe('reverseTraversal', () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
// it('should reverse traversal the linked list with callback', () => {
|
||||
// const linkedList = new LinkedList();
|
||||
//
|
||||
|
@ -244,7 +244,7 @@ export default class FourierTester {
|
||||
const { input, output: expectedOutput } = testCase;
|
||||
|
||||
// Try to split input signal into sequence of pure sinusoids.
|
||||
const formattedInput = input.map(sample => sample.amplitude);
|
||||
const formattedInput = input.map((sample) => sample.amplitude);
|
||||
const currentOutput = fourierTransform(formattedInput);
|
||||
|
||||
// Check the signal has been split into proper amount of sub-signals.
|
||||
|
@ -46,8 +46,8 @@ export default function fastFourierTransform(inputData, inverse = false) {
|
||||
for (let blockLength = 2; blockLength <= N; blockLength *= 2) {
|
||||
const imaginarySign = inverse ? -1 : 1;
|
||||
const phaseStep = new ComplexNumber({
|
||||
re: Math.cos(2 * Math.PI / blockLength),
|
||||
im: imaginarySign * Math.sin(2 * Math.PI / blockLength),
|
||||
re: Math.cos((2 * Math.PI) / blockLength),
|
||||
im: imaginarySign * Math.sin((2 * Math.PI) / blockLength),
|
||||
});
|
||||
|
||||
for (let blockStart = 0; blockStart < N; blockStart += blockLength) {
|
||||
|
@ -9,7 +9,7 @@ export default function pascalTriangle(lineNumber) {
|
||||
|
||||
for (let numIndex = 1; numIndex < currentLineSize; numIndex += 1) {
|
||||
// See explanation of this formula in README.
|
||||
currentLine[numIndex] = currentLine[numIndex - 1] * (lineNumber - numIndex + 1) / numIndex;
|
||||
currentLine[numIndex] = (currentLine[numIndex - 1] * (lineNumber - numIndex + 1)) / numIndex;
|
||||
}
|
||||
|
||||
return currentLine;
|
||||
|
@ -6,7 +6,7 @@ describe('degreeToRadian', () => {
|
||||
expect(degreeToRadian(45)).toBe(Math.PI / 4);
|
||||
expect(degreeToRadian(90)).toBe(Math.PI / 2);
|
||||
expect(degreeToRadian(180)).toBe(Math.PI);
|
||||
expect(degreeToRadian(270)).toBe(3 * Math.PI / 2);
|
||||
expect(degreeToRadian(270)).toBe((3 * Math.PI) / 2);
|
||||
expect(degreeToRadian(360)).toBe(2 * Math.PI);
|
||||
});
|
||||
});
|
||||
|
@ -6,7 +6,7 @@ describe('radianToDegree', () => {
|
||||
expect(radianToDegree(Math.PI / 4)).toBe(45);
|
||||
expect(radianToDegree(Math.PI / 2)).toBe(90);
|
||||
expect(radianToDegree(Math.PI)).toBe(180);
|
||||
expect(radianToDegree(3 * Math.PI / 2)).toBe(270);
|
||||
expect(radianToDegree((3 * Math.PI) / 2)).toBe(270);
|
||||
expect(radianToDegree(2 * Math.PI)).toBe(360);
|
||||
});
|
||||
});
|
||||
|
@ -31,7 +31,7 @@ export default function interpolationSearch(sortedArray, seekElement) {
|
||||
}
|
||||
|
||||
// Do interpolation of the middle index.
|
||||
const middleIndex = leftIndex + Math.floor(valueDelta * indexDelta / rangeDelta);
|
||||
const middleIndex = leftIndex + Math.floor((valueDelta * indexDelta) / rangeDelta);
|
||||
|
||||
// If we've found the element just return its position.
|
||||
if (sortedArray[middleIndex] === seekElement) {
|
||||
|
@ -7,7 +7,7 @@ export default function combineWithRepetitions(comboOptions, comboLength) {
|
||||
// If the length of the combination is 1 then each element of the original array
|
||||
// is a combination itself.
|
||||
if (comboLength === 1) {
|
||||
return comboOptions.map(comboOption => [comboOption]);
|
||||
return comboOptions.map((comboOption) => [comboOption]);
|
||||
}
|
||||
|
||||
// Init combinations array.
|
||||
|
@ -7,7 +7,7 @@ export default function combineWithoutRepetitions(comboOptions, comboLength) {
|
||||
// If the length of the combination is 1 then each element of the original array
|
||||
// is a combination itself.
|
||||
if (comboLength === 1) {
|
||||
return comboOptions.map(comboOption => [comboOption]);
|
||||
return comboOptions.map((comboOption) => [comboOption]);
|
||||
}
|
||||
|
||||
// Init combinations array.
|
||||
|
@ -150,7 +150,6 @@ export default class Knapsack {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Solve unbounded knapsack problem.
|
||||
// Greedy approach.
|
||||
solveUnboundedKnapsackProblem() {
|
||||
|
@ -8,7 +8,7 @@ export default function permutateWithRepetitions(
|
||||
permutationLength = permutationOptions.length,
|
||||
) {
|
||||
if (permutationLength === 1) {
|
||||
return permutationOptions.map(permutationOption => [permutationOption]);
|
||||
return permutationOptions.map((permutationOption) => [permutationOption]);
|
||||
}
|
||||
|
||||
// Init permutations array.
|
||||
|
@ -81,7 +81,6 @@ function nQueensRecursive(solutions, previousQueensPositions, queensCount, rowIn
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} queensCount
|
||||
* @return {QueenPosition[][]}
|
||||
|
@ -16,7 +16,7 @@ export default class BloomFilter {
|
||||
const hashValues = this.getHashValues(item);
|
||||
|
||||
// Set each hashValue index to true.
|
||||
hashValues.forEach(val => this.storage.setValue(val));
|
||||
hashValues.forEach((val) => this.storage.setValue(val));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -51,7 +51,7 @@ describe('BloomFilter', () => {
|
||||
});
|
||||
|
||||
it('should insert strings correctly and return true when checking for inserted values', () => {
|
||||
people.forEach(person => bloomFilter.insert(person));
|
||||
people.forEach((person) => bloomFilter.insert(person));
|
||||
|
||||
expect(bloomFilter.mayContain('Bruce Wayne')).toBe(true);
|
||||
expect(bloomFilter.mayContain('Clark Kent')).toBe(true);
|
||||
|
@ -94,7 +94,7 @@ describe('DisjointSet', () => {
|
||||
});
|
||||
|
||||
it('should do basic manipulations on disjoint set with custom key extractor', () => {
|
||||
const keyExtractor = value => value.key;
|
||||
const keyExtractor = (value) => value.key;
|
||||
|
||||
const disjointSet = new DisjointSet(keyExtractor);
|
||||
|
||||
|
@ -218,7 +218,7 @@ export default class DoublyLinkedList {
|
||||
* @return {DoublyLinkedList}
|
||||
*/
|
||||
fromArray(values) {
|
||||
values.forEach(value => this.append(value));
|
||||
values.forEach((value) => this.append(value));
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -228,7 +228,7 @@ export default class DoublyLinkedList {
|
||||
* @return {string}
|
||||
*/
|
||||
toString(callback) {
|
||||
return this.toArray().map(node => node.toString(callback)).toString();
|
||||
return this.toArray().map((node) => node.toString(callback)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -164,7 +164,7 @@ describe('DoublyLinkedList', () => {
|
||||
.append(nodeValue1)
|
||||
.prepend(nodeValue2);
|
||||
|
||||
const nodeStringifier = value => `${value.key}:${value.value}`;
|
||||
const nodeStringifier = (value) => `${value.key}:${value.value}`;
|
||||
|
||||
expect(linkedList.toString(nodeStringifier)).toBe('key2:2,key1:1');
|
||||
});
|
||||
@ -195,12 +195,12 @@ describe('DoublyLinkedList', () => {
|
||||
.append({ value: 2, key: 'test2' })
|
||||
.append({ value: 3, key: 'test3' });
|
||||
|
||||
const node = linkedList.find({ callback: value => value.key === 'test2' });
|
||||
const node = linkedList.find({ callback: (value) => value.key === 'test2' });
|
||||
|
||||
expect(node).toBeDefined();
|
||||
expect(node.value.value).toBe(2);
|
||||
expect(node.value.key).toBe('test2');
|
||||
expect(linkedList.find({ callback: value => value.key === 'test5' })).toBeNull();
|
||||
expect(linkedList.find({ callback: (value) => value.key === 'test5' })).toBeNull();
|
||||
});
|
||||
|
||||
it('should find node by means of custom compare function', () => {
|
||||
|
@ -48,7 +48,7 @@ describe('DoublyLinkedListNode', () => {
|
||||
it('should convert node to string with custom stringifier', () => {
|
||||
const nodeValue = { value: 1, key: 'test' };
|
||||
const node = new DoublyLinkedListNode(nodeValue);
|
||||
const toStringCallback = value => `value: ${value.value}, key: ${value.key}`;
|
||||
const toStringCallback = (value) => `value: ${value.value}, key: ${value.key}`;
|
||||
|
||||
expect(node.toString(toStringCallback)).toBe('value: 1, key: test');
|
||||
});
|
||||
|
@ -64,7 +64,7 @@ export default class GraphVertex {
|
||||
* @return {GraphEdge[]}
|
||||
*/
|
||||
getEdges() {
|
||||
return this.edges.toArray().map(linkedListNode => linkedListNode.value);
|
||||
return this.edges.toArray().map((linkedListNode) => linkedListNode.value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -80,7 +80,7 @@ export default class GraphVertex {
|
||||
*/
|
||||
hasEdge(requiredEdge) {
|
||||
const edgeNode = this.edges.find({
|
||||
callback: edge => edge === requiredEdge,
|
||||
callback: (edge) => edge === requiredEdge,
|
||||
});
|
||||
|
||||
return !!edgeNode;
|
||||
@ -92,7 +92,7 @@ export default class GraphVertex {
|
||||
*/
|
||||
hasNeighbor(vertex) {
|
||||
const vertexNode = this.edges.find({
|
||||
callback: edge => edge.startVertex === vertex || edge.endVertex === vertex,
|
||||
callback: (edge) => edge.startVertex === vertex || edge.endVertex === vertex,
|
||||
});
|
||||
|
||||
return !!vertexNode;
|
||||
@ -123,7 +123,7 @@ export default class GraphVertex {
|
||||
* @return {GraphVertex}
|
||||
*/
|
||||
deleteAllEdges() {
|
||||
this.getEdges().forEach(edge => this.deleteEdge(edge));
|
||||
this.getEdges().forEach((edge) => this.deleteEdge(edge));
|
||||
|
||||
return this;
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ export default class HashTable {
|
||||
const keyHash = this.hash(key);
|
||||
this.keys[key] = keyHash;
|
||||
const bucketLinkedList = this.buckets[keyHash];
|
||||
const node = bucketLinkedList.find({ callback: nodeValue => nodeValue.key === key });
|
||||
const node = bucketLinkedList.find({ callback: (nodeValue) => nodeValue.key === key });
|
||||
|
||||
if (!node) {
|
||||
// Insert new node.
|
||||
@ -71,7 +71,7 @@ export default class HashTable {
|
||||
const keyHash = this.hash(key);
|
||||
delete this.keys[key];
|
||||
const bucketLinkedList = this.buckets[keyHash];
|
||||
const node = bucketLinkedList.find({ callback: nodeValue => nodeValue.key === key });
|
||||
const node = bucketLinkedList.find({ callback: (nodeValue) => nodeValue.key === key });
|
||||
|
||||
if (node) {
|
||||
return bucketLinkedList.delete(node.value);
|
||||
@ -86,7 +86,7 @@ export default class HashTable {
|
||||
*/
|
||||
get(key) {
|
||||
const bucketLinkedList = this.buckets[this.hash(key)];
|
||||
const node = bucketLinkedList.find({ callback: nodeValue => nodeValue.key === key });
|
||||
const node = bucketLinkedList.find({ callback: (nodeValue) => nodeValue.key === key });
|
||||
|
||||
return node ? node.value.value : undefined;
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ describe('HashTable', () => {
|
||||
expect(hashTable.has('b')).toBe(true);
|
||||
expect(hashTable.has('c')).toBe(true);
|
||||
|
||||
const stringifier = value => `${value.key}:${value.value}`;
|
||||
const stringifier = (value) => `${value.key}:${value.value}`;
|
||||
|
||||
expect(hashTable.buckets[0].toString(stringifier)).toBe('c:earth');
|
||||
expect(hashTable.buckets[1].toString(stringifier)).toBe('a:sky,d:ocean');
|
||||
|
@ -180,7 +180,7 @@ export default class LinkedList {
|
||||
* @return {LinkedList}
|
||||
*/
|
||||
fromArray(values) {
|
||||
values.forEach(value => this.append(value));
|
||||
values.forEach((value) => this.append(value));
|
||||
|
||||
return this;
|
||||
}
|
||||
@ -205,7 +205,7 @@ export default class LinkedList {
|
||||
* @return {string}
|
||||
*/
|
||||
toString(callback) {
|
||||
return this.toArray().map(node => node.toString(callback)).toString();
|
||||
return this.toArray().map((node) => node.toString(callback)).toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -146,7 +146,7 @@ describe('LinkedList', () => {
|
||||
.append(nodeValue1)
|
||||
.prepend(nodeValue2);
|
||||
|
||||
const nodeStringifier = value => `${value.key}:${value.value}`;
|
||||
const nodeStringifier = (value) => `${value.key}:${value.value}`;
|
||||
|
||||
expect(linkedList.toString(nodeStringifier)).toBe('key2:2,key1:1');
|
||||
});
|
||||
@ -177,12 +177,12 @@ describe('LinkedList', () => {
|
||||
.append({ value: 2, key: 'test2' })
|
||||
.append({ value: 3, key: 'test3' });
|
||||
|
||||
const node = linkedList.find({ callback: value => value.key === 'test2' });
|
||||
const node = linkedList.find({ callback: (value) => value.key === 'test2' });
|
||||
|
||||
expect(node).toBeDefined();
|
||||
expect(node.value.value).toBe(2);
|
||||
expect(node.value.key).toBe('test2');
|
||||
expect(linkedList.find({ callback: value => value.key === 'test5' })).toBeNull();
|
||||
expect(linkedList.find({ callback: (value) => value.key === 'test5' })).toBeNull();
|
||||
});
|
||||
|
||||
it('should create linked list from array', () => {
|
||||
|
@ -39,7 +39,7 @@ describe('LinkedListNode', () => {
|
||||
it('should convert node to string with custom stringifier', () => {
|
||||
const nodeValue = { value: 1, key: 'test' };
|
||||
const node = new LinkedListNode(nodeValue);
|
||||
const toStringCallback = value => `value: ${value.value}, key: ${value.key}`;
|
||||
const toStringCallback = (value) => `value: ${value.value}, key: ${value.key}`;
|
||||
|
||||
expect(node.toString(toStringCallback)).toBe('value: 1, key: test');
|
||||
});
|
||||
|
@ -22,7 +22,7 @@ describe('Queue', () => {
|
||||
queue.enqueue({ value: 'test1', key: 'key1' });
|
||||
queue.enqueue({ value: 'test2', key: 'key2' });
|
||||
|
||||
const stringifier = value => `${value.key}:${value.value}`;
|
||||
const stringifier = (value) => `${value.key}:${value.value}`;
|
||||
|
||||
expect(queue.toString(stringifier)).toBe('key1:test1,key2:test2');
|
||||
expect(queue.dequeue().value).toBe('test1');
|
||||
|
@ -54,7 +54,7 @@ export default class Stack {
|
||||
toArray() {
|
||||
return this.linkedList
|
||||
.toArray()
|
||||
.map(linkedListNode => linkedListNode.value);
|
||||
.map((linkedListNode) => linkedListNode.value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -56,7 +56,7 @@ describe('Stack', () => {
|
||||
stack.push({ value: 'test1', key: 'key1' });
|
||||
stack.push({ value: 'test2', key: 'key2' });
|
||||
|
||||
const stringifier = value => `${value.key}:${value.value}`;
|
||||
const stringifier = (value) => `${value.key}:${value.value}`;
|
||||
|
||||
expect(stack.toString(stringifier)).toBe('key2:test2,key1:test1');
|
||||
expect(stack.pop().value).toBe('test2');
|
||||
|
Loading…
x
Reference in New Issue
Block a user