Skip to content

Add Absolute Number function in Maths #16

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

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# dependencies
/node_modules

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

# intelliJ workspace folder
.idea
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test
105 changes: 105 additions & 0 deletions Data-structures/QuickSelect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/**
* [QuickSelect](https://www.geeksforgeeks.org/quickselect-algorithm/) is an algorithm to find the kth smallest number
*
* Notes:
* - QuickSelect is related to QuickSort, thus has optimal best and average case O(n) but unlikely poor worst case O(n^2)
* ----
* @complexity O(n) (on average)
* @complexity O(n^2) (worst case)
* ----
* @param items array
* @flow
*/

const QuickSelect = (items: Array<number>, kth: number): number => {
if (kth < 1 || kth > items.length) {
throw new RangeError("Index Out of Bound");
}

return RandomizedSelect(items, 0, items.length - 1, kth);
};

/**
* @param items
* @param left
* @param right
* @param i
* @returns number
*/
const RandomizedSelect = (
items: Array<number>,
left: number,
right: number,
i: number
): number => {
if (left === right) return items[left];

const pivotIndex = RandomizedPartition(items, left, right);
const k = pivotIndex - left + 1;

if (i === k) return items[pivotIndex];
if (i < k) return RandomizedSelect(items, left, pivotIndex - 1, i);

return RandomizedSelect(items, pivotIndex + 1, right, i - k);
};
/**
*
* @param items
* @param left
* @param right
* @returns
*/
const RandomizedPartition = (
items: Array<number>,
left: number,
right: number
): number => {
const rand = getRandomInt(left, right);
Swap(items, rand, right);
return Partition(items, left, right);
};
/**
*
* @param items
* @param left
* @param right
* @returns
*/
const Partition = (items: Array<number>, left: number, right: number) : number => {
const x = items[right];
let pivotIndex = left - 1;

for (let j = left; j < right; j++) {
if (items[j] <= x) {
pivotIndex++;
Swap(items, pivotIndex, j);
}
}

Swap(items, pivotIndex + 1, right);

return pivotIndex + 1;
};

/**
*
* @param min
* @param max
* @returns
*/
const getRandomInt = (min : number, max : number) : number => {
return Math.floor(Math.random() * (max - min + 1)) + min;
}


/**
*
* @param arr array
* @param x array element to swap
* @param y array element to swap
*/
const Swap = (arr : Array<number>, x : number, y : number) : void => {
[arr[x], arr[y]] = [arr[y], arr[x]];
}

export { QuickSelect };
49 changes: 49 additions & 0 deletions Data-structures/test/QuickSelect.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { QuickSelect } from '../QuickSelect'

describe('QuickSelect tests', () => {
it('should return the only element of a list of length 1', () => {
// Test a mix of number types (i.e., positive/negative, numbers with decimals, fractions)
expect(QuickSelect([100], 1)).toEqual(100)
expect(QuickSelect([-23], 1)).toEqual(-23)
expect(QuickSelect([2007.102], 1)).toEqual(2007.102)
expect(QuickSelect([0.9], 1)).toEqual(0.9)
expect(QuickSelect([-0.075], 1)).toEqual(-0.075)
expect(QuickSelect([0], 1)).toEqual(0)
expect(QuickSelect([1], 1)).toEqual(1)
})

it('should throw an Error when k is greater than the length of the list', () => {
expect(() => QuickSelect([100, 2], 5)).toThrow('Index Out of Bound')
})

it('should throw an Error when k is less than 1', () => {
expect(() => QuickSelect([100, 2], 0)).toThrow('Index Out of Bound')
expect(() => QuickSelect([100, 2], -1)).toThrow('Index Out of Bound')
})

describe('varieties of list composition', () => {
it('should return the kth smallest element of a list that is in increasing order', () => {
expect(QuickSelect([10, 22, 33, 44, 55], 1)).toEqual(10)
expect(QuickSelect([10, 22, 33, 44, 55], 2)).toEqual(22)
expect(QuickSelect([10, 22, 33, 44, 55], 3)).toEqual(33)
expect(QuickSelect([10, 22, 33, 44, 55], 4)).toEqual(44)
expect(QuickSelect([10, 22, 33, 44, 55], 5)).toEqual(55)
})

it('should return the kth smallest element of an input list that is in decreasing order', () => {
expect(QuickSelect([82, 33.12, 4.0, 1], 1)).toEqual(1)
expect(QuickSelect([82, 33.12, 4.0, 1], 2)).toEqual(4.0)
expect(QuickSelect([82, 33.12, 4.0, 1], 2)).toEqual(4)
expect(QuickSelect([82, 33.12, 4.0, 1], 3)).toEqual(33.12)
expect(QuickSelect([82, 33.12, 4.0, 1], 4)).toEqual(82)
})

it('should return the kth smallest element of an input list that is no particular order', () => {
expect(QuickSelect([123, 14231, -10, 0, 15], 3)).toEqual(15)
expect(QuickSelect([0, 15, 123, 14231, -10], 3)).toEqual(15)
expect(QuickSelect([-10, 15, 123, 14231, 0], 3)).toEqual(15)
expect(QuickSelect([14231, 0, 15, 123, -10], 3)).toEqual(15)
expect(QuickSelect([14231, 0, 15, -10, 123], 3)).toEqual(15)
})
})
})
20 changes: 20 additions & 0 deletions Maths/Abs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/**
* A function to get absolute value of given number
* @param num The input integer
* @return {number} Absolute value of `num`
* @example abs(-10) => 10 | abs(50) => 50 | abs(0) => 0
* @see https://en.wikipedia.org/wiki/Absolute_value
*/

const abs = (num : number | string) : number => {
const validNumber = +num // converted to number, also can use - Number(num)

if (Number.isNaN(validNumber)) {
throw new TypeError('Argument is NaN - Not a Number')
}

return validNumber < 0 ? -validNumber : validNumber // if number is less then zero mean negative then it converted to positive. i.e -> n = -2 = -(-2) = 2
}

export { abs }

28 changes: 28 additions & 0 deletions Maths/test/Abs.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { abs } from '../Abs'

describe('Testing abs function', () => {
it('Testing for number of string type', () => {
expect(abs('-345')).toBe(345)
expect(abs('-345.455645')).toBe(345.455645)
})

it('should return an absolute value of a negative number', () => {
const absOfNegativeNumber = abs(-34)
expect(absOfNegativeNumber).toBe(34)
})

it('should return an absolute value of a positive number', () => {
const absOfPositiveNumber = abs(50)
expect(absOfPositiveNumber).toBe(50)
})

it('should return an absolute value of a zero number', () => {
const absOfPositiveNumber = abs(0)
expect(absOfPositiveNumber).toBe(0)
})

it('should return an absolute value of any floating number', () => {
const absOfPositiveNumber = abs(-20.2034)
expect(absOfPositiveNumber).toBe(20.2034)
})
})
7 changes: 7 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
'@babel/preset-typescript'
]
};

9 changes: 9 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import type { Config } from "@jest/types";
// Sync object
const config: Config.InitialOptions = {
verbose: true,
transform: {
"^.+\\.tsx?$": "ts-jest",
},
};
export default config;
Loading