Skip to content

Commit 6958645

Browse files
authored
Merge branch 'TheAlgorithms:master' into master
2 parents 4afaaae + 7e23e1e commit 6958645

34 files changed

+295
-41
lines changed

DIRECTORY.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
* [Is Even](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_even.ts)
3030
* [Is Leap Year](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_leap_year.ts)
3131
* [Is Odd](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_odd.ts)
32+
* [Is Palindrome](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_palindrome.ts)
3233
* [Is Square Free](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/is_square_free.ts)
3334
* [Lowest Common Multiple](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/lowest_common_multiple.ts)
3435
* [Perfect Square](https://github.com/TheAlgorithms/TypeScript/blob/HEAD/maths/perfect_square.ts)

Maths/CalculateMedian.ts

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/**
2+
* @function calculateMedian
3+
* @description This function will find the median value of an array of numbers.
4+
* @param {number[]} numbers Sorted array of numeric values.
5+
* @return {number} The median of input numbers.
6+
* @see https://en.wikipedia.org/wiki/Median
7+
* @example calculateMedian([1, 2, 4, 5, 8]) = 4
8+
* @example calculateMedian([1, 2, 4, 5]) = 3
9+
*/
10+
11+
export const calculateMedian = (numbers: number[]): number => {
12+
if (numbers.length < 1) {
13+
throw new TypeError("Input array must contain at least one number.");
14+
}
15+
16+
const totalNumbers = numbers.length;
17+
18+
if (totalNumbers % 2 === 0) {
19+
let index = totalNumbers / 2;
20+
return (numbers[index - 1] + numbers[index]) / 2;
21+
} else {
22+
let index = (totalNumbers + 1) / 2;
23+
return numbers[index - 1];
24+
}
25+
};

Maths/test/CalculateMedian.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { calculateMedian } from "../CalculateMedian";
2+
3+
describe("Tests for CalculateMedian", () => {
4+
it("should be a function", () => {
5+
expect(typeof calculateMedian).toEqual("function");
6+
});
7+
8+
it("should throw error for invalid input", () => {
9+
expect(() => calculateMedian([])).toThrowError(
10+
"Input array must contain at least one number."
11+
);
12+
});
13+
14+
it("should return the median of an array of numbers - even length", () => {
15+
const medianFunction = calculateMedian([1, 2, 3, 4]);
16+
expect(medianFunction).toBe(2.5);
17+
});
18+
19+
it("should return the median of an array of numbers - odd length", () => {
20+
const medianFunction = calculateMedian([1, 2, 3, 4, 6, 8, 9]);
21+
expect(medianFunction).toBe(4);
22+
});
23+
});
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { DoublyLinkedList } from "../doubly_linked_list";
2+
import { testLinkedList } from "./linked_list";
3+
4+
describe("DoublyLinkedList", () => {
5+
testLinkedList(DoublyLinkedList);
6+
7+
it("should reverse the list", () => {
8+
const list: DoublyLinkedList<number> = new DoublyLinkedList<number>();
9+
10+
list.append(1);
11+
list.append(2);
12+
list.append(3);
13+
list.reverse();
14+
15+
expect(list.get(0)).toBe(3);
16+
expect(list.get(1)).toBe(2);
17+
});
18+
19+
it("should return null for reverse when list is empty", () => {
20+
const list: DoublyLinkedList<number> = new DoublyLinkedList<number>();
21+
22+
expect(list.reverse()).toBeNull();
23+
});
24+
});

data_structures/hashing/hash_map.ts renamed to data_structures/map/hash_map.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Map } from "../map";
1+
import { Map } from "./map";
22

33
/**
44
* Represents a hash map.

data_structures/map.ts renamed to data_structures/map/map.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { HashMapEntry } from "./hashing/hash_map";
1+
import { HashMapEntry } from "./hash_map";
22

33
/**
44
* This interface is a representation of the Map data structure.

data_structures/hashing/test/hash_map.test.ts renamed to data_structures/map/test/hash_map.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { HashMap } from "../hash_map";
1+
import { HashMap } from "../../map/hash_map";
22

33
describe("Hash Map", () => {
44
let hashMap: HashMap<string, number>;
File renamed without changes.
+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
/**
2+
* Circular Queue implementation using array.
3+
*
4+
* @template T The type of the elements in the queue.
5+
* @param {T[]} queue The array that holds the elements of the queue.
6+
* @param {number} frontIndex The index of the front element of the queue.
7+
* @param {number} rearIndex The index of the rear element of the queue.
8+
* @param {number} size The size of the queue.
9+
*/
10+
export class CircularQueue<T> {
11+
private queue: T[];
12+
private frontIndex: number;
13+
private rearIndex: number;
14+
private size: number;
15+
16+
constructor(size: number) {
17+
this.queue = new Array(size);
18+
this.frontIndex = -1;
19+
this.rearIndex = -1;
20+
this.size = size;
21+
}
22+
23+
/**
24+
* Adds an item to the queue.
25+
*
26+
* @param item The item being added to the queue.
27+
*/
28+
enqueue(item: T): void {
29+
if (
30+
(this.frontIndex == 0 && this.rearIndex == this.size - 1) ||
31+
this.rearIndex == (this.frontIndex - 1) % (this.size - 1)
32+
) {
33+
throw new Error("Queue is full");
34+
} else if (this.frontIndex == -1) {
35+
this.frontIndex = 0;
36+
this.rearIndex = 0;
37+
this.queue[this.rearIndex] = item;
38+
} else if (this.rearIndex == this.size - 1 && this.frontIndex != 0) {
39+
this.rearIndex = 0;
40+
this.queue[this.rearIndex] = item;
41+
} else {
42+
this.rearIndex++;
43+
this.queue[this.rearIndex] = item;
44+
}
45+
}
46+
47+
/**
48+
* Removes an item from the queue and returns it.
49+
*
50+
* @throws Queue Underflow if the queue is empty.
51+
* @returns The item that was removed from the queue.
52+
*/
53+
dequeue(): T | undefined {
54+
if (this.frontIndex == -1) {
55+
throw new Error("Queue is empty");
56+
}
57+
58+
const item = this.queue[this.frontIndex];
59+
if (this.frontIndex == this.rearIndex) {
60+
this.frontIndex = -1;
61+
this.rearIndex = -1;
62+
} else if (this.frontIndex == this.size - 1) {
63+
this.frontIndex = 0;
64+
} else {
65+
this.frontIndex++;
66+
}
67+
68+
return item;
69+
}
70+
71+
/**
72+
* Returns the item at the front of the queue.
73+
*
74+
* @returns The item at the front of the queue or null if the queue is empty.
75+
*/
76+
peek(): T | null | undefined {
77+
if (this.frontIndex == -1) {
78+
return null;
79+
}
80+
81+
return this.queue[this.frontIndex];
82+
}
83+
84+
/**
85+
* Checks if the queue is empty.
86+
*
87+
* @returns {boolean} Whether the queue is empty or not.
88+
*/
89+
isEmpty(): boolean {
90+
return this.frontIndex == -1;
91+
}
92+
93+
/**
94+
* Returns the number of items in the queue.
95+
*
96+
* @returns {number} The number of items in the queue.
97+
*/
98+
length(): number {
99+
if (this.frontIndex == -1) {
100+
return 0;
101+
}
102+
103+
if (this.rearIndex >= this.frontIndex) {
104+
return this.rearIndex - this.frontIndex + 1;
105+
}
106+
107+
return this.size - (this.frontIndex - this.rearIndex - 1);
108+
}
109+
}
File renamed without changes.

data_structures/stack_queue.ts renamed to data_structures/queue/stack_queue.ts

+9-10
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
/**
2-
* A Stack Based Queue Implementation.
3-
* The Queue data structure which follows the FIFO (First in First Out) rule.
4-
* The dequeue operation in a normal stack based queue would be o(n), as the entire has to be shifted
5-
* With the help of two stacks, the time complexity of this can be brought down to amortized-O(1).
6-
* Here, one stack acts as an Enqueue stack where elements are added.
2+
* A Stack Based Queue Implementation.
3+
* The Queue data structure which follows the FIFO (First in First Out) rule.
4+
* The dequeue operation in a normal stack based queue would be o(n), as the entire has to be shifted
5+
* With the help of two stacks, the time complexity of this can be brought down to amortized-O(1).
6+
* Here, one stack acts as an Enqueue stack where elements are added.
77
* The other stack acts as a dequeue stack which helps in dequeuing the elements
88
*/
99

10-
import { Queue } from './queue';
11-
import { Stack } from './stack';
12-
13-
export class StackQueue<T> implements Queue<T>{
10+
import { Stack } from "../stack/stack";
11+
import { Queue } from "./queue";
1412

13+
export class StackQueue<T> implements Queue<T> {
1514
private enqueueStack: Stack<T> = new Stack<T>();
1615
private dequeueStack: Stack<T> = new Stack<T>();
1716

@@ -44,7 +43,7 @@ export class StackQueue<T> implements Queue<T>{
4443

4544
/**
4645
* Shifts the elements from the enqueueStack to the dequeueStack
47-
* In the worst case, all the elements from the enqueue stack needs to shifted, which needs O(n) time.
46+
* In the worst case, all the elements from the enqueue stack needs to shifted, which needs O(n) time.
4847
* However, after the shift, elements can de dequeued at O(1).
4948
* This helps in dequeuing the elements in amortized O(1) time.
5049
*/
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
import { CircularQueue } from "../circular_queue";
2+
3+
describe("Circular Queue", () => {
4+
let queue: CircularQueue<number>;
5+
6+
beforeEach(() => {
7+
queue = new CircularQueue(5);
8+
});
9+
10+
it("should enqueue an element", () => {
11+
queue.enqueue(1);
12+
13+
expect(queue.peek()).toBe(1);
14+
});
15+
16+
it("should throw an error on enqueue when queue is full", () => {
17+
queue.enqueue(1);
18+
queue.enqueue(2);
19+
queue.enqueue(3);
20+
queue.enqueue(4);
21+
queue.enqueue(5);
22+
23+
expect(() => queue.enqueue(6)).toThrowError("Queue is full");
24+
});
25+
26+
it("should dequeue an element", () => {
27+
queue.enqueue(1);
28+
queue.enqueue(2);
29+
30+
expect(queue.dequeue()).toBe(1);
31+
});
32+
33+
it("should throw an error on dequeue when queue is empty", () => {
34+
expect(() => queue.dequeue()).toThrowError("Queue is empty");
35+
});
36+
37+
it("should peek an element", () => {
38+
queue.enqueue(1);
39+
queue.enqueue(2);
40+
41+
expect(queue.peek()).toBe(1);
42+
});
43+
44+
it("should return null on peek when queue is empty", () => {
45+
expect(queue.peek()).toBeNull();
46+
});
47+
48+
it("should return true on isEmpty when queue is empty", () => {
49+
expect(queue.isEmpty()).toBeTruthy();
50+
});
51+
52+
it("should return false on isEmpty when queue is not empty", () => {
53+
queue.enqueue(1);
54+
55+
expect(queue.isEmpty()).toBeFalsy();
56+
});
57+
58+
it("should return the correct length", () => {
59+
queue.enqueue(1);
60+
queue.enqueue(2);
61+
queue.enqueue(3);
62+
63+
expect(queue.length()).toBe(3);
64+
});
65+
});

data_structures/test/queue.ts renamed to data_structures/queue/test/queue.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Queue } from '../queue';
2+
23
type QueueConstructor = new <T>() => Queue<T>
34
export function testQueue(Queue: QueueConstructor) {
45
it("enqueue should add a new element to the queue", () => {

data_structures/hashing/hash_map_set.ts renamed to data_structures/set/hash_map_set.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { Map } from "../map";
2-
import { MapSet } from "../map_set";
3-
import { HashMap } from "./hash_map";
1+
import { Map } from "../map/map";
2+
import { HashMap } from "../map/hash_map";
3+
import { MapSet } from "./map_set";
44

55
/**
66
* This class is a representation of the Set data structure based on a hash map.
File renamed without changes.
File renamed without changes.

data_structures/linked_list_stack.ts renamed to data_structures/stack/linked_list_stack.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SinglyLinkedList } from "./singly_linked_list";
1+
import { SinglyLinkedList } from "../list/singly_linked_list";
22

33
/**
44
* This is an implementation of a stack, based on a linked list.
File renamed without changes.

data_structures/test/doubly_linked_list.test.ts

-24
This file was deleted.

maths/is_palindrome.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* A function to see if a number is a palindrome.
3+
* Note that if the reversed number is larger than MAX_SAFE_INTEGER, rounding errors may occur and the result may be incorrect.
4+
* Time Complexity: O(log(n))
5+
*
6+
* @param number The input number.
7+
* @return {boolean} Wether the number is a Palindrome or not.
8+
*/
9+
export const IsPalindrome = (number: number): boolean => {
10+
if (number < 0 || (number % 10 === 0 && number !== 0)) {
11+
return false;
12+
}
13+
14+
let reversed: number = 0;
15+
while (number > reversed) {
16+
reversed = reversed * 10 + (number % 10);
17+
number = Math.floor(number / 10);
18+
}
19+
20+
return number === reversed || number === Math.floor(reversed / 10);
21+
};

maths/test/is_palindrome.test.ts

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { IsPalindrome } from "../is_palindrome";
2+
3+
describe("IsPalindrome", () => {
4+
test.each([[5, true], [1234, false], [12321, true], [31343, false]])(
5+
"correct output for %i",
6+
(nums, expected) => {
7+
expect(IsPalindrome(nums)).toBe(expected);
8+
},
9+
);
10+
});

0 commit comments

Comments
 (0)