@@ -64,15 +64,36 @@ public static void RunInteractiveTesting()
64
64
65
65
public class MyQueue < T > where T : IEquatable < T >
66
66
{
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 ;
69
69
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;
71
85
72
86
public MyQueue ( )
73
87
{
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 ; ;
76
97
77
98
debug_queue = new Queue < T > ( ) ;
78
99
}
@@ -92,63 +113,79 @@ public string Debug_View
92
113
// Using screen coordinates convention for
93
114
// the visualization: 0,0 is at upper left
94
115
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
+
98
120
// +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 )
102
124
sbArr [ i ] = new StringBuilder ( ) ;
103
125
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 ( ) ;
105
140
106
141
sbArr [ i ] . Append ( $ "{ item } ") ;
107
-
108
- tempStack . Push ( item ) ;
142
+
143
+ // Put the items back
144
+ s1_left . Push ( item ) ;
109
145
}
110
- sbArr [ i ] = new StringBuilder ( ) ;
111
- sbArr [ i ] . Append ( "s1_left_odd" ) ;
146
+ sbArr [ ^ 1 ] . Append ( "s1_left_odd" ) ;
112
147
113
- // Put them back
114
- while ( tempStack . Count > 0 )
115
- s1_left_odd . Push ( tempStack . Pop ( ) ) ;
116
148
117
149
PadWithWhitespace ( sbArr ) ;
118
150
119
-
151
+ // Build bottom to top
152
+ // Adding to the sb during step of pushing the items
153
+ // back on their original stack
120
154
121
155
// Now add on all the items from s2_right_even
122
156
// This time bottom to top
157
+
158
+ while ( s2_right . Count > 0 )
159
+ tempStack . Push ( s2_right . Pop ( ) ) ;
160
+
123
161
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 )
127
163
{
128
- var item = s2_right_even . Pop ( ) ;
164
+ var item = tempStack . Pop ( ) ;
129
165
130
166
sbArr [ k ] . Append ( $ "{ item } ") ;
131
167
132
- tempStack . Push ( item ) ;
168
+ // Put them back
169
+ s2_right . Push ( item ) ;
133
170
}
134
171
135
- // Put them back
136
- while ( tempStack . Count > 0 )
137
- s2_right_even . Push ( tempStack . Pop ( ) ) ;
138
172
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
173
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 } ") ;
148
185
149
- // sbArr[^2].Append($"{ item} " );
150
- // }
151
- // sbArr[^1].Append("debug_queue");
186
+ debug_queue . Enqueue ( item ) ;
187
+ }
188
+ sbArr [ ^ 1 ] . Append ( "debug_queue" ) ;
152
189
153
190
154
191
var sb = new StringBuilder ( ) ;
@@ -196,18 +233,97 @@ private void PadWithWhitespace(StringBuilder[] sbArr)
196
233
// then the "front of the queue" is on the top of the right stack
197
234
// -> Dequeue the front of the queue by popping the "right"/"even" stack
198
235
236
+
237
+
238
+ private bool whenEvenPopLeft ;
239
+
199
240
public T Dequeue ( )
200
241
{
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 ) ;
204
293
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.");
206
326
207
- if ( Count % 2 == 1 )
208
- item = s1_left_odd . Pop ( ) ;
209
- else
210
- item = s2_right_even . Pop ( ) ;
211
327
212
328
//var dequeued = debug_queue.Dequeue();
213
329
@@ -243,39 +359,40 @@ public T Dequeue()
243
359
244
360
public void Enqueue ( T item )
245
361
{
362
+ // Enqueue and Dequeue designed to always leave the left stack
363
+ // taller when Count is odd
364
+
246
365
if ( Count % 2 == 1 )
247
366
{
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 ( ) ) ;
250
369
251
- s2_right_even . Push ( item ) ;
370
+ s2_right . Push ( item ) ;
252
371
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 ( ) ) ;
255
374
}
256
375
else
257
376
{
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 ( ) ) ;
260
379
261
- s1_left_odd . Push ( item ) ;
380
+ s1_left . Push ( item ) ;
262
381
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 ( ) ) ;
265
384
}
266
- //T result;
267
385
268
- //var check = debug_queue.TryPeek(out result);
269
386
270
- // debug_queue.Enqueue(item);
387
+ debug_queue . Enqueue ( item ) ;
271
388
}
272
389
273
390
274
391
public int Count
275
392
{
276
393
get
277
394
{
278
- return s1_left_odd . Count + s2_right_even . Count ;
395
+ return s1_left . Count + s2_right . Count ;
279
396
}
280
397
}
281
398
0 commit comments