Skip to content

Commit 19068db

Browse files
committed
Broken version. Current Enqueue seems to work well. Can't figure out how to Dequeue in a way that is compatible for intermixing calls to Enqueue and Dequeue intermittantly.
1 parent 244a384 commit 19068db

File tree

1 file changed

+178
-61
lines changed

1 file changed

+178
-61
lines changed

Assignment5/Problem2.cs

+178-61
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,36 @@ public static void RunInteractiveTesting()
6464

6565
public class MyQueue<T> where T : IEquatable<T>
6666
{
67-
private Stack<T> s1_left_odd;
68-
private Stack<T> s2_right_even;
67+
private readonly Stack<T> s1_left;
68+
private readonly Stack<T> s2_right;
6969

70-
private Queue<T> debug_queue;
70+
private readonly Queue<T> debug_queue;
71+
72+
//private bool popLeftNext;
73+
74+
// TODO: FIGURE OUT WHAT'S GOING ON WITH THIS ENUM NOT WORKING
75+
76+
//TODO: UPDATE THESE WITH FINAL STACK NAMES
77+
//public enum StackSide
78+
//{
79+
// never_popped = 0,
80+
// s1_left = 1,
81+
// s2_right = 2,
82+
//}
83+
//// For specifying the front of the queue ONLY when Count >= 3
84+
//public StackSide lastPoppedSide = StackSide.never_popped;
7185

7286
public MyQueue()
7387
{
74-
s1_left_odd = new Stack<T>();
75-
s2_right_even = new Stack<T>();
88+
s1_left = new Stack<T>();
89+
s2_right = new Stack<T>();
90+
91+
//lastPoppedSide = StackSide.never_popped;
92+
93+
//popLeftNext = true;
94+
95+
96+
whenEvenPopLeft = true; ;
7697

7798
debug_queue = new Queue<T>();
7899
}
@@ -92,63 +113,79 @@ public string Debug_View
92113
// Using screen coordinates convention for
93114
// the visualization: 0,0 is at upper left
94115

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];
116+
117+
var tallestStackHeight =
118+
s1_left.Count > s2_right.Count ? s1_left.Count : s2_right.Count;
119+
98120
// +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-
{
121+
var sbArr = new StringBuilder[tallestStackHeight + 1];
122+
// For simplicity, put the SB objects in first
123+
for (var i = 0; i < sbArr.Length; ++i)
102124
sbArr[i] = new StringBuilder();
103125

104-
var item = s1_left_odd.Pop();
126+
127+
128+
// Stringify all the items from s1_left_odd
129+
// put them in the array of SBs to render
130+
// BUG: BE CAREFUL OF COMPARING TWO THINGS WHEN THEY ARE BOTH CHANGING
131+
// ARE YOU SURE THAT'S WHAT YOU MEAN?
132+
133+
// Get the items ready to read
134+
while (s1_left.Count > 0)
135+
tempStack.Push(s1_left.Pop());
136+
137+
for (var i = sbArr.Length - 2; tempStack.Count > 0; --i)
138+
{
139+
var item = tempStack.Pop();
105140

106141
sbArr[i].Append($"{item}");
107-
108-
tempStack.Push(item);
142+
143+
// Put the items back
144+
s1_left.Push(item);
109145
}
110-
sbArr[i] = new StringBuilder();
111-
sbArr[i].Append("s1_left_odd");
146+
sbArr[^1].Append("s1_left_odd");
112147

113-
// Put them back
114-
while (tempStack.Count > 0)
115-
s1_left_odd.Push(tempStack.Pop());
116148

117149
PadWithWhitespace(sbArr);
118150

119-
151+
// Build bottom to top
152+
// Adding to the sb during step of pushing the items
153+
// back on their original stack
120154

121155
// Now add on all the items from s2_right_even
122156
// This time bottom to top
157+
158+
while(s2_right.Count > 0)
159+
tempStack.Push(s2_right.Pop());
160+
123161
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
162+
for (var k = sbArr.Length - 2; tempStack.Count > 0; --k)
127163
{
128-
var item = s2_right_even.Pop();
164+
var item = tempStack.Pop();
129165

130166
sbArr[k].Append($"{item}");
131167

132-
tempStack.Push(item);
168+
// Put them back
169+
s2_right.Push(item);
133170
}
134171

135-
// Put them back
136-
while (tempStack.Count > 0)
137-
s2_right_even.Push(tempStack.Pop());
138172

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);
143173

144-
//// Now the queue for comparison:
145-
//for (var m = 0; m < debug_queue.Count; ++m)
146-
//{
147-
// var item = debug_queue.Dequeue();
174+
PadWithWhitespace(sbArr);
175+
176+
// Don't need a temp queue, since we can simply
177+
// make the items "go around and get back in"
178+
179+
// Now the queue for comparison:
180+
for (var m = 1; m <= debug_queue.Count; ++m)
181+
{
182+
var item = debug_queue.Dequeue();
183+
184+
sbArr[^2].Append($"{item} ");
148185

149-
// sbArr[^2].Append($"{item} ");
150-
//}
151-
//sbArr[^1].Append("debug_queue");
186+
debug_queue.Enqueue(item);
187+
}
188+
sbArr[^1].Append("debug_queue");
152189

153190

154191
var sb = new StringBuilder();
@@ -196,18 +233,97 @@ private void PadWithWhitespace(StringBuilder[] sbArr)
196233
// then the "front of the queue" is on the top of the right stack
197234
// -> Dequeue the front of the queue by popping the "right"/"even" stack
198235

236+
237+
238+
private bool whenEvenPopLeft;
239+
199240
public T Dequeue()
200241
{
201-
// Let's see what exception we get when we pop from an empty stack
202-
//if(Count == 0)
203-
// throw new Empty
242+
if (Count == 0)
243+
throw new InvalidOperationException("Queue is empty.");
244+
245+
// Stacks are maintained after each Enqueue and Dequeue operation
246+
// for the next item for Dequeue to be on the top of the left stack
247+
// and the item-after-that for Dequeue to be on the top of the right
248+
// stack
249+
// Means we don't need a seperate tracking variable to remember
250+
// where to Dequeue items from or where to Enqueue items to
251+
252+
T item = s1_left.Pop();
253+
254+
//if (popLeftNext == true)
255+
//{
256+
// item = s1_left.Pop();
257+
// popLeftNext = false;
258+
//}
259+
//else
260+
//{
261+
// item = s2_right.Pop();
262+
// popLeftNext = true;
263+
//}
264+
265+
266+
// Alternating works fine for Count >= 4
267+
// For Count <= 3, we need special handling:
268+
//if (Count <= 3)
269+
// popLeftNext = true;
270+
271+
272+
// After popping
273+
274+
// If right stack is taller
275+
// Fixup: Move the top item of the right stack to the left stack
276+
// Thus making the stacks equal height
277+
if (s1_left.Count < s2_right.Count)
278+
s1_left.Push(s2_right.Pop());
279+
// Now the next item to Dequeue is on the top of the left stack
280+
// and the item-after-that to Dequeue is on the top of the right
281+
// stack
282+
283+
284+
// My guess is that if the stacks are the same height, that sometimes
285+
// we should swap the top ones and sometimes we should not (based on
286+
// something! maybe we do need an additional variable) Let's experiment...
287+
else if (s1_left.Count == s2_right.Count && s1_left.Count > 0 && whenEvenPopLeft)
288+
{
289+
// Let's try swapping them all of the time and see what happen
290+
var temp = s1_left.Pop();
291+
s1_left.Push(s2_right.Pop());
292+
s2_right.Push(temp);
204293

205-
T item;
294+
whenEvenPopLeft = false;
295+
}
296+
297+
// Maybe it is a simple alternation
298+
299+
300+
301+
// Basically, at any given moment, we want to be able to Enqueue
302+
// as though nothing has ever been Dequeued, since Enqueue is so
303+
// much more complicated anyway, wanting to shift some of the overall
304+
// complexity to here in Dequque
305+
306+
307+
var itemFromRealQueue = debug_queue.Dequeue();
308+
309+
if (item.Equals(itemFromRealQueue) == false)
310+
throw new Exception("Item Dequeued from MyQueue != item Dequeued from real Queue.");
311+
312+
313+
314+
//if (lastPoppedSide == StackSide.s2_right || lastPoppedSide == StackSide.never_popped)
315+
//{
316+
// item = s1_left.Pop();
317+
// lastPoppedSide = StackSide.s1_left;
318+
//}
319+
//else if (lastPoppedSide == StackSide.s1_left)
320+
//{
321+
// item = s2_right.Pop();
322+
// lastPoppedSide = StackSide.s2_right;
323+
//}
324+
//else
325+
// throw new Exception("Stack side alternation in a bad state.");
206326

207-
if (Count % 2 == 1)
208-
item = s1_left_odd.Pop();
209-
else
210-
item = s2_right_even.Pop();
211327

212328
//var dequeued = debug_queue.Dequeue();
213329

@@ -243,39 +359,40 @@ public T Dequeue()
243359

244360
public void Enqueue(T item)
245361
{
362+
// Enqueue and Dequeue designed to always leave the left stack
363+
// taller when Count is odd
364+
246365
if (Count % 2 == 1)
247366
{
248-
while (s2_right_even.Count > 0)
249-
s1_left_odd.Push(s2_right_even.Pop());
367+
while (s2_right.Count > 0)
368+
s1_left.Push(s2_right.Pop());
250369

251-
s2_right_even.Push(item);
370+
s2_right.Push(item);
252371

253-
while (s1_left_odd.Count != s2_right_even.Count)
254-
s2_right_even.Push(s1_left_odd.Pop());
372+
while (s1_left.Count != s2_right.Count)
373+
s2_right.Push(s1_left.Pop());
255374
}
256375
else
257376
{
258-
while (s1_left_odd.Count > 0)
259-
s2_right_even.Push( s1_left_odd.Pop() );
377+
while (s1_left.Count > 0)
378+
s2_right.Push( s1_left.Pop() );
260379

261-
s1_left_odd.Push(item);
380+
s1_left.Push(item);
262381

263-
while (s1_left_odd.Count <= s2_right_even.Count)
264-
s1_left_odd.Push(s2_right_even.Pop());
382+
while (s1_left.Count <= s2_right.Count)
383+
s1_left.Push(s2_right.Pop());
265384
}
266-
//T result;
267385

268-
//var check = debug_queue.TryPeek(out result);
269386

270-
//debug_queue.Enqueue(item);
387+
debug_queue.Enqueue(item);
271388
}
272389

273390

274391
public int Count
275392
{
276393
get
277394
{
278-
return s1_left_odd.Count + s2_right_even.Count;
395+
return s1_left.Count + s2_right.Count;
279396
}
280397
}
281398

0 commit comments

Comments
 (0)