Skip to content
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

algorithm : Added Maths' Functions #12

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 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
/temp
# 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 @@
/**
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated changes

Copy link
Contributor Author

@Owais28 Owais28 Sep 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What needs to be changed.

* [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)
})
})
})
18 changes: 18 additions & 0 deletions Maths/Abs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* A function to get absolute value of a given number
* @param {number} num - The input integer
* @return {number} Absolute vlaue of `num`
* @example abs(-10) => 10 | abs(50) => 50 | abs(0) => 0
* @see https://en.wikipedia.org/wiki/Absolute_value
* @author Owais28 <https://github.com/Owais28>
*/

export const abs = (num: number ): number => {
const validNumber : number = +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
};
201 changes: 201 additions & 0 deletions Maths/Area.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
This script provides various methods to find the area of a particular shape
*/

/**
* function to calculate the surface area of a cube
*
* @param side side value of the cube
* @return {number} surace area
* @example surfaceAreaCube(1) = 6
* @see [surfaceAreaCube](https://en.wikipedia.org/wiki/Area#Surface_area)
* @author Owais28 <https://github.com/Owais28>
*/
const surfaceAreaCube = (side: number): number => {
validateNumericParam(side, "side");
return 6 * side ** 2;
};

/**
* function to calculate the surface area of a sphere
*
* @param radius radius of the the spere
* @return {number} - 4 * `PI` * `radius`^2
* @example surfaceAreaSphere(5) = 314.1592653589793
* @see [surfaceAreaSphere](https://en.wikipedia.org/wiki/Sphere)
* @author Owais28 <https://github.com/Owais28>
*/
const surfaceAreaSphere = (radius: number): number => {
validateNumericParam(radius, "radius");
return 4.0 * Math.PI * radius ** 2.0;
};

/**
* function to calculate the area of a Rectangle
*
* @param length length of the rectangle
* @param width width of the rectangle
* @return {Integer} `width` * `length`
* @example areaRectangle(4) = 16
* @see [areaRectangle](https://en.wikipedia.org/wiki/Area#Quadrilateral_area)
* @author Owais28 <https://github.com/Owais28>
*/
const areaRectangle = (length: number, width: number): number => {
validateNumericParam(length, "Length");
validateNumericParam(width, "Width");
return width * length;
};

/**
* function to calculate the area of a Square
*
* @param side side of the square
* @return {number} `side`^2 | `side` ** 2
* @example areaSquare(4) = 16
* @see [areaSquare](https://en.wikipedia.org/wiki/Square)
* @author Owais28 <https://github.com/Owais28>
*/
const areaSquare = (side: number): number => {
validateNumericParam(side, "square side");
return side ** 2;
};

/**
* function to calculate the area of a Triangle
*
* @param base base of the triangle
* @param height height of the triangle
* @return {number} `base` * `height` / 2.
* @example areaTriangle(1.66, 3.44) = 2.8552
* @see [areaTriangle](https://en.wikipedia.org/wiki/Area#Triangle_area)
* @author Owais28 <https://github.com/Owais28>
*/
const areaTriangle = (base: number, height: number): number => {
validateNumericParam(base, "Base");
validateNumericParam(height, "Height");
return (base * height) / 2.0;
};

/**
* function to calculate the area of a Triangle with the all three sides given.
*
* @param side1 side 1
* @param side2 side 2
* @param side3 side 3
* @return {number} area of triangle.
* @example areaTriangleWithAllThreeSides(5, 6, 7) = 14.7
* @see [areaTriangleWithAllThreeSides](https://en.wikipedia.org/wiki/Heron%27s_formula)
* @author Owais28 <https://github.com/Owais28>
*/
const areaTriangleWithAllThreeSides = (
side1: number,
side2: number,
side3: number
): number => {
validateNumericParam(side1, "side1");
validateNumericParam(side2, "side2");
validateNumericParam(side3, "side3");
if (
side1 + side2 <= side3 ||
side1 + side3 <= side2 ||
side2 + side3 <= side1
) {
throw new TypeError("Invalid Triangle sides.");
}
// Finding Semi perimeter of the triangle using formula
const semi = (side1 + side2 + side3) / 2;

// Calculating the area of the triangle
const area = Math.sqrt(
semi * (semi - side1) * (semi - side2) * (semi - side3)
);
return Number(area.toFixed(2));
};

/**
* function to calculate the area of a Parallelogram
*
* @param base
* @param height
* @return {number} `base` * `height`
* @example areaParallelogram(5, 6) = 24
* @see [areaParallelogram](https://en.wikipedia.org/wiki/Area#Dissection,_parallelograms,_and_triangles)
* @author Owais28 <https://github.com/Owais28>
*/
const areaParallelogram = (base : number, height : number) : number => {
validateNumericParam(base, "Base");
validateNumericParam(height, "Height");
return base * height;
};

/**
* function to calculate the area of a Trapezium
*
* @param base1 base 1 of trapazium
* @param base2 base 2 of trapazium
* @param height height of trapazium
* @return {number} (1 / 2) * (`base1` + `base2`) * `height`
* @example areaTrapezium(5, 12, 10) = 85
* @see [areaTrapezium](https://en.wikipedia.org/wiki/Trapezoid)
* @author Owais28 <https://github.com/Owais28>
*/
const areaTrapezium = (base1 : number, base2 : number, height : number) : number => {
validateNumericParam(base1, "Base One");
validateNumericParam(base2, "Base Two");
validateNumericParam(height, "Height");
return (1 / 2) * (base1 + base2) * height;
};

/**
* function to calculate the area of a Circle.
*
* @param radius radius of the circle
* @return {number} `Math.PI` * `radius` ** 2
* @example areaCircle(5, 12, 10) = 85
* @see [areaCircle](https://en.wikipedia.org/wiki/Area_of_a_circle)
* @author Owais28 <https://github.com/Owais28>
*/
const areaCircle = (radius : number) : number => {
validateNumericParam(radius, "Radius");
return Math.PI * radius ** 2;
};

/**
* function to calculate the area of a Circle.
*
* @param diagonal1 first diagonal of rhombus
* @param diagonal2 second diagonal of rhombus
* @return {number} (1 / 2) * `diagonal1` * `diagonal2`
* @example areaRhombus(12, 10) = 60
* @see [areaRhombus](https://en.wikipedia.org/wiki/Rhombus)
* @author Owais28 <https://github.com/Owais28>
*/
const areaRhombus = (diagonal1 : number, diagonal2 : number): number => {
validateNumericParam(diagonal1, "diagonal one");
validateNumericParam(diagonal2, "diagonal two");
return (1 / 2) * diagonal1 * diagonal2;
};

/**
* function to validate the given number
* @param param
* @param paramName
*/
const validateNumericParam = (param : number, paramName : string = "param") : void | Error => {
if (param < 0) {
throw new Error("The " + paramName + " only accepts non-negative values");
}
};

export {
surfaceAreaCube,
surfaceAreaSphere,
areaRectangle,
areaSquare,
areaTriangle,
areaParallelogram,
areaTrapezium,
areaCircle,
areaRhombus,
areaTriangleWithAllThreeSides,
};
Loading