Skip to content
  • Sponsor TheAlgorithms/TypeScript

  • Notifications You must be signed in to change notification settings
  • Fork 428

algorithm : Added Maths' Functions #12

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 16 commits into from
Closed
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 @@
/**
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,
};
25 changes: 25 additions & 0 deletions Maths/BinaryConvert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
* Function to covert a Decimal input to Binary
* @param num Decimal input
* @return Binary of `num`
* @example BinaryConvert(12) => 1100 | BinaryConvert(12 + 2) => 1110
* @see [BinaryConvert](https://www.programiz.com/javascript/examples/decimal-binary)
* @author Owais28 <https://github.com/Owais28>
*/

const BinaryConvert = (num : number) : number => {
let power = 1
let binary = 0

while (num) {
const rem = num % 2
num = Math.floor(num / 2)
binary = rem * power + binary
power *= 10
}

return binary
}

export { BinaryConvert }

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

describe('Testing abs function', () => {


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)
})
})
106 changes: 106 additions & 0 deletions Maths/test/Area.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import * as area from '../Area'

describe('Testing surfaceAreaCube calculations', () => {
it('with natural number', () => {
const surfaceAreaOfOne = area.surfaceAreaCube(1.2)
const surfaceAreaOfThree = area.surfaceAreaCube(3)
expect(surfaceAreaOfOne).toBe(8.64)
expect(surfaceAreaOfThree).toBe(54)
})
it('with negative argument, expect throw', () => {
expect(() => area.surfaceAreaCube(-1)).toThrow()
})
})

describe('Testing surfaceAreaSphere calculations', () => {
it('with correct value', () => {
const calculateArea = area.surfaceAreaSphere(5)
const expected = 314.1592653589793
expect(calculateArea).toBe(expected)
})
it('with negative value, expect throw', () => {
expect(() => area.surfaceAreaSphere(-1)).toThrow()
})
})

describe('Testing areaRectangle calculations', () => {
it('with correct args', () => {
const areaRectangle = area.areaRectangle(2.5, 2)
expect(areaRectangle).toBe(5.0)
})
it('with incorrect args, expect throw', () => {
expect(() => area.areaRectangle(-1, 20)).toThrow()
expect(() => area.areaRectangle(23, -1)).toThrow()
})
})

describe('Testing areaSquare calculations', () => {
it('with correct args', () => {
const areaSquare = area.areaSquare(2.5)
expect(areaSquare).toBe(6.25)
})
it('with incorrect side length, expect throw', () => {
expect(() => area.areaSquare(-1)).toThrow()
})
})

describe('Testing areaTriangle calculations', () => {
it('with correct args', () => {
const areaTriangle = area.areaTriangle(1.66, 3.44)
expect(areaTriangle).toBe(2.8552)
})
it('with incorrect base and height, expect throw', () => {
expect(() => area.areaTriangle(-1, 1)).toThrow()
})
})

describe('Testing areaTriangleWithAllThreeSides calculations', () => {
it('with correct args', () => {
const areaTriangle = area.areaTriangleWithAllThreeSides(5, 6, 7)
expect(areaTriangle).toBe(14.7)
})
it('with incorrect sides, expect throw', () => {
expect(() => area.areaTriangleWithAllThreeSides(-1, 1, 10)).toThrow()
expect(() => area.areaTriangleWithAllThreeSides(1, 10, 12)).toThrow()
})
})

describe('Testing areaParallelogram calculations', () => {
it('with correct args', () => {
const areaParallelogram = area.areaParallelogram(1.66, 3.44)
expect(areaParallelogram).toBe(5.7104)
})
it('with incorrect base and height, expect throw', () => {
expect(() => area.areaParallelogram(-1, 1)).toThrow()
})
})

describe('Testing areaTrapezium calculations', () => {
it('with correct args', () => {
const areaTrapezium = area.areaTrapezium(1.66, 2.41, 4.1)
expect(areaTrapezium).toBe(8.3435)
})
it('with incorrect bases and height, expect throw', () => {
expect(() => area.areaTrapezium(-1, 1, 0)).toThrow()
})
})

describe('Testing areaCircle calculations', () => {
it('with correct args', () => {
const areaCircle = area.areaCircle(3.456)
expect(areaCircle).toBe(37.52298159254666)
})
it('with incorrect diagonal, expect throw', () => {
expect(() => area.areaCircle(-1)).toThrow()
})
})

describe('Testing areaRhombus calculations', () => {
it('with correct args', () => {
const areaRhombus = area.areaRhombus(2.5, 2.0)
expect(areaRhombus).toBe(2.5)
})
it('with incorrect diagonals, expect throw', () => {
expect(() => area.areaRhombus(7, -1)).toThrow()
})
})
22 changes: 22 additions & 0 deletions Maths/test/BinaryConvert.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { BinaryConvert } from '../BinaryConvert'

describe('BinaryConvert', () => {
it('should return the correct value', () => {
expect(BinaryConvert(4)).toBe(100)
})
it('should return the correct value', () => {
expect(BinaryConvert(12)).toBe(1100)
})
it('should return the correct value of the sum from two number', () => {
expect(BinaryConvert(12 + 2)).toBe(1110)
})
it('should return the correct value of the subtract from two number', () => {
expect(BinaryConvert(245 - 56)).toBe(10111101)
})
it('should return the correct value', () => {
expect(BinaryConvert(254)).toBe(11111110)
})
it('should return the correct value', () => {
expect(BinaryConvert(63483)).toBe(1111011111111011)
})
})
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;
6,465 changes: 6,465 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

21 changes: 21 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "typescript",
"version": "1.0.0",
"type": "module",
"description": "A repository for All algorithms implemented in Typescript (for educational purposes only)",
"main": "",
"devDependencies": {
"@types/jest": "^29.0.3",
"husky": "^8.0.1",
"jest": "^29.0.3",
"ts-jest": "^29.0.2",
"ts-node": "^10.9.1"
},
"scripts": {
"test": "jest --no-cache",
"style": "standard",
"prepare": "husky install"
},
"author": "TheAlgorithms",
"license": "MIT"
}
20 changes: 20 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {

/* Language and Environment */
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */

/* Modules */
"module": "CommonJS", /* Specify what module code is generated. */

/* Interop Constraints */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */

/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */
"strictFunctionTypes": true, /* Visit https://aka.ms/tsconfig to read more about this file */ /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}
}