[Enhancement] Add Eslint + Prttier for JavaScript project (#217)

pull/218/head
Ming Tsai 2021-04-16 14:38:23 -04:00 committed by GitHub
parent 9219607191
commit a123ccd805
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 1564 additions and 284 deletions

35
.github/workflows/node.js.yml vendored 100644
View File

@ -0,0 +1,35 @@
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
name: Node.js CI
on:
push:
branches: [ main ]
paths: '**/**.js'
pull_request:
branches: [ main ]
paths: '**/**.js'
env:
PATH_PREFIX: 'algorithms/JavaScript'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [10.x, 12.x, 14.x, 15.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: |
cd ${{ env.PATH_PREFIX }}
npm ci
- run: npm run build --if-present --prefix ${{ env.PATH_PREFIX }}
- run: npm run lint --prefix ${{ env.PATH_PREFIX }}

View File

@ -0,0 +1,42 @@
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true
},
"extends": [
"google"
],
"parserOptions": {
"ecmaVersion": 12
},
"rules": {
"linebreak-style": 0,
"global-require": 0,
"eslint linebreak-style": [
0,
"error",
"windows"
],
"require-jsdoc": [
"error",
{
"require": {
"FunctionDeclaration": false,
"MethodDefinition": false,
"ClassDeclaration": false,
"ArrowFunctionExpression": false,
"FunctionExpression": false
}
}
],
"semi": [
"error",
"always"
],
"quotes": [
"error",
"single"
]
}
}

116
algorithms/JavaScript/.gitignore vendored 100644
View File

@ -0,0 +1,116 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v2
.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
.pnp.*

View File

@ -0,0 +1,6 @@
{
"trailingComma": "es5",
"tabWidth": 2,
"semi": true,
"singleQuote": true
}

View File

@ -1,21 +1,21 @@
# JavaScript
## Arrays
1. [Count Inversions](arrays/count-inversions.js)
1. [Counting Inversions](src/arrays/counting-inversions.js)
## Linked Lists
1. [Singly](linked_lists/singly.js)
1. [Singly](lsrc/inked_lists/singly.js)
## Searching
1. [Binary Search Recursive](searching/binary-search-recursive.js)
2. [Binary Search](searching/binary-search.js)
3. [Linear Search](searching/linear-search.js)
1. [Binary Search Recursive](src/searching/binary-search-recursive.js)
2. [Binary Search](src/searching/binary-search.js)
3. [Linear Search](src/searching/linear-search.js)
## Sorting
1. [Bubble Sort](sorting/bubble-sort.js)
2. [Insertion Sort](sorting/insertion-sort.js)
3. [Selection Sort](sorting/selection-sort.js)
1. [Bubble Sort](src/sorting/bubble-sort.js)
2. [Insertion Sort](src/sorting/insertion-sort.js)
3. [Selection Sort](src/sorting/selection-sort.js)
## Strings
1. [Palindrome](strings/palindrome.js)
2. [Sequence](strings/sequence.js)
1. [Palindrome](src/strings/palindrome.js)
2. [Sequence](src/strings/sequence.js)

View File

@ -1,48 +0,0 @@
// Algorithm Type: Divide & Conquer
// Time Complexity: O(n*log(n))
function count_split_inv(arr, left, right) {
let split_inv, lidx, ridx;
split_inv = ridx = lidx = 0;
let size = arr.length;
let lsize = left.length;
let rsize = right.length;
for (let i = 0; i < size; i++) {
if (lidx != lsize && ridx != rsize) {
if (right[ridx] <= left[lidx]) {
arr[i] = right[ridx];
ridx++;
split_inv += lsize - lidx;
} else {
arr[i] = left[lidx];
lidx++;
}
} else if (lidx == lsize) {
arr[i] = right[ridx];
ridx++;
} else if (ridx == rsize) {
arr[i] = left[lidx];
lidx++;
}
}
return split_inv;
}
function count_inversions(arr) {
let size = arr.length;
if (size == 1) {
return 0;
}
let mid = parseInt(size / 2);
let left = arr.slice(0, mid);
let right = arr.slice(mid, size);
let left_inv = count_inversions(left);
let right_inv = count_inversions(right);
let split_inv = count_split_inv(arr, left, right);
return left_inv + right_inv + split_inv;
}
var arr = [8, 2, 1, 5, 7, 3, 9, 2, 0, 1];
console.log(count_inversions(arr));

View File

@ -1,55 +0,0 @@
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class SinglyLinkedList {
constructor() {
this.head = null;
}
insertAtHead(data) {
let newNode = new Node(data);
if(this.head == null) {
this.head = newNode;
} else {
newNode.next = this.head;
this.head = newNode;
}
}
removeAtHead() {
// check for underflow
if(this.head == null) {
console.log("Underflow");
return;
}
// store head's reference data value in local data variable
let data = this.head.data;
this.head = this.head.next;
return data;
}
printList() {
// if head is null then list is empty
if(this.head == null) {
console.log("List is Empty");
} else {
// iterate through list until itr is not null
let itr = this.head;
while(itr != null) {
console.log(itr.data);
itr = itr.next;
}
}
}
}
let l = new SinglyLinkedList();
l.insertAtHead(1);
l.insertAtHead('xyz');
l.insertAtHead(1.1);
l.removeAtHead();
l.printList()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
{
"name": "algorithms",
"version": "1.0.0",
"description": "Data structure and Algorithm (DSA) contributions",
"main": "index.js",
"directories": {
"test": "test"
},
"scripts": {
"lint": "eslint src/**/*.js",
"build": "node src/index.js",
"test": "echo 'Doesn't have test'"
},
"dependencies": {},
"devDependencies": {
"eslint": "^7.24.0",
"eslint-config-google": "^0.14.0",
"prettier": "2.2.1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MakeContributions/DSA.git"
},
"keywords": [
"DSA",
"Algorithm",
"JavaScript"
],
"author": "Make Contributions",
"license": "MIT",
"bugs": {
"url": "https://github.com/MakeContributions/DSA/issues"
},
"homepage": "https://github.com/MakeContributions/DSA#readme"
}

View File

@ -1,52 +0,0 @@
//Recursive Method
/*Arguments to Function
arr - array ( Sorted Only )
low - lower index of array (0)
high - max index of array (length of array - 1 )
item = Element to be searched .
*/
function binary_recurrence(arr, low, high, item) {
// Base Case for the termination of Recursion
if(low > high) {
return -1 ; //Item is not present in the Array
}
// Calculating Mid Index
let mid = Math.floor((low+high)/2) ;
//Equation Middle Element with the item to be searched
if(arr[mid] == item ){
// Middle Element equal to the Item
// We found Element at the mid Index
return mid ;
}
else if( arr[mid] > item ){
// Item is less than the middle Element
// Ignore the Right Half , as right half contains elements greater than middle element and so item too .
// Make a recursive call to the left Half
return binary_recurrence(arr,low,mid-1,item);
}
else {
//Item is greater than the middle Element
//Ignore the Left Half ,as left half contains element less than middle element and so item too .
//Make recursive call to the right Half
return binary_recurrence(arr,mid+1,high,item);
}
}
console.log(binary_recurrence([1,3,5,7,8,9], 0, 5, 7)); //returns 3 , Found at Index 3
console.log(binary_recurrence([1,3,5,7,8,9], 0, 5, 10)); //returns -1 , 10 is not present in array

View File

@ -1,34 +0,0 @@
/* In this We will learn how to search for an item in Sorted array using Binary Search .*/
function binarySearch( item , arr ) {
let first = 0; //left endpoint or index of first array element
let last = arr.length - 1; //right endpoint or index of lat array element .
while (first <= last) {
let middle = Math.floor((first + last)/2);
if ( arr[middle] == item ) {
// If the element is present at the middle itself
return middle ;
}
else if ( arr[middle] > item ) {
// Ignore Right Half i.e. items after middle element .
last = middle - 1;
}
else {
// Ignore Right Half i.e. items after middle element .
first = middle + 1;
}
}
return -1; //Item is not present in Array .
}
console.log(binarySearch(6,[2, 6, 8])); //expected output = 1
console.log(binarySearch(10,[2, 3, 10, 14])); //expected output = 2
console.log(binarySearch(1,[2, 6, 8])); //expected output = -1

View File

@ -1,16 +0,0 @@
function insertionSort(array) {
// start with index 1 because only one element is already sorted
for(let i=1; i<array.length ; i++) {
let key = array[i];
let j = i - 1;
// decrement j until array[j] is not less or equal to key
while(j >= 0 && array[j] > key) {
array[j+1] = array[j];
j--;
}
array[j+1] = key;
}
return array;
}
console.log(insertionSort([4,5,6,7,8,10,1,2,3,4])) // output : [1,2,3,4,4,5,6,7,8,10]

View File

@ -1,25 +0,0 @@
function selectionSort(array) {
// loop through all elements except last in array
for(let i=0;i<array.length - 1;i++) {
let min_index = i;
// find minimum element index in unsorted array
for(let j=i+1;j<array.length;j++) {
if(array[j] < array[i]) {
min_index = j;
}
// swap with element at minimum index
let temp = array[min_index];
array[min_index] = array[i];
array[i] = temp;
}
}
// return sorted array
return array;
}
// test
console.log(selectionSort([9,8,7,6,5,4,3,2,1,0]))

View File

@ -0,0 +1,51 @@
// Algorithm Type: Divide & Conquer
// Time Complexity: O(n*log(n))
function countingSplit(arr, left, right) {
let splitInversion = 0;
let leftIndex = 0;
let rightIndex = 0;
const size = arr.length;
const leftSize = left.length;
const rightSize = right.length;
for (let i = 0; i < size; i++) {
if (leftIndex != leftSize && rightIndex != rightSize) {
if (right[rightIndex] <= left[leftIndex]) {
arr[i] = right[rightIndex];
rightIndex++;
splitInversion += leftSize - leftIndex;
} else {
arr[i] = left[leftIndex];
leftIndex++;
}
} else if (leftIndex == leftSize) {
arr[i] = right[rightIndex];
rightIndex++;
} else if (rightIndex == rightSize) {
arr[i] = left[leftIndex];
leftIndex++;
}
}
return splitInversion;
}
function countingInversions(arr) {
const size = arr.length;
let result = 0;
if (size !== 1) {
const mid = parseInt(size / 2);
const left = arr.slice(0, mid);
const right = arr.slice(mid, size);
const leftInversion = countingInversions(left);
const rightInversion = countingInversions(right);
const splitInversion = countingSplit(arr, left, right);
result = leftInversion + rightInversion + splitInversion;
}
return result;
}
const arr = [8, 2, 1, 5, 7, 3, 9, 2, 0, 1];
console.log(countingInversions(arr));

View File

@ -0,0 +1,19 @@
// Arrays
require('./arrays/counting-inversions');
// Linked Lists
require('./linked-lists/singly');
// Searching
require('./searching/binary-search-recursive');
require('./searching/binary-search');
require('./searching/linear-search');
// Sorting
require('./sorting/bubble-sort');
require('./sorting/insertion-sort');
require('./sorting/selection-sort');
// Strings
require('./strings/palindrome');
require('./strings/sequence');

View File

@ -0,0 +1,55 @@
class Node {
constructor(data) {
this.data = data;
this.next = null;
}
}
class SinglyLinkedList {
constructor() {
this.head = null;
}
insertAtHead(data) {
const newNode = new Node(data);
if (this.head == null) {
this.head = newNode;
} else {
newNode.next = this.head;
this.head = newNode;
}
}
removeAtHead() {
// check for underflow
if (this.head == null) {
console.log('Underflow');
return;
}
// store head's reference data value in local data variable
const data = this.head.data;
this.head = this.head.next;
return data;
}
printList() {
// if head is null then list is empty
if (this.head == null) {
console.log('List is Empty');
} else {
// iterate through list until itr is not null
let itr = this.head;
while (itr != null) {
console.log(itr.data);
itr = itr.next;
}
}
}
}
const array = new SinglyLinkedList();
array.insertAtHead(1);
array.insertAtHead('xyz');
array.insertAtHead(1.1);
array.removeAtHead();
array.printList();

View File

@ -0,0 +1,47 @@
// Recursive Method
/*
* Arguments to Function
* arr - array ( Sorted Only )
* low - lower index of array (0)
* high - max index of array (length of array - 1 )
* item = Element to be searched .
*/
function binaryRecursive(arr, low, high, item) {
// Base Case for the termination of Recursion
if (low > high) {
return -1;// Item is not present in the Array
}
// Calculating Mid Index
const mid = Math.floor((low + high) / 2);
// Equation Middle Element with the item to be searched
if (arr[mid] == item) {
// Middle Element equal to the Item
// We found Element at the mid Index
return mid;
} else if (arr[mid] > item) {
// Item is less than the middle Element
// Ignore the Right Half , as right half contains elements
// greater than middle element and so item too.
// Make a recursive call to the left Half
return binaryRecursive(arr, low, mid - 1, item);
} else {
// Item is greater than the middle Element
// Ignore the Left Half ,as left half contains element less
// than middle element and so item too .
// Make recursive call to the right Half
return binaryRecursive(arr, mid + 1, high, item);
}
}
// returns 3 , Found at Index 3
console.log(binaryRecursive([1, 3, 5, 7, 8, 9], 0, 5, 7));
// returns -1 , 10 is not present in array
console.log(binaryRecursive([1, 3, 5, 7, 8, 9], 0, 5, 10));

View File

@ -0,0 +1,31 @@
/*
* In this We will learn how to search for an item in
* Sorted array using Binary Search.
*/
function binarySearch(item, arr) {
let first = 0; // left endpoint or index of first array element
let last = arr.length - 1; // right endpoint or index of lat array element .
while (first <= last) {
const middle = Math.floor((first + last) / 2);
if (arr[middle] == item) {
// If the element is present at the middle itself
return middle;
} else if (arr[middle] > item) {
// Ignore Right Half i.e. items after middle element .
last = middle - 1;
} else {
// Ignore Right Half i.e. items after middle element .
first = middle + 1;
}
}
return -1; // Item is not present in Array .
}
// expected output = 1
console.log(binarySearch(6, [2, 6, 8]));
// expected output = 2
console.log(binarySearch(10, [2, 3, 10, 14]));
// expected output = -1
console.log(binarySearch(1, [2, 6, 8]));

View File

@ -1,9 +1,11 @@
// Linear Search JavaScript Version: searches for a specific item in an array and returns the index of the item.
// Linear Search JavaScript Version: searches for a
// specific item in an array and returns the index of the item.
function linearSearch(arr, x) {
// Loop through the array
for (let i = 0; i < arr.length; i++) {
// Checks if the item in the array = search item. If yes, return the index. If not, move to next item.
// Checks if the item in the array = search item.
// If yes, return the index. If not, move to next item.
if (arr[i] === x) {
return i;
}

View File

@ -2,11 +2,12 @@
function bubbleSort(arr) {
// Copy the contents of the input array and store them as a separate variable
let sorted = [...arr];
const sorted = [...arr];
// Loop through the copied array
for (let i = 0; i < sorted.length; i++) {
// Checks if an item in the array is greater than the item next to it (index + 1)
// Checks if an item in the array is
// greater than the item next to it (index + 1)
if (sorted[i] > sorted[i + 1]) {
// If yes, swap them
sorted.splice(i, 2, sorted[i + 1], sorted[i]);

View File

@ -0,0 +1,17 @@
function insertionSort(array) {
// start with index 1 because only one element is already sorted
for (let i = 1; i < array.length; i++) {
const key = array[i];
let j = i - 1;
// decrement j until array[j] is not less or equal to key
while (j >= 0 && array[j] > key) {
array[j + 1] = array[j];
j--;
}
array[j + 1] = key;
}
return array;
}
// output : [1,2,3,4,4,5,6,7,8,10]
console.log(insertionSort([4, 5, 6, 7, 8, 10, 1, 2, 3, 4]));

View File

@ -0,0 +1,24 @@
function selectionSort(array) {
// loop through all elements except last in array
for (let i = 0; i < array.length - 1; i++) {
let minIndex = i;
// find minimum element index in unsorted array
for (let j = i + 1; j < array.length; j++) {
if (array[j] < array[i]) {
minIndex = j;
}
// swap with element at minimum index
const temp = array[minIndex];
array[minIndex] = array[i];
array[i] = temp;
}
}
// return sorted array
return array;
}
// test
console.log(selectionSort([9, 8, 7, 6, 5, 4, 3, 2, 1, 0]));

View File

@ -0,0 +1,22 @@
// JavaScript Palindrome Checker: Checks whether a word is the same in reverse.
// Ignores punctuation, capitalization & spaces.
function isPalindrome(str) {
// First convert the string into proper alphanumeric word
const properStr = str.replace(/[_\W]/g, '').toLowerCase();
// Now reverse the proper string
const reverseStr = properStr.split('').reverse().join('');
/*
* Finally compare the proper string and reverse string and
* return true or false
*/
return properStr === reverseStr;
}
// Output to the console
console.log(isPalindrome('eye'));
console.log(isPalindrome('Mr. Owl ate my metal worm'));
console.log(isPalindrome('RAce C*_aR'));
console.log(isPalindrome('asdfggfrd'));

View File

@ -1,25 +1,15 @@
var list = [];
let list = [];
const subsequence = (input, output = '') => {
if (input === "") {
if (output !== '' && !list.includes(output)) list.push(output);
return;
}
if (input === '') {
if (output !== '' && !list.includes(output)) list.push(output);
return;
}
subsequence(input.substr(1), output + input.charAt(0));
subsequence(input.substr(1), output);
}
subsequence(input.substr(1), output + input.charAt(0));
subsequence(input.substr(1), output);
};
subsequence('abc');
console.log('abc', list);
list = [];
subsequence('aaa');
console.log('aaa', list);
list = [];
subsequence('hello');
console.log('hello', list);
/*
to run the file:
@ -42,3 +32,15 @@ console.log('hello', list);
'lo', 'l', 'o'
]
*/
subsequence('abc');
console.log('abc', list);
list = [];
subsequence('aaa');
console.log('aaa', list);
list = [];
subsequence('hello');
console.log('hello', list);

View File

@ -1,22 +0,0 @@
// JavaScript Palindrome Checker: Checks whether a word is the same in reverse. Ignores punctuation, capitalization & spaces.
function isPalindrome(str) {
// First convert the string into proper alphanumeric word
let properStr = str
.replace(/[_\W]/g, "")
.toLowerCase();
// Now reverse the proper string
let reverseStr = properStr
.split("")
.reverse()
.join("");
// Finally compare the proper string and reverse string and return true or false
return properStr === reverseStr;
}
// Output to the console
console.log(isPalindrome("eye"));
console.log(isPalindrome("Mr. Owl ate my metal worm"));
console.log(isPalindrome("RAce C*_aR"));

3
package-lock.json generated 100644
View File

@ -0,0 +1,3 @@
{
"lockfileVersion": 1
}