Skip to content

Commit f67d2d5

Browse files
committed
fix tests
1 parent 7477384 commit f67d2d5

2 files changed

Lines changed: 161 additions & 10 deletions

File tree

src/3_Stack_Queue/min_in_stack.cpp

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

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,

0 commit comments

Comments
 (0)