Skip to content

Commit 67c6d83

Browse files
committed
feat: create submodules for problems and core concepts
1 parent 57c3d05 commit 67c6d83

File tree

14 files changed

+266
-11
lines changed

14 files changed

+266
-11
lines changed

src/core/sorting/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
## Sorting Algorithms
2+
3+
This directory contains implementations of various sorting algorithms in TypeScript. Each algorithm resides in its own subdirectory with a dedicated README file explaining its logic, complexity, and use cases.
4+
5+
### Included Algorithms
6+
7+
Here's a list of the currently implemented sorting algorithms:
8+
9+
* Bubble Sort - A simple sorting technique good for educational purposes but inefficient for large datasets.
10+
* Insertion Sort - Sorts by inserting elements into their correct positions within a sorted sub-array. Efficient for small to medium-sized datasets.
11+
* (Add entries for other implemented algorithms here)
12+
13+
### Understanding the Code
14+
15+
Each subdirectory contains the following:
16+
17+
* **index.ts:** The main implementation file for the specific sorting algorithm.
18+
* **README.md:** A detailed explanation of the algorithm's logic, complexity, and use cases.
19+
20+
This project aims to provide a clear and comprehensive understanding of various sorting algorithms in TypeScript. Feel free to explore the code and implement additional sorting techniques to expand the collection!

src/core/sorting/bubble/README.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
## Bubble Sort
2+
3+
Bubble Sort works by repeatedly stepping through the list to be sorted.
4+
In each pass, it compares adjacent elements and swaps them if they are in the wrong order.
5+
The larger element "bubbles" up towards the end of the list with each pass.
6+
7+
### Algorithm Breakdown
8+
9+
Here's a detailed breakdown:
10+
11+
1. **Initialization:**
12+
- Set a variable `swapped` to `false` (indicates if a swap occurred during the pass).
13+
- Iterate through the list using a loop for `n-1` times (since the last element is already in its final position after n-1 passes).
14+
15+
2. **Inner Loop:**
16+
- In each iteration of the inner loop, compare the current element (at index `i`) with the next element (at index `i+1`).
17+
- If the current element is greater than the next element, swap their positions and set `swapped` to `true`.
18+
19+
3. **Swapping:**
20+
- To swap elements, use a temporary variable to hold the current element.
21+
- Assign the next element's value to the current element's position.
22+
- Assign the temporary variable (holding the original current element's value) to the next element's position.
23+
24+
4. **Continue Until No Swaps:**
25+
- After the inner loop completes, check the value of `swapped`.
26+
- If `swapped` is `false`, it means no swaps occurred during the pass, indicating the list is sorted. Terminate the outer loop.
27+
- If `swapped` is `true`, repeat the outer loop for another pass, as elements might still be out of order.
28+
29+
### Time Complexity
30+
31+
Bubble Sort has a time complexity of O(n^2) in the worst and average cases. This means the number of comparisons (and potentially swaps) grows quadratically with the size of the input list (n). For larger datasets, this can be quite inefficient.
32+
33+
### Space Complexity
34+
35+
Bubble Sort has a space complexity of O(1). It only uses a constant amount of additional space (e.g., temporary variables for swapping) regardless of the input list size.
36+
37+
### Advantages
38+
39+
* **Simple to understand and implement:** Due to its straightforward logic, Bubble Sort is a great starting point for learning sorting algorithms.
40+
* **Easy to visualize:** The concept of elements bubbling up is easy to grasp and can be visualized for better understanding.
41+
42+
### Disadvantages
43+
44+
* **Inefficient for large datasets:** The O(n^2) time complexity makes Bubble Sort impractical for sorting massive amounts of data.
45+
46+
### Use Cases
47+
48+
* Bubble Sort is primarily used for educational purposes due to its simplicity.
49+
* It might be suitable for sorting very small datasets where efficiency is not a critical concern.
50+
51+
### Conclusion
52+
53+
Bubble Sort provides a valuable introduction to sorting algorithms. While not the most efficient option for real-world applications, understanding its logic is beneficial for grasping more complex sorting techniques.

src/core/sorting/bubble/index.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* ## Bubble Sort
3+
*
4+
* Sorts an array of numbers in ascending order using the Bubble Sort algorithm
5+
* with an optimization to terminate early if no swaps occur.
6+
*
7+
* Time complexity: O(n^2) (potentially less with early termination)
8+
* Space complexity: O(1) (in-place sorting)
9+
*
10+
* @param arr - The array of numbers to be sorted.
11+
* @returns A new array containing the sorted numbers.
12+
*/
13+
export const bubbleSort = (arr: number[]): number[] => {
14+
// Flag to track if any swaps occurred in the inner loop
15+
let swapped = true;
16+
17+
// Loop through each element of the array (outer loop)
18+
for (let outer = arr.length - 1; outer >= 0 && swapped; outer--) {
19+
swapped = false; // Reset flag before inner loop
20+
21+
// Loop through the unsorted part of the array (inner loop)
22+
for (let inner = 0; inner < outer; inner++) {
23+
// Compare adjacent elements and swap if they are in the wrong order
24+
if (arr[inner] > arr[inner + 1]) {
25+
[arr[inner], arr[inner + 1]] = [arr[inner + 1], arr[inner]];
26+
swapped = true; // Set flag if a swap occurred
27+
}
28+
}
29+
}
30+
// Return the sorted array
31+
return arr;
32+
};
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
## Insertion Sort
2+
3+
Insertion Sort works by dividing the input list into two parts: a sorted sub-array on the left and an unsorted sub-array on the right. In each pass, it takes an element from the unsorted sub-array and inserts it into its correct position within the sorted sub-array.
4+
5+
### Algorithm Breakdown
6+
7+
Here's a step-by-step explanation:
8+
9+
1. **Initialization:**
10+
- Consider the first element of the list to be the sorted sub-array (size 1).
11+
- Iterate through the list starting from the second element (index 1) onwards.
12+
13+
2. **Pick Unsorted Element:**
14+
- In each iteration, select the current element from the unsorted sub-array.
15+
16+
3. **Shift Sorted Elements:**
17+
- Iterate backwards through the sorted sub-array (starting from the element before the current position).
18+
- If the current element is less than the element at the current position in the sorted sub-array, shift the larger element one position to the right.
19+
20+
4. **Insert Element:**
21+
- Once a position in the sorted sub-array is greater than or equal to the current element, insert the current element at that position.
22+
23+
5. **Repeat Until Sorted:**
24+
- Continue iterating through the unsorted sub-array, picking elements and inserting them into their correct positions within the sorted sub-array.
25+
- By the end of the loop, the entire list becomes sorted.
26+
27+
### Time Complexity
28+
29+
The time complexity of Insertion Sort depends on the initial state of the data:
30+
31+
* **Best Case:** O(n) - If the data is already sorted, Insertion Sort only needs to iterate through the list once, resulting in linear time complexity.
32+
* **Average Case:** O(n^2) - For random or partially sorted data, Insertion Sort performs multiple shifts and comparisons, leading to quadratic time complexity.
33+
* **Worst Case:** O(n^2) - If the data is in reverse order, Insertion needs to make numerous shifts for each element, resulting in the same quadratic complexity as the average case.
34+
35+
### Space Complexity
36+
37+
Insertion Sort has a space complexity of O(1). It only uses a constant amount of additional space (e.g., temporary variables) regardless of the input list size.
38+
39+
### Advantages
40+
41+
* **Simple to understand and implement:** Similar to Bubble Sort, Insertion Sort's logic is easy to grasp, making it a good choice for beginners.
42+
* **Efficient for small to medium datasets:** In such cases, Insertion Sort's performance is comparable to more complex algorithms.
43+
* **Stable sorting:** Insertion Sort preserves the original order of elements with equal values.
44+
45+
### Disadvantages
46+
47+
* **Inefficient for large datasets:** The O(n^2) time complexity in the worst and average cases makes Insertion Sort less suitable for sorting massive amounts of data.
48+
49+
### Use Cases
50+
51+
* Insertion Sort is a good choice for sorting small to medium-sized datasets where simplicity and stability are important.
52+
* It can be useful in situations where frequent insertions into a partially sorted list occur.
53+
54+
### Conclusion
55+
56+
Insertion Sort offers a good balance between simplicity and efficiency for specific use cases. While not ideal for very large datasets, it provides a solid foundation for understanding sorting algorithms.
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/**
2+
* ## Insertion Sort
3+
*
4+
* Sorts an array of elements in ascending order using the Insertion Sort algorithm.
5+
*
6+
* @param arr - The array to be sorted.
7+
* @returns A new array containing the sorted elements.
8+
*
9+
* Time complexity: O(n^2) (average and worst case)
10+
* Space complexity: O(1) (in-place sorting)
11+
*/
12+
export const insertionSort = (arr: number[]): number[] => {
13+
// Loop through each element of the array (except the first element)
14+
for (let i = 1; i < arr.length; i++) {
15+
const current = arr[i];
16+
let j = i - 1;
17+
18+
// Shift elements of the sorted sub-array to make space for the current element
19+
while (j >= 0 && arr[j] > current) {
20+
arr[j + 1] = arr[j];
21+
j--;
22+
}
23+
24+
// Insert the current element at its correct position
25+
arr[j + 1] = current;
26+
}
27+
28+
// Return the sorted array
29+
return arr;
30+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { bench } from "vitest";
2+
import { bubbleSort } from "../bubble";
3+
import { insertionSort } from "../insertion";
4+
import { TEST_DATA } from "./test-data";
5+
6+
describe("Sorting Algorithms", () => {
7+
bench("Bubble Sort", () => {
8+
for (const { input } of TEST_DATA) {
9+
bubbleSort(input);
10+
}
11+
});
12+
13+
bench("Insertion Sort", () => {
14+
for (const { input } of TEST_DATA) {
15+
insertionSort(input);
16+
}
17+
});
18+
});
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { bubbleSort } from "../bubble";
2+
import { insertionSort } from "../insertion";
3+
import { TEST_DATA } from "./test-data";
4+
5+
describe("Sorting Algorithms", () => {
6+
describe("Bubble Sort", () => {
7+
it.each(TEST_DATA)("should sort the array correctly", ({ input, expected }) => {
8+
// Validate the test data
9+
expect(input).toBeDefined();
10+
expect(expected).toBeDefined();
11+
12+
// Run the function
13+
const result = bubbleSort(input);
14+
15+
// Validate the result
16+
expect(result).toBeDefined();
17+
expect(result).toEqual(expected);
18+
});
19+
});
20+
21+
describe("Insertion Sort", () => {
22+
it.each(TEST_DATA)("should sort the array correctly", ({ input, expected }) => {
23+
// Validate the test data
24+
expect(input).toBeDefined();
25+
expect(expected).toBeDefined();
26+
27+
// Run the function
28+
const result = insertionSort(input);
29+
30+
// Validate the result
31+
expect(result).toBeDefined();
32+
expect(result).toEqual(expected);
33+
});
34+
});
35+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { InputTestData } from "@typings/input-data";
2+
3+
export const TEST_DATA: InputTestData<number[], number[]>[] = [
4+
// Test cases with different array sizes
5+
{ input: [1], expected: [1] },
6+
{ input: [2, 1], expected: [1, 2] },
7+
{ input: [4, 3, 2, 1, 0], expected: [0, 1, 2, 3, 4] },
8+
{ input: [10, 5, 15, 2, 8], expected: [2, 5, 8, 10, 15] },
9+
{ input: [100, 50, 200, 1, 75], expected: [1, 50, 75, 100, 200] },
10+
11+
// Test cases with duplicate elements
12+
{ input: [3, 1, 2, 3, 1], expected: [1, 1, 2, 3, 3] },
13+
{ input: [5, 5, 5], expected: [5, 5, 5] },
14+
15+
// Test cases with negative numbers
16+
{ input: [-2, 5, 0, -1], expected: [-2, -1, 0, 5] },
17+
{ input: [-5, -1, -3, -4], expected: [-5, -4, -3, -1] },
18+
19+
// Test cases with empty array
20+
{ input: [], expected: [] },
21+
];

src/problems/1-two-sum/tests/index.bench.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { bench, describe } from "vitest";
1+
import { bench } from "vitest";
22

33
import { TWO_SUM } from "..";
44
import { TEST_DATA } from "./test-data";

src/problems/1-two-sum/tests/index.spec.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import { describe, expect, it } from "vitest";
2-
31
import { TWO_SUM } from "..";
42
import { TEST_DATA } from "./test-data";
53

0 commit comments

Comments
 (0)