Skip to content

Commit 244a384

Browse files
committed
Implemented Prob2 (Implement a queue with two stacks)
Wrote interactive testing Wrote a debug visualization for stack and queue...still working out the bugs of it
1 parent f3a3c9f commit 244a384

File tree

2 files changed

+313
-1
lines changed

2 files changed

+313
-1
lines changed

Assignment5/Problem2.cs

+309
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,309 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace Assignment5
6+
{
7+
class Problem2
8+
{
9+
10+
public static void RunInteractiveTesting()
11+
{
12+
string intro =
13+
"==============\n" +
14+
"= Problem #2 =\n" +
15+
"==============\n" +
16+
"\n" +
17+
"Implement a Queue using two stacks, s1 and s2.\n";
18+
19+
Console.WriteLine(intro);
20+
21+
var queue = new MyQueue<string>();
22+
23+
string input = "default";
24+
25+
var queue2 = new Queue<string>();
26+
27+
queue2.Enqueue("a string");
28+
29+
queue2.Dequeue();
30+
31+
32+
33+
while (input != "done")
34+
{
35+
Console.WriteLine(queue.Debug_View);
36+
37+
Console.WriteLine("\nEnter Queue command or \"done\"\n");
38+
input = Console.ReadLine();
39+
string[] commands = input.Split(' ');
40+
41+
if (commands[0] == "en")
42+
{
43+
var item = commands[1];
44+
queue.Enqueue(item);
45+
Console.WriteLine($"Enqueued: {item}\n");
46+
}
47+
else if (commands[0] == "de")
48+
{
49+
Console.WriteLine($"Dequeued: {queue.Dequeue()}\n");
50+
}
51+
}
52+
}
53+
54+
55+
// TODO: Debug visualization:
56+
// Pop all the items of each stack onto a temp stack
57+
// Reading them as you go to print the contents
58+
// Then re-load the stack to continue testing
59+
60+
// Check the number of items in the queue
61+
// Dequeue them and re-queue them, printing as go
62+
// Stopping when gotten all the way around
63+
64+
65+
public class MyQueue<T> where T : IEquatable<T>
66+
{
67+
private Stack<T> s1_left_odd;
68+
private Stack<T> s2_right_even;
69+
70+
private Queue<T> debug_queue;
71+
72+
public MyQueue()
73+
{
74+
s1_left_odd = new Stack<T>();
75+
s2_right_even = new Stack<T>();
76+
77+
debug_queue = new Queue<T>();
78+
}
79+
80+
81+
82+
public string Debug_View
83+
{
84+
// This approach should work as long as it is executed in-between
85+
// Enqueue and Dequeue method calls
86+
// Using this during one of those calls may mess up the formatting
87+
// May need to return and make more robust if that is the goal
88+
get
89+
{
90+
var tempStack = new Stack<T>();
91+
92+
// Using screen coordinates convention for
93+
// the visualization: 0,0 is at upper left
94+
95+
// Stringify all the items from s1_left_odd
96+
// put them in the array of SBs to render
97+
var sbArr = new StringBuilder[s1_left_odd.Count+1];
98+
// +1 since we want a row below to label the stacks and queue
99+
var i = 0;
100+
for (; i < s1_left_odd.Count; ++i)
101+
{
102+
sbArr[i] = new StringBuilder();
103+
104+
var item = s1_left_odd.Pop();
105+
106+
sbArr[i].Append($"{item}");
107+
108+
tempStack.Push(item);
109+
}
110+
sbArr[i] = new StringBuilder();
111+
sbArr[i].Append("s1_left_odd");
112+
113+
// Put them back
114+
while (tempStack.Count > 0)
115+
s1_left_odd.Push(tempStack.Pop());
116+
117+
PadWithWhitespace(sbArr);
118+
119+
120+
121+
// Now add on all the items from s2_right_even
122+
// This time bottom to top
123+
sbArr[^1].Append("s2_right_odd");
124+
for (var k = s2_right_even.Count-1; k >= 0; --k)
125+
// Running the loop when k == 0 crashes since that is
126+
// popping from an empty stack
127+
{
128+
var item = s2_right_even.Pop();
129+
130+
sbArr[k].Append($"{item}");
131+
132+
tempStack.Push(item);
133+
}
134+
135+
// Put them back
136+
while (tempStack.Count > 0)
137+
s2_right_even.Push(tempStack.Pop());
138+
139+
// Until I figure out wtf is up with the regular C# Queue
140+
// Try it in the same context with a different type,
141+
// maybe a value type
142+
//PadWithWhitespace(sbArr);
143+
144+
//// Now the queue for comparison:
145+
//for (var m = 0; m < debug_queue.Count; ++m)
146+
//{
147+
// var item = debug_queue.Dequeue();
148+
149+
// sbArr[^2].Append($"{item} ");
150+
//}
151+
//sbArr[^1].Append("debug_queue");
152+
153+
154+
var sb = new StringBuilder();
155+
// Must disambiguate the call to AppendJoin
156+
sb.AppendJoin("\n", sbArr as IEnumerable<StringBuilder>);
157+
158+
return sb.ToString();
159+
}
160+
}
161+
162+
private void PadWithWhitespace(StringBuilder[] sbArr)
163+
{
164+
const int EXTRA_PAD = 5;
165+
166+
int lengthOfLongestSB = sbArr[0].Length;
167+
for(var i = 1; i < sbArr.Length; ++i)
168+
{
169+
if (sbArr[i].Length > lengthOfLongestSB)
170+
lengthOfLongestSB = sbArr[i].Length;
171+
}
172+
173+
for(var k = 0; k < sbArr.Length; ++k)
174+
{
175+
var padCount =
176+
lengthOfLongestSB - sbArr[k].Length + EXTRA_PAD;
177+
sbArr[k].Append(' ', padCount);
178+
}
179+
}
180+
181+
182+
// TODO: Have to handle pop from empty stack...how does that go with
183+
// the mod test for left or right?
184+
185+
186+
187+
188+
// For Dequeue:
189+
190+
// If queue count (that is, stack1.count + stack1.count) % 2 == 1
191+
// (that is, number of items in queue is odd)
192+
// then the "front of the queue" is on the top of the left stack
193+
// -> Dequeue the front of the queue by popping the "left"/"odd" stack
194+
195+
// Else, if the number of items in queue is even
196+
// then the "front of the queue" is on the top of the right stack
197+
// -> Dequeue the front of the queue by popping the "right"/"even" stack
198+
199+
public T Dequeue()
200+
{
201+
// Let's see what exception we get when we pop from an empty stack
202+
//if(Count == 0)
203+
// throw new Empty
204+
205+
T item;
206+
207+
if (Count % 2 == 1)
208+
item = s1_left_odd.Pop();
209+
else
210+
item = s2_right_even.Pop();
211+
212+
//var dequeued = debug_queue.Dequeue();
213+
214+
//if (item.Equals(dequeued))
215+
// throw new Exception($"{item} was popped from the stacks, but {dequeued} was dequeued");
216+
217+
return item;
218+
}
219+
220+
221+
// For Enqueue:
222+
223+
// If there is an even number of items, time for there to be an odd
224+
// number of items, with one more item being on the left stack
225+
226+
// Pop all items from the left stack onto the right stack (count how many)
227+
// Push the newly "Enqueued" item onto the (now empty) left stack
228+
// Then Push "count" number of items back onto the left stack
229+
230+
// Now the stacks should be in a good state for being able to pop all
231+
// the way down to empty immediately, should the user dequeue all the items
232+
233+
234+
// If there is an odd number of items, time for there to be an even
235+
// number of items, with equal number of items being on each stack
236+
237+
// Pop all items from the right stack onto the left stack (count how many)
238+
// Push the newly "Enqueued" item onto the (now empty) right stack
239+
// Then push "count" number of items back onto the right stack
240+
241+
// Wait. We don't need to count how many.
242+
// Just put back until the the stacks have the same number
243+
244+
public void Enqueue(T item)
245+
{
246+
if (Count % 2 == 1)
247+
{
248+
while (s2_right_even.Count > 0)
249+
s1_left_odd.Push(s2_right_even.Pop());
250+
251+
s2_right_even.Push(item);
252+
253+
while (s1_left_odd.Count != s2_right_even.Count)
254+
s2_right_even.Push(s1_left_odd.Pop());
255+
}
256+
else
257+
{
258+
while (s1_left_odd.Count > 0)
259+
s2_right_even.Push( s1_left_odd.Pop() );
260+
261+
s1_left_odd.Push(item);
262+
263+
while (s1_left_odd.Count <= s2_right_even.Count)
264+
s1_left_odd.Push(s2_right_even.Pop());
265+
}
266+
//T result;
267+
268+
//var check = debug_queue.TryPeek(out result);
269+
270+
//debug_queue.Enqueue(item);
271+
}
272+
273+
274+
public int Count
275+
{
276+
get
277+
{
278+
return s1_left_odd.Count + s2_right_even.Count;
279+
}
280+
}
281+
282+
283+
// Enqueue must remove them in the order that they were added,
284+
// so odd/even will enable alternating between the stacks
285+
286+
// Maybe can tell which stack has the "front" of the queue
287+
// based on whether the count of items in the queue is even or odd?
288+
289+
290+
291+
292+
293+
// Always leave stacks ready to pop all the way down after pushing
294+
295+
296+
297+
298+
// Keep track of which stack currently has the "front" of the queue
299+
// "Stabilize" the stacks after every operation so that they either
300+
// contain the same number of items, or they differ by only one
301+
302+
303+
304+
305+
306+
}
307+
308+
}
309+
}

Program.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,10 @@ static void Main(string[] args)
4646

4747

4848

49-
Assignment5.Problem5.RunInteractiveTesting();
49+
//Assignment5.Problem5.RunInteractiveTesting();
50+
51+
52+
Assignment5.Problem2.RunInteractiveTesting();
5053

5154

5255
// looks like there's no copy constructor for Array

0 commit comments

Comments
 (0)