Skip to content

Commit 921a4a9

Browse files
committed
fix tests
1 parent 7477384 commit 921a4a9

5 files changed

Lines changed: 175 additions & 23 deletions

File tree

20 KB
Binary file not shown.

src/3_Stack_Queue/min_in_stack.cpp

Lines changed: 154 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include <iostream>
3232
#include <optional>
33+
#include <cassert>
3334
#include <stack>
3435
#include <string>
3536

@@ -117,28 +118,179 @@ struct TestRunner {
117118
// Test cases to ensure correctness of StackWithMin operations.
118119
void test() {
119120
TestRunner runner;
121+
122+
// 1) Empty stack behavior
123+
{
124+
StackWithMin<int> stack;
125+
runner.expectEqual(stack.min(), std::optional<int>{}, "min on empty");
126+
runner.expectEqual(stack.top(), std::optional<int>{}, "top on empty");
127+
128+
// If pop() is supposed to be safe on empty, this should not crash.
129+
stack.pop();
130+
runner.expectEqual(stack.min(), std::optional<int>{}, "min still empty after pop on empty");
131+
runner.expectEqual(stack.top(), std::optional<int>{}, "top still empty after pop on empty");
132+
}
133+
134+
// 2) Basic push/pop + popping all the way to empty
120135
{
121136
StackWithMin<int> stack;
122137
stack.push(10);
123138
stack.push(5);
124139
stack.push(2);
125140
runner.expectEqual(stack.min(), std::optional<int>(2), "min after push");
126141
runner.expectEqual(stack.top(), std::optional<int>(2), "top after push");
142+
127143
stack.pop();
128144
runner.expectEqual(stack.min(), std::optional<int>(5), "min after pop");
129145
runner.expectEqual(stack.top(), std::optional<int>(5), "top after pop");
146+
147+
stack.pop(); // removes 5
148+
runner.expectEqual(stack.min(), std::optional<int>(10), "min after pop to single");
149+
runner.expectEqual(stack.top(), std::optional<int>(10), "top after pop to single");
150+
151+
stack.pop(); // removes 10 -> empty
152+
runner.expectEqual(stack.min(), std::optional<int>{}, "min after popping to empty");
153+
runner.expectEqual(stack.top(), std::optional<int>{}, "top after popping to empty");
130154
}
155+
156+
// 3) Negative values + restore
131157
{
132158
StackWithMin<int> stack;
133159
stack.push(-1);
134160
stack.push(7);
135161
stack.push(-2);
136-
runner.expectEqual(stack.min(), std::optional<int>(-2),
137-
"min with negative");
162+
runner.expectEqual(stack.min(), std::optional<int>(-2), "min with negative");
163+
138164
stack.pop();
139165
runner.expectEqual(stack.min(), std::optional<int>(-1), "min restored");
140166
runner.expectEqual(stack.top(), std::optional<int>(7), "top restored");
141167
}
168+
169+
// 4) Duplicate minimums (min should persist until ALL mins are popped)
170+
{
171+
StackWithMin<int> stack;
172+
stack.push(3);
173+
stack.push(1);
174+
stack.push(1);
175+
stack.push(2);
176+
177+
runner.expectEqual(stack.min(), std::optional<int>(1), "min with duplicates");
178+
runner.expectEqual(stack.top(), std::optional<int>(2), "top with duplicates");
179+
180+
stack.pop(); // pop 2
181+
runner.expectEqual(stack.min(), std::optional<int>(1), "min after popping non-min");
182+
runner.expectEqual(stack.top(), std::optional<int>(1), "top after popping non-min");
183+
184+
stack.pop(); // pop 1 (still another 1 remains)
185+
runner.expectEqual(stack.min(), std::optional<int>(1), "min remains after popping one duplicate min");
186+
runner.expectEqual(stack.top(), std::optional<int>(1), "top now duplicate min");
187+
188+
stack.pop(); // pop last 1, min should restore to 3
189+
runner.expectEqual(stack.min(), std::optional<int>(3), "min restores after all duplicate mins removed");
190+
runner.expectEqual(stack.top(), std::optional<int>(3), "top restores after all duplicate mins removed");
191+
}
192+
193+
// 5) All equal values
194+
{
195+
StackWithMin<int> stack;
196+
stack.push(4);
197+
stack.push(4);
198+
stack.push(4);
199+
200+
runner.expectEqual(stack.min(), std::optional<int>(4), "min with all equal");
201+
runner.expectEqual(stack.top(), std::optional<int>(4), "top with all equal");
202+
203+
stack.pop();
204+
runner.expectEqual(stack.min(), std::optional<int>(4), "min after pop with all equal");
205+
stack.pop();
206+
runner.expectEqual(stack.min(), std::optional<int>(4), "min after second pop with all equal");
207+
stack.pop();
208+
runner.expectEqual(stack.min(), std::optional<int>{}, "min after popping all equal to empty");
209+
}
210+
211+
// 6) Monotonic increasing: min should stay first element until empty
212+
{
213+
StackWithMin<int> stack;
214+
stack.push(1);
215+
stack.push(2);
216+
stack.push(3);
217+
stack.push(4);
218+
219+
runner.expectEqual(stack.min(), std::optional<int>(1), "min in increasing sequence");
220+
stack.pop(); // 4
221+
runner.expectEqual(stack.min(), std::optional<int>(1), "min after pop in increasing sequence");
222+
stack.pop(); // 3
223+
runner.expectEqual(stack.min(), std::optional<int>(1), "min after second pop in increasing sequence");
224+
}
225+
226+
// 7) Monotonic decreasing: min updates each push, restores each pop
227+
{
228+
StackWithMin<int> stack;
229+
stack.push(4);
230+
runner.expectEqual(stack.min(), std::optional<int>(4), "min after push 4 (decreasing)");
231+
232+
stack.push(3);
233+
runner.expectEqual(stack.min(), std::optional<int>(3), "min after push 3 (decreasing)");
234+
235+
stack.push(2);
236+
runner.expectEqual(stack.min(), std::optional<int>(2), "min after push 2 (decreasing)");
237+
238+
stack.push(1);
239+
runner.expectEqual(stack.min(), std::optional<int>(1), "min after push 1 (decreasing)");
240+
241+
stack.pop(); // 1
242+
runner.expectEqual(stack.min(), std::optional<int>(2), "min restores to 2 after popping 1");
243+
stack.pop(); // 2
244+
runner.expectEqual(stack.min(), std::optional<int>(3), "min restores to 3 after popping 2");
245+
stack.pop(); // 3
246+
runner.expectEqual(stack.min(), std::optional<int>(4), "min restores to 4 after popping 3");
247+
}
248+
249+
// 8) Longer deterministic sequence: validate min after every push and pop
250+
{
251+
StackWithMin<int> stack;
252+
253+
// Push a sequence where the min changes a few times.
254+
// Values: 50, 49, ..., 26, 0, 25, 24, ..., 1
255+
int expectedMin = 1e9;
256+
for (int i = 50; i >= 26; --i) {
257+
stack.push(i);
258+
expectedMin = std::min(expectedMin, i);
259+
runner.expectEqual(stack.min(), std::optional<int>(expectedMin), "min after push in long sequence (part 1)");
260+
}
261+
262+
stack.push(0);
263+
expectedMin = 0;
264+
runner.expectEqual(stack.min(), std::optional<int>(0), "min after pushing 0 in long sequence");
265+
266+
for (int i = 25; i >= 1; --i) {
267+
stack.push(i);
268+
runner.expectEqual(stack.min(), std::optional<int>(0), "min stays 0 in long sequence (part 2)");
269+
}
270+
271+
// Now pop everything above 0; min should stay 0 until 0 is popped.
272+
for (int i = 1; i <= 25; ++i) {
273+
stack.pop();
274+
runner.expectEqual(stack.min(), std::optional<int>(0), "min stays 0 while popping down to 0");
275+
}
276+
277+
// Pop 0; min should restore to 26 (the smallest remaining from 26..50)
278+
stack.pop();
279+
runner.expectEqual(stack.min(), std::optional<int>(26), "min restores after popping 0");
280+
281+
// Pop remaining; min should climb upward as we remove 26,27,...
282+
for (int expected = 27; expected <= 50; ++expected) {
283+
stack.pop();
284+
runner.expectEqual(stack.min(),
285+
(expected <= 50 ? std::optional<int>(expected) : std::optional<int>{}),
286+
"min after popping in long sequence tail");
287+
}
288+
289+
// After all popped, empty
290+
runner.expectEqual(stack.min(), std::optional<int>{}, "min empty at end of long sequence");
291+
runner.expectEqual(stack.top(), std::optional<int>{}, "top empty at end of long sequence");
292+
}
293+
142294
runner.summary();
143295
}
144296

src/8_Trees/convert_to_list.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,6 @@ class TreeWithVector : public BinaryTree {
9595
}
9696
};
9797

98-
// Simple test function using assertions
99-
void testTreeWithVector(TestRunner &runner, const TreeWithVector &tree,
100-
const std::vector<int> &inorderExpected,
101-
const std::vector<int> &preorderExpected) {
102-
runner.expectEqual(tree.inorder(), inorderExpected, "inorder traversal");
103-
runner.expectEqual(tree.preorder(), preorderExpected, "preorder traversal");
104-
}
105-
10698
namespace {
10799
struct TestRunner {
108100
int total = 0;
@@ -140,6 +132,14 @@ struct TestRunner {
140132
};
141133
} // namespace
142134

135+
// Simple test function using assertions
136+
void testTreeWithVector(TestRunner &runner, const TreeWithVector &tree,
137+
const std::vector<int> &inorderExpected,
138+
const std::vector<int> &preorderExpected) {
139+
runner.expectEqual(tree.inorder(), inorderExpected, "inorder traversal");
140+
runner.expectEqual(tree.preorder(), preorderExpected, "preorder traversal");
141+
}
142+
143143
int main() {
144144
TestRunner runner;
145145
testTreeWithVector(runner,

src/8_Trees/depth.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,6 @@ class TreeWithDepth : public BinaryTree {
5757
}
5858
};
5959

60-
// Test function to verify that the computed depth matches the expected depth.
61-
void testTreeWithDepth(TestRunner &runner, const TreeWithDepth &tree,
62-
unsigned int expectedDepth, const std::string &label) {
63-
runner.expectEqual(tree.depth(), expectedDepth, label);
64-
}
65-
6660
namespace {
6761
struct TestRunner {
6862
int total = 0;
@@ -87,6 +81,12 @@ struct TestRunner {
8781
};
8882
} // namespace
8983

84+
// Test function to verify that the computed depth matches the expected depth.
85+
void testTreeWithDepth(TestRunner &runner, const TreeWithDepth &tree,
86+
unsigned int expectedDepth, const std::string &label) {
87+
runner.expectEqual(tree.depth(), expectedDepth, label);
88+
}
89+
9090
int main() {
9191
TestRunner runner;
9292
{

src/8_Trees/largest_subtrees.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,6 @@ class TreeWithSubtree : public BinaryTree {
8282
}
8383
};
8484

85-
// Test function to ensure that the computed largest BST subtree size matches
86-
// the expected size.
87-
void testTreeWithSubtree(TestRunner &runner, const TreeWithSubtree &tree,
88-
int expectedSize, const std::string &label) {
89-
runner.expectEqual(tree.largestBST(), expectedSize, label);
90-
}
91-
9285
namespace {
9386
struct TestRunner {
9487
int total = 0;
@@ -112,6 +105,13 @@ struct TestRunner {
112105
};
113106
} // namespace
114107

108+
// Test function to ensure that the computed largest BST subtree size matches
109+
// the expected size.
110+
void testTreeWithSubtree(TestRunner &runner, const TreeWithSubtree &tree,
111+
int expectedSize, const std::string &label) {
112+
runner.expectEqual(tree.largestBST(), expectedSize, label);
113+
}
114+
115115
int main() {
116116
TestRunner runner;
117117
{

0 commit comments

Comments
 (0)