Skip to content

Commit 349e06b

Browse files
Merge branch 'master' into floyd_warshall-into-graph
2 parents b617c80 + ef209df commit 349e06b

22 files changed

+865
-332
lines changed

.github/workflows/awesome_workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ jobs:
6161
submodules: true
6262
- run: |
6363
cmake -B ./build -S .
64-
cmake --build build
64+
cmake --build build --parallel 4
6565
- name: Label on PR fail
6666
uses: actions/github-script@v6
6767
if: ${{ failure() && matrix.os == 'ubuntu-latest' && github.event_name == 'pull_request' }}

.github/workflows/gh-pages.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ jobs:
2525
clean: false
2626
- name: Move & Commit files
2727
run: |
28-
git config --global user.name github-actions
29-
git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com'
28+
git config --global user.name "$GITHUB_ACTOR"
29+
git config --global user.email "$[email protected]"
3030
git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY
3131
rm -rf d* && rm *.html && rm *.svg && rm *.map && rm *.md5 && rm *.png && rm *.js && rm *.css
3232
git add .

DIRECTORY.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
* [Searching Of Element In Dynamic Array](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/searching_of_element_in_dynamic_array.cpp)
120120
* [Shortest Common Supersequence](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/shortest_common_supersequence.cpp)
121121
* [Subset Sum](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/subset_sum.cpp)
122+
* [Trapped Rainwater](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/trapped_rainwater.cpp)
122123
* [Tree Height](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/tree_height.cpp)
123124
* [Word Break](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/dynamic_programming/word_break.cpp)
124125

@@ -161,7 +162,7 @@
161162
* [Boruvkas Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/boruvkas_minimum_spanning_tree.cpp)
162163
* [Dijkstra](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/dijkstra.cpp)
163164
* [Huffman](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/huffman.cpp)
164-
* [Jumpgame](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jumpgame.cpp)
165+
* [Jump Game](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/jump_game.cpp)
165166
* [Knapsack](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/knapsack.cpp)
166167
* [Kruskals Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/kruskals_minimum_spanning_tree.cpp)
167168
* [Prims Minimum Spanning Tree](https://github.com/TheAlgorithms/C-Plus-Plus/blob/HEAD/greedy_algorithms/prims_minimum_spanning_tree.cpp)
Lines changed: 166 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,179 @@
1-
#include <iostream>
1+
#include <cassert> /// For std::assert
2+
#include <iostream> /// For std::cout
3+
#include <memory> /// For std::unique_ptr
4+
#include <stdexcept> /// For std::out_of_range
25

3-
int *stack;
4-
int stack_idx = 0, stack_size;
6+
/**
7+
* @namespace
8+
* @brief data_structures
9+
*/
10+
namespace data_structures {
11+
/**
12+
* @brief Class representation of a stack
13+
* @tparam T The type of the elements in the stack
14+
*/
15+
template <typename T>
16+
class Stack {
17+
private:
18+
std::unique_ptr<T[]> stack; ///< Smart pointer to the stack array
19+
int stackSize; ///< Maximum size of the stack
20+
int stackIndex; ///< Index pointing to the top element of the stack
521

6-
void push(int x) {
7-
if (stack_idx == stack_size) {
8-
std::cout << "\nOverflow";
9-
} else {
10-
stack[stack_idx++] = x;
22+
public:
23+
/**
24+
* @brief Constructs a new Stack object
25+
*
26+
* @param size Maximum size of the stack
27+
*/
28+
Stack(int size) : stackSize(size), stackIndex(-1), stack(new T[size]) {}
29+
30+
/**
31+
* @brief Checks if the stack is full
32+
*
33+
* @return true if the stack is full, false otherwise
34+
*/
35+
bool full() const { return stackIndex == stackSize - 1; }
36+
37+
/**
38+
* @brief Checks if the stack is empty
39+
* @return true if the stack is empty, false otherwise
40+
*/
41+
bool empty() const { return stackIndex == -1; }
42+
43+
/**
44+
* @brief Pushes an element onto the stack
45+
*
46+
* @param element Element to push onto the stack
47+
*/
48+
void push(T element) {
49+
if (full()) {
50+
throw std::out_of_range("Stack overflow");
51+
} else {
52+
stack[++stackIndex] = element;
53+
}
1154
}
12-
}
1355

14-
void pop() {
15-
if (stack_idx == 0) {
16-
std::cout << "\nUnderflow";
17-
} else {
18-
std::cout << "\n" << stack[--stack_idx] << " deleted";
56+
/**
57+
* @brief Pops an element from the stack
58+
*
59+
* @return The popped element
60+
* @throws std::out_of_range if the stack is empty
61+
*/
62+
T pop() {
63+
if (empty()) {
64+
throw std::out_of_range("Stack underflow");
65+
}
66+
return stack[stackIndex--];
67+
}
68+
69+
/**
70+
* @brief Displays all elements in the stack
71+
*/
72+
void show() const {
73+
for (int i = 0; i <= stackIndex; i++) {
74+
std::cout << stack[i] << "\n";
75+
}
1976
}
20-
}
2177

22-
void show() {
23-
for (int i = 0; i < stack_idx; i++) {
24-
std::cout << stack[i] << "\n";
78+
/**
79+
* @brief Displays the topmost element of the stack
80+
*
81+
* @return The topmost element of the stack
82+
* @throws std::out_of_range if the stack is empty
83+
*/
84+
T topmost() const {
85+
if (empty()) {
86+
throw std::out_of_range("Stack underflow");
87+
}
88+
return stack[stackIndex];
2589
}
26-
}
2790

28-
void topmost() { std::cout << "\nTopmost element: " << stack[stack_idx - 1]; }
29-
void bottom() { std::cout << "\nBottom element: " << stack[0]; } // If we need access to first element without using pop command
30-
int main() {
31-
std::cout << "\nEnter stack_size of stack : ";
32-
std::cin >> stack_size;
33-
stack = new int[stack_size];
34-
int ch, x;
35-
do {
36-
std::cout << "\n0. Exit";
37-
std::cout << "\n1. Push";
38-
std::cout << "\n2. Pop";
39-
std::cout << "\n3. Print";
40-
std::cout << "\n4. Print topmost element:";
41-
std::cout << "\n5. Print Bottom element:";
42-
std::cout << "\nEnter Your Choice : ";
43-
std::cin >> ch;
44-
if (ch == 1) {
45-
std::cout << "\nInsert : ";
46-
std::cin >> x;
47-
push(x);
48-
} else if (ch == 2) {
49-
pop();
50-
} else if (ch == 3) {
51-
show();
52-
} else if (ch == 4) {
53-
topmost();
54-
} else if(ch == 5) {
55-
bottom();
91+
/**
92+
* @brief Displays the bottom element of the stack
93+
*
94+
* @return The bottom element of the stack
95+
* @throws std::out_of_range if the stack is empty
96+
*/
97+
T bottom() const {
98+
if (empty()) {
99+
throw std::out_of_range("Stack underflow");
56100
}
57-
} while (ch != 0);
101+
return stack[0];
102+
}
103+
};
104+
} // namespace data_structures
105+
106+
/**
107+
* @brief Self-test implementations
108+
* @returns void
109+
*/
110+
static void test() {
111+
data_structures::Stack<int> stack(5);
112+
113+
// Test empty and full operations
114+
assert(stack.empty());
115+
assert(!stack.full());
58116

59-
delete[] stack;
117+
// Test pushing elements and checking topmost
118+
stack.push(10);
119+
assert(stack.topmost() == 10);
60120

121+
stack.push(20);
122+
assert(stack.topmost() == 20);
123+
124+
stack.push(30);
125+
stack.push(40);
126+
stack.push(50);
127+
assert(stack.full());
128+
129+
// Test stack overflow
130+
try {
131+
stack.push(60);
132+
} catch (const std::out_of_range& e) {
133+
assert(std::string(e.what()) == "Stack overflow");
134+
}
135+
136+
// Test popping elements
137+
assert(stack.pop() == 50);
138+
assert(stack.pop() == 40);
139+
assert(stack.pop() == 30);
140+
141+
// Check topmost and bottom elements
142+
assert(stack.topmost() == 20);
143+
assert(stack.bottom() == 10);
144+
145+
assert(stack.pop() == 20);
146+
assert(stack.pop() == 10);
147+
148+
assert(stack.empty());
149+
assert(!stack.full());
150+
151+
// Test stack underflow
152+
try {
153+
stack.pop();
154+
} catch (const std::out_of_range& e) {
155+
assert(std::string(e.what()) == "Stack underflow");
156+
}
157+
158+
try {
159+
stack.topmost();
160+
} catch (const std::out_of_range& e) {
161+
assert(std::string(e.what()) == "Stack underflow");
162+
}
163+
164+
try {
165+
stack.bottom();
166+
} catch (const std::out_of_range& e) {
167+
assert(std::string(e.what()) == "Stack underflow");
168+
}
169+
}
170+
171+
/**
172+
* @brief Main function
173+
* @returns 0 on exit
174+
*/
175+
int main() {
176+
test(); // run self-test implementations
177+
std::cout << "All tests passed!" << std::endl;
61178
return 0;
62179
}
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
* @file
3+
* @brief Implementation of the [Trapped Rainwater
4+
* Problem](https://www.geeksforgeeks.org/trapping-rain-water/)
5+
* @details
6+
* This implementation calculates the amount of rainwater that can be trapped
7+
* between walls represented by an array of heights.
8+
* @author [SOZEL](https://github.com/TruongNhanNguyen)
9+
*/
10+
11+
#include <algorithm> /// For std::min and std::max
12+
#include <cassert> /// For assert
13+
#include <cstddef> /// For std::size_t
14+
#include <cstdint> /// For integral typedefs
15+
#include <vector> /// For std::vector
16+
17+
/*
18+
* @namespace
19+
* @brief Dynamic Programming Algorithms
20+
*/
21+
namespace dynamic_programming {
22+
/**
23+
* @brief Function to calculate the trapped rainwater
24+
* @param heights Array representing the heights of walls
25+
* @return The amount of trapped rainwater
26+
*/
27+
uint32_t trappedRainwater(const std::vector<uint32_t>& heights) {
28+
std::size_t n = heights.size();
29+
if (n <= 2)
30+
return 0; // No water can be trapped with less than 3 walls
31+
32+
std::vector<uint32_t> leftMax(n), rightMax(n);
33+
34+
// Calculate the maximum height of wall to the left of each wall
35+
leftMax[0] = heights[0];
36+
for (std::size_t i = 1; i < n; ++i) {
37+
leftMax[i] = std::max(leftMax[i - 1], heights[i]);
38+
}
39+
40+
// Calculate the maximum height of wall to the right of each wall
41+
rightMax[n - 1] = heights[n - 1];
42+
for (std::size_t i = n - 2; i < n; --i) {
43+
rightMax[i] = std::max(rightMax[i + 1], heights[i]);
44+
}
45+
46+
// Calculate the trapped rainwater between walls
47+
uint32_t trappedWater = 0;
48+
for (std::size_t i = 0; i < n; ++i) {
49+
trappedWater +=
50+
std::max(0u, std::min(leftMax[i], rightMax[i]) - heights[i]);
51+
}
52+
53+
return trappedWater;
54+
}
55+
56+
} // namespace dynamic_programming
57+
58+
/**
59+
* @brief Self-test implementations
60+
* @returns void
61+
*/
62+
static void test() {
63+
std::vector<uint32_t> test_basic = {0, 1, 0, 2, 1, 0, 1, 3, 2, 1, 2, 1};
64+
assert(dynamic_programming::trappedRainwater(test_basic) == 6);
65+
66+
std::vector<uint32_t> test_peak_under_water = {3, 0, 2, 0, 4};
67+
assert(dynamic_programming::trappedRainwater(test_peak_under_water) == 7);
68+
69+
std::vector<uint32_t> test_bucket = {5, 1, 5};
70+
assert(dynamic_programming::trappedRainwater(test_bucket) == 4);
71+
72+
std::vector<uint32_t> test_skewed_bucket = {4, 1, 5};
73+
assert(dynamic_programming::trappedRainwater(test_skewed_bucket) == 3);
74+
75+
std::vector<uint32_t> test_empty = {};
76+
assert(dynamic_programming::trappedRainwater(test_empty) == 0);
77+
78+
std::vector<uint32_t> test_flat = {0, 0, 0, 0, 0};
79+
assert(dynamic_programming::trappedRainwater(test_flat) == 0);
80+
81+
std::vector<uint32_t> test_no_trapped_water = {1, 1, 2, 4, 0, 0, 0};
82+
assert(dynamic_programming::trappedRainwater(test_no_trapped_water) == 0);
83+
84+
std::vector<uint32_t> test_single_elevation = {5};
85+
assert(dynamic_programming::trappedRainwater(test_single_elevation) == 0);
86+
87+
std::vector<uint32_t> test_two_point_elevation = {5, 1};
88+
assert(dynamic_programming::trappedRainwater(test_two_point_elevation) ==
89+
0);
90+
91+
std::vector<uint32_t> test_large_elevation_map_difference = {5, 1, 6, 1,
92+
7, 1, 8};
93+
assert(dynamic_programming::trappedRainwater(
94+
test_large_elevation_map_difference) == 15);
95+
}
96+
97+
/**
98+
* @brief Main function
99+
* @returns 0 on exit
100+
*/
101+
int main() {
102+
test(); // run self-test implementations
103+
return 0;
104+
}

0 commit comments

Comments
 (0)