Looping through a circular buffer in Chisel - chisel

Let's say I have implemented a circular buffer with a head and a tail. Is there an elegant scala-way of looping through this buffer starting from the head ending at the tail (and doing a possible wrap-around at the end)
class MyBuffer() extends Module
{
val data = Reg(Vec(NUM_ELEMENTS, Bool())
val head = RegInit(0.U(NUM_ELEMENTS_W.W))
val tail = RegInit(0.U(NUM_ELEMENTS_W.W))
}

I'm not sure what your looping goal is. But consider the following code example (with a few details left out). This example exposes the contents of a RingBuffer as Vec view with ViewLength valid elements. I think this demonstrates a modestly elegant method for this definition of looping, the emitted hardware (or the view idea) may not be elegant. Let me know if is not quite the notion of looping you had in mind.
import chisel3._
import chisel3.util.log2Ceil
/**
* This ring buffer presents its current contents through view
*
* #param depth
* #param bitWidth
*/
class RingBuffer(depth: Int, bitWidth: Int) extends MultiIOModule {
/*
You need a bunch of IO's here to push and pop and get full status
*/
val view = IO(Output(Vec(depth, UInt(bitWidth.W))))
val viewLength = IO(Output(UInt(log2Ceil(depth).W)))
val data = Reg(Vec(depth, Bool()))
val head = RegInit(0.U(bitWidth.W))
val tail = RegInit(0.U(bitWidth.W))
/* Need some code here to push and pop elements */
// this constructs a mapping between the indices between current head and tail
// to the 0 to n indices of the view
def mappedIndex(i: Int): UInt = {
val out = Wire(UInt(log2Ceil(depth).W))
when((i.U + head) <= depth.U) {
out := i.U + head
}.otherwise {
out := (i.U + head) - depth.U
}
out
}
// This creates the complicated Mux structure to map betweem
// the ring buffer elements and 0 to n style view
view.zipWithIndex.foreach { case (viewElement, index) =>
viewElement := data(mappedIndex(index))
}
// This presents the number of valid elements in the current view
val difference = tail - head
when((difference) < 0.U) {
viewLength := (difference) + depth.U
}.otherwise {
viewLength := (difference)
}
}

Related

converting one function into multiple - Kotlin

how would I go about taking this one function and turning it into multiple functions?
I need to create a local double variable called change and set it to a test value (e.g. 44.77)
Create five separate functions dollars(), quarters(), dimes(), nickels() and pennies().
Each function will:
accept a double amount as an argument
calculate and display that denominations number (e.g. 7 Dollars)
then return the recalculated change (e.g. 0.67)
In Kotlin, the function signature for quarters would be: quarters(myChange: Double): Double
I really wish we didn't have to do separate function as one function is so much easier.
here is my code so far:
fun main(args: Array<String>) {
var remChange = .03 ;
monies(remChange);
}
fun monies(remChange: Double){
var dollars = Math.floor(remChange/1.0);
var remChange1 = remChange-(dollars*1.00);
print(Math.round(dollars*1)/1)
if(dollars<2) println("_Dollar"); else if (dollars>=2) println("_Dollars")
var quarter = Math.floor(remChange1/0.25);
var remChange2 = remChange1-(quarter*0.25);
print(Math.round(quarter*4)/4)
if(quarter<2) println("_Quarter"); else if (quarter>=2) println("_Quarters")
var dime = Math.floor(remChange2 / 0.10);
var remChange3 = remChange2 - (dime*0.10);
print(Math.round(dime*10)/10)
if(dime<2) println("_Dime") else if(dime>=2) println("_Dimes")
var nickel = Math.floor(remChange3 / 0.05);
var remChange4 = remChange3 - (nickel*0.05);
print(Math.round(nickel*20)/20)
if(nickel<2) println("_Nickel") else if (nickel>=2) println("_Nickels")
var penny = Math.floor(remChange4*100);
print(Math.round(penny*100)/100)
if(penny<2) println("_Penny") else if (penny>=2) println("_Pennies")
return Unit;
}
here is my attempt at this:
fun main(args: Array<String>) {
val change = 10.88
Dollar(change);
Quarter(change);
Dime(change);
Nickel(change);
Penny(change);
}
fun Dollar(myChange: Double): Double{
val dollar = myChange/(1.00).toFloat();
val change1 = myChange - (dollar * 1.00);
print((dollar * 1)/1);
if(dollar<2) println("_Dollar"); else if (dollar>=2) println("_Dollars");
return change1
}
fun Quarter(myChange: Double): Double{
val quarter = myChange/(0.25).toFloat();
val change2 = myChange - (quarter * 0.25);
println((quarter*4)/4);
if(quarter<2) println("_Quarter"); else if (quarter>=2) println("_Quarters");
return change2
}
fun Dime(myChange: Double): Double{
val dime = myChange/(0.10).toFloat();
val change3 = myChange - (dime * 0.10);
println((dime * 10)/10);
if(dime<2) println("_Dime"); else if(dime>=2) println("_Dimes");
return change3
}
fun Nickel(myChange: Double): Double{
val nickel = myChange/(0.05).toFloat();
val change4 = myChange - (nickel * 0.05);
println((nickel*20)/20);
if(nickel<2) println("_Nickel"); else if (nickel>=2) println("_Nickels");
return change4
}
fun Penny(myChange: Double){
val penny = myChange/100);
print((penny * 100)/ 100);
if(penny<2) println("_Penny"); else if (penny>=2) println("_Pennies");
return Unit
}
OUTPUT:
Unexpected tokens (use ';' to separate expressions on the same line)
Expecting an element
I can't figure out where the rouge ';' is or lack there of
and I'm not sure why it's missing an element. I just want it to produce the same output as my first code. I've done everything from youtube, w3, chegg, online forum research.
Since this is homework I'm not just going to provide a solution, but here's something important to consider - usually, the point of breaking stuff down into multiple functions is to reduce repetition, and make code reusable by having it as its own function. Check this out, from your solution:
fun Dime(myChange: Double): Double{
val dime = myChange/(0.10).toFloat();
val change3 = myChange - (dime * 0.10);
println((dime * 10)/10);
if(dime<2) println("_Dime"); else if(dime>=2) println("_Dimes");
return change3
}
fun Nickel(myChange: Double): Double{
val nickel = myChange/(0.05).toFloat();
val change4 = myChange - (nickel * 0.05);
println((nickel*20)/20);
if(nickel<2) println("_Nickel"); else if (nickel>=2) println("_Nickels");
return change4
}
Obviously there's a lot of repetition there, which is probably part of the reason you're saying it's just making things harder - it's true, it is! It's bloating the code and making it harder to maintain, because any change in the logic has to be repeated for every function, because it's the same logic, just using different values.
So what you could do, is create one calculation function that handles this logic, using a set of values that's passed in. Then, each denomination's function can call that calculation one, passing in the set of values appropriate for that denomination. So they end up acting as helper functions, "configuring" the main one.
So now the question is, what are those parameters? What is it that changes in each of those functions, what are the things that vary, the variables? You should probably think about it yourself before you read the rest, but I see these:
the value you're dividing by to get a coin count (e.g. 0.05 for nickels)
the value you're multiplying by to get a money total, to work out how much change is remaining (e.g. 0.05 for nickels)
the value you're multiplying your coin total by in the println statement (e.g. 20 for nickels)
the value you're dividing by in the same statement (e.g. 20 for nickels)
singular and plural labels for the denomination (e.g. _Nickel and Nickels for nickels)
Some of those look the same (e.g. 0.05 and 0.05) so maybe you can pass in a single variable, which gets used in two places in the logic. You have to work out if this is the case, if they're the same value being referenced twice, or if it's a coincidence.
Some of those also look related to other values, e.g. 10 * 0.1 = 1.0, 20 * 0.05 = 1.0. If this is the case, and there's a consistent relationship between two values, then maybe you can derive one from the other, meaning you only need to pass one value in, and calculate the others you need to use from that. Again, you need to work out if this is logically sound - you're writing an algorithm here, you need to understand what those values are and what they mean. Breaking stuff down into reusable functions is all about this kind of generalisation and working out how things relate to each other.
Once you have your nice utility function that takes a set of parameters, you can make helper functions that call it with a fixed set of values:
fun nickels(myChange: Double): Double {
return calculate(parameters relating to nickels go here)
}
and now, there's no repetition! The calculation code is in one function, the printing code is in one function, and each of the denomination functions just holds unique data (the parameters passed to the main function).
I wouldn't necessarily tackle this problem like this (and I'm not reviewing the actual logic in your functions either) but it's good as a general example of how you approach things in a more functional way. Basically - if you find yourself repeating things, maybe you can stick that in its own function, and have the repeats call that instead
import kotlin.math.floor
fun dollars(remChange: Double): Double {
return arrayOf(1.0).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun quarters(remChange: Double): Double {
return arrayOf(1.0, 0.25).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun dimes(remChange: Double): Double {
return arrayOf(1.0, 0.25, 0.1).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun nickels(remChange: Double): Double {
return arrayOf(1.0, 0.25, 0.1, 0.05).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
fun pennies(remChange: Double): Double {
return arrayOf(1.0, 0.25, 0.1, 0.05, 0.01).fold(0.0 to remChange) { acc, dbl ->
val amount = floor(acc.second / dbl) * dbl
amount to acc.second - amount
}.first
}
val amount = 44.77
println("Dollars : " + dollars(amount)) // 44.0
println("Quarters : " + quarters(amount)) // 0.75
println("Dimes : " + dimes(amount)) // 0.0
println("Nickels : " + nickels(amount)) // 0.0
println("Pennies : " + pennies(amount)) // 0.2
Your error is this extra closing parenthesis on this line:
val penny = myChange/100);
I don't know of any online playground that shows you the error in the proper location. If you use an IDE like IntelliJ IDEA, it will highlight the error in your code as you type it with a red squiggly underline, just like a typo in a word processor. I highly recommend using IntelliJ IDEA if you are trying to learn Kotlin. It would have saved you a lot of time here.
Regarding your homework task, I think the point of challenging you to break your function up is to remove the repetition, which is a core principle of effective programming. Your new solution breaks it up into multiple functions without removing the repetition, so that's why it seems like a less sensible solution to you. See #cactustictacs' answer for more info about that.

Count no. of ones by position(place) of an array of 32-bit binary numbers

An array(10^5 size) of 32-bit binary numbers is given, we're required to count the no. of ones for every bit of those numbers.
For example:
Array : {10101,1011,1010,1}
Counts : {1's place: 3, 2's place: 2, 3's place: 1, 4's place: 2, 5's place: 1}
No bit manipulation technique seems to satisfy the constraints to me.
Well, this should be solveable with two loops: one going over the array the other one masking the right bits. Running time should be not too bad for your constraints.
Here is a rust implementation (out of my head, not throughtfully tested):
fn main() {
let mut v = vec!();
for i in 1..50*1000 {
v.push(i);
}
let r = bitcount_arr(v);
r.iter().enumerate().for_each( |(i,x)| print!("index {}:{} ",i+1,x));
}
fn bitcount_arr(input:Vec<u32>) -> [u32;32] {
let mut res = [0;32];
for num in input {
for i in 0..31 {
let mask = 1 << i;
if num & mask != 0 {
res[i] += 1;
}
}
}
res
}
This can be done with transposed addition, though the array is a bit long for it.
To transpose addition, use an array of counters, but instead of using one counter for every position we'll use one counter for every bit of the count. So a counter that tracks for each position whether the count is even/odd, a counter that tracks for each position whether the count has a 2 in it, etc.
To add an element of the array into this, only half-add operations (& to find the new carry, ^ to update) are needed, since it's only a conditional increment: (not tested)
uint32_t counters[17];
for (uint32_t elem : array) {
uint32_t c = elem;
for (int i = 0; i < 17; i++) {
uint32_t nextcarry = counters[i] & c;
counters[i] ^= c;
c = nextcarry;
}
}
I chose 17 counters because log2(10^5) is just less than 17. So even if all bits are 1, the counters won't wrap.
To read off the result for bit k, take the k'th bit of every counter.
There are slightly more efficient ways that can add several elements of the array into the counters at once using some full-adds and duplicated counters.

How to call function for object I want?

I didnt know how to exactly ask the question in the title but I can explain it here. So I have this class for pawns in my game.
And in my main program i call a bunch of instances of it with different names.
var z1:ZeleniPijun = new ZeleniPijun();
var z2:ZeleniPijun = new ZeleniPijun();
Basicly I have functions for movement and other variables that I use in my code in the class.
I'm making a multiplayer game and z1 and z2 would be pawns that I move around.
Until now I have used Switch and by knowing the ID of the player and the pawn that was clicked I moved them around the board. That means I have a switch for selecting a player and a switch inside that switch for selecting a pawn. And every time it goes trough the switch it goes to the same code but with a "different name".
For example if I roll a 4 for pawn number 1 it does
z1.movePawn(4);
z1.location += 4;
and other stuff that I need it to do
and if I roll a 3 for pawn number 2 it does
z2.movePawn(4);
z2.location += 4;
and other stuff that I need it to do
I have to copy the same code 16 times and just change the name from z1 to z2 to z3 etc...
Is there anyway I can make a function that would do that for me?
Something like this:
public function doStuff(pawnName:String, number:int):void{
pawnName.movePawn(number);
pawnName.location = number;
and other stuff that I need it to do
}
and then I can just give it the parameters I want 16 times instead of copying the same code everywhere.
send to the doStuff function the object that you want to do changes like
public function doStuff(theObj:ZeleniPijun ):void{
theObj.movePawn(number);
theObj.location = number;
and other stuff that I need it to do
}
if you have many objects, put them in a collection, like an array an iterate on it something like
foreach (obj in collection){
doStuff(obj);
}
this is just more or less pseudo-code, but you get the idea
You can use the object ZeleniPijun as parameter and call the method passing the instance you want.
// example creating multiples objects
var numObjs : uint = 5;
var objectsControl : Vector.<ZeleniPijun> = new Vector.<ZeleniPijun>(numObjs);
var zeleninPijun : ZeleniPijun;
for (var i : int = 0; i < numObjs; i++)
{
zeleninPijun = new ZeleniPijun();
objectsControl[i] = zeleninPijun;
}
// if you want to animate one object
doStuff(objectsControl[0], 4);
// if you want to animate them all
for each (var zeleninPijunObj : ZeleniPijun in objectsControl)
{
doStuff(zeleninPijunObj, 4);
}
function doStuff(pawnObj:ZeleniPijun, location:int):void
{
pawnObj.movePawn(location);
pawnObj.location = location;
}

Passing Vector.<T> references as Object, casting causes a copy to be made

I'd like to be able to pass Vectors around as references. Now, if a method takes a Vector.<Object>, then passing a Vector.<TRecord>, where TRecord inherits directly from Object does not work. Where a method takes just plain Object; say vec: Object, then passing the Vector is possible. Once inside this method, an explicit cast at some stage is required to access vec as a Vector again. Unfortunately, a cast seems to make a copy, which means wrapping one up in multiple Flex ListCollectionViews is useless; each ListCollectionView will be pointing to a different Vector.
Using Arrays with ArrayCollection presents no such problem, but I lose out out the type safety, neatness (code should be clean enough to eat off of) and performance advantages of Vector.
Is there a way to cast them or pass them as references in a generic manner without copies being made along the way?
Note in this example, IRecord is an interface with {r/w id: int & name: String} properties, but it could be a class, say TRecord { id: int; name: String} or any other usable type.
protected function check(srcVec: Object): void
{
if (!srcVec) {
trace("srcVec is null!");
return;
}
// srcVec = (#b347e21)
trace(srcVec.length); // 4, as expected
var refVec: Vector.<Object> = Vector.<Object>(srcVec);
// refVec = (#bc781f1)
trace(refVec.length); // 4, ok, but refVec has a different address than srcVec
refVec.pop();
trace(refVec.length); // 3 ok
trace(srcVec.length); // 4 - A copy was clearly created!!!
}
protected function test(): void
{
var vt1: Vector.<IRecord> = new Vector.<IRecord>; // (#b347e21) - original Vector address
var vt2: Vector.<Object> = Vector.<Object>(vt1); // (#bbb57c1) - wrong
var vt3: Vector.<Object> = vt1 as Vector.<Object>; // (#null) - failure to cast
var vt4: Object = vt1; // (#b347e21) - good
for (var ix: int = 0; ix < 4; ix++)
vt1.push(new TRecord);
if (vt1) trace(vt1.length); // 4, as expected
if (vt2) trace(vt2.length); // 0
if (vt3) trace(vt3.length); // vt3 is null
if (vt4) trace(vt4.length); // 4
if (vt1) trace(Vector.<Object>(vt1).length); //
trace("calling check(vt1)");
check(vt1);
}
This is not possible. If a type T is covariant with type U, then any container of T is not covariant with a container of type U. C# and Java did this with the built-in array types, and their designers wish they could go back and cut it out.
Consider, if this code was legal
var vt1: Vector.<IRecord> = new Vector.<IRecord>;
var vt3: Vector.<Object> = vt1 as Vector.<Object>;
Now we have a Vector.<Object>. But wait- if we have a container of Objects, then surely we can stick an Object in it- right?
vt3.push(new Object());
But wait- because it's actually an instance of Vector.<IRecord>, you can't do this, even though the contract of Vector.<Object> clearly says that you can insert Object. That's why this behaviour is explicitly not allowable.
Edit: Of course, your framework may allow for it to become a non-mutable reference to such, which is safe. But I have little experience with ActionScript and cannot verify that it actually does.

How to implement three stacks using a single array

I came across this problem in an interview website. The problem asks for efficiently implement three stacks in a single array, such that no stack overflows until there is no space left in the entire array space.
For implementing 2 stacks in an array, it's pretty obvious: 1st stack grows from LEFT to RIGHT, and 2nd stack grows from RIGHT to LEFT; and when the stackTopIndex crosses, it signals an overflow.
Thanks in advance for your insightful answer.
You can implement three stacks with a linked list:
You need a pointer pointing to the next free element. Three more pointers return the last element of each stack (or null, if the stack is empty).
When a stack gets another element added, it has to use the first free element and set the free pointer to the next free element (or an overflow error will be raised). Its own pointer has to point to the new element, from there back to the next element in the stack.
When a stack gets an element removed it will hand it back into the list of free elements. The own pointer of the stack will be redirected to the next element in the stack.
A linked list can be implemented within an array.
How (space) efficent is this?
It is no problem to build a linked list by using two cells of an array for each list element (value + pointer). Depending on the specification you could even get pointer and value into one array element (e.g. the array is long, value and pointer are only int).
Compare this to the solution of kgiannakakis ... where you lose up to 50% (only in the worst case). But I think that my solution is a bit cleaner (and maybe more academic, which should be no disadvantage for an interview question ^^).
See Knuth, The Art of Computer Programming, Volume 1, Section 2.2.2. titled "Sequential allocation". Discusses allocating multiple queues/stacks in a single array, with algorithms dealing with overflows, etc.
We can use long bit array representing to which stack the i-th array cell belongs to.
We can take values by modulo 3 (00 - empty, 01 - A, 10 - B, 11 - C). It would take N/2 bits or N/4 bytes of additional memory for N sized array.
For example for 1024 long int elements (4096 bytes) it would take only 256 bytes or 6%.
This bit array map can be placed in the same array at the beginning or at the end, just shrinking the size of the given array by constant 6%!
First stack grows from left to right.
Second stack grows from right to left.
Third stack starts from the middle. Suppose odd sized array for simplicity. Then third stack grows like this:
* * * * * * * * * * *
5 3 1 2 4
First and second stacks are allowed to grow maximum at the half size of array. The third stack can grow to fill in the whole array at a maximum.
Worst case scenario is when one of the first two arrays grows at 50% of the array. Then there is a 50% waste of the array. To optimise the efficiency the third array must be selected to be the one that grows quicker than the other two.
This is an interesting conundrum, and I don't have a real answer but thinking slightly outside the box...
it could depend on what each element in the stack consists of. If it's three stacks of true/false flags, then you could use the first three bits of integer elements. Ie. bit 0 is the value for the first stack, bit 1 is the value for the second stack, bit 2 is the value for the third stack. Then each stack can grow independently until the whole array is full for that stack. This is even better as the other stacks can also continue to grow even when the first stack is full.
I know this is cheating a bit and doesn't really answer the question but it does work for a very specific case and no entries in the stack are wasted. I am watching with interest to see whether anyone can come up with a proper answer that works for more generic elements.
Split array in any 3 parts (no matter if you'll split it sequentially or interleaved). If one stack grows greater than 1/3 of array you start filling ends of rest two stacks from the end.
aaa bbb ccc
1 2 3
145 2 3
145 2 6 3
145 2 6 3 7
145 286 3 7
145 286 397
The worse case is when two stacks grows up to 1/3 boundary and then you have 30% of space waste.
Assuming that all array positions should be used to store values - I guess it depends on your definition of efficiency.
If you do the two stack solution, place the third stack somewhere in the middle, and track both its bottom and top, then most operations will continue to be efficient, at a penalty of an expensive Move operation (of the third stack towards wherever free space remains, moving to the half way point of free space) whenever a collision occurs.
It's certainly going to be quick to code and understand. What are our efficiency targets?
A rather silly but effective solution could be:
Store the first stack elements at i*3 positions: 0,3,6,...
Store the second stack elements at i*3+1 positions: 1,4,7...
And third stack elements at i*3+2 positions.
The problem with this solution is that the used memory will be always three times the size of the deepest stack and that you can overflow even when there are available positions at the array.
Make a HashMap with keys to the begin and end positions e.g. < "B1" , 0 >, <"E1" , n/3 >
for each Push(value) add a condition to check if position of Bx is previous to Ex or there is some other "By" in between. -- lets call it condition (2)
with above condition in mind,
if above (2) is true // if B1 and E1 are in order
{ if ( S1.Push()), then E1 ++ ;
else // condition of overflow ,
{ start pushing at end of E2 or E3 (whichever has a space) and update E1 to be E2-- or E3-- ; }
}
if above (2) is false
{ if ( S1.Push()), then E1 -- ;
else // condition of overflow ,
{ start pushing at end of E2 or E3 (whichever has a space) and update E1 to be E2-- or E3-- ; }
}
Assume you only has integer index. if it's treated using FILO (First In Last Out) and not referencing individual, and only using an array as data. Using it's 6 space as stack reference should help:
[head-1, last-1, head-2, last-2, head-3, last-3, data, data, ... ,data]
you can simply using 4 space, because head-1 = 0 and last-3 = array length. If using FIFO (First In First Out) you need to re-indexing.
nb: I’m working on improving my English.
first stack grows at 3n,
second stack grows at 3n+1,
third grows at 3n+2
for n={0...N}
Yet another approach (as additional to linked-list) is to use map of stacks. In that case you'll have to use additional log(3^n)/log(2) bits for building map of data distribution in your n-length array. Each of 3-value part of map says which stack is owns next element.
Ex. a.push(1); b.push(2); c.push(3); a.push(4); a.push(5); will give you image
aacba
54321
appropriate value of map is calculated while elements is pushed onto stack (with shifting contents of array)
map0 = any
map1 = map0*3 + 0
map2 = map1*3 + 1
map3 = map2*3 + 2
map4 = map3*3 + 0
map5 = map4*3 + 0 = any*3^5 + 45
and length of stacks 3,1,1
Once you'll want to do c.pop() you'll have to reorganize your elements by finding actual position of c.top() in original array through walking in cell-map (i.e. divide by 3 while mod by 3 isn't 2) and then shift all contents in array back to cover that hole. While walking through cell-map you'll have to store all position you have passed (mapX) and after passing that one which points to stack "c" you'll have to divide by 3 yet another time and multiply it by 3^(amount positions passed-1) and add mapX to get new value of cells-map.
Overhead for that fixed and depends on size of stack element (bits_per_value):
(log(3n)/log(2)) / (nlog(bits_per_value)/log(2)) = log(3n) / (nlog(bits_per_value)) = log(3) / log(bits_per_value)
So for bits_per_value = 32 it will be 31.7% space overhead and with growing bits_per_value it will decay (i.e. for 64 bits it will be 26.4%).
In this approach, any stack can grow as long as there is any free space in the array.
We sequentially allocate space to the stacks and we link new blocks to the previous block. This means any new element in a stack keeps a pointer to the previous top element of that particular stack.
int stackSize = 300;
int indexUsed = 0;
int[] stackPointer = {-1,-1,-1};
StackNode[] buffer = new StackNode[stackSize * 3];
void push(int stackNum, int value) {
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = indexUsed;
indexUsed++;
buffer[stackPointer[stackNum]]=new StackNode(lastIndex,value);
}
int pop(int stackNum) {
int value = buffer[stackPointer[stackNum]].value;
int lastIndex = stackPointer[stackNum];
stackPointer[stackNum] = buffer[stackPointer[stackNum]].previous;
buffer[lastIndex] = null;
indexUsed--;
return value;
}
int peek(int stack) { return buffer[stackPointer[stack]].value; }
boolean isEmpty(int stackNum) { return stackPointer[stackNum] == -1; }
class StackNode {
public int previous;
public int value;
public StackNode(int p, int v){
value = v;
previous = p;
}
}
This code implements 3 stacks in single array. It takes care of empty spaces and fills the empty spaces in between the data.
#include <stdio.h>
struct stacknode {
int value;
int prev;
};
struct stacknode stacklist[50];
int top[3] = {-1, -1, -1};
int freelist[50];
int stackindex=0;
int freeindex=-1;
void push(int stackno, int value) {
int index;
if(freeindex >= 0) {
index = freelist[freeindex];
freeindex--;
} else {
index = stackindex;
stackindex++;
}
stacklist[index].value = value;
if(top[stackno-1] != -1) {
stacklist[index].prev = top[stackno-1];
} else {
stacklist[index].prev = -1;
}
top[stackno-1] = index;
printf("%d is pushed in stack %d at %d\n", value, stackno, index);
}
int pop(int stackno) {
int index, value;
if(top[stackno-1] == -1) {
printf("No elements in the stack %d\n", value, stackno);
return -1;
}
index = top[stackno-1];
freeindex++;
freelist[freeindex] = index;
value = stacklist[index].value;
top[stackno-1] = stacklist[index].prev;
printf("%d is popped put from stack %d at %d\n", value, stackno, index);
return value;
}
int main() {
push(1,1);
push(1,2);
push(3,3);
push(2,4);
pop(3);
pop(3);
push(3,3);
push(2,3);
}
Another solution in PYTHON, please let me know if that works as what you think.
class Stack(object):
def __init__(self):
self.stack = list()
self.first_length = 0
self.second_length = 0
self.third_length = 0
self.first_pointer = 0
self.second_pointer = 1
def push(self, stack_num, item):
if stack_num == 1:
self.first_pointer += 1
self.second_pointer += 1
self.first_length += 1
self.stack.insert(0, item)
elif stack_num == 2:
self.second_length += 1
self.second_pointer += 1
self.stack.insert(self.first_pointer, item)
elif stack_num == 3:
self.third_length += 1
self.stack.insert(self.second_pointer - 1, item)
else:
raise Exception('Push failed, stack number %d is not allowd' % stack_num)
def pop(self, stack_num):
if stack_num == 1:
if self.first_length == 0:
raise Exception('No more element in first stack')
self.first_pointer -= 1
self.first_length -= 1
self.second_pointer -= 1
return self.stack.pop(0)
elif stack_num == 2:
if self.second_length == 0:
raise Exception('No more element in second stack')
self.second_length -= 1
self.second_pointer -= 1
return self.stack.pop(self.first_pointer)
elif stack_num == 3:
if self.third_length == 0:
raise Exception('No more element in third stack')
self.third_length -= 1
return self.stack.pop(self.second_pointer - 1)
def peek(self, stack_num):
if stack_num == 1:
return self.stack[0]
elif stack_num == 2:
return self.stack[self.first_pointer]
elif stack_num == 3:
return self.stack[self.second_pointer]
else:
raise Exception('Peek failed, stack number %d is not allowd' % stack_num)
def size(self):
return len(self.items)
s = Stack()
# push item into stack 1
s.push(1, '1st_stack_1')
s.push(1, '2nd_stack_1')
s.push(1, '3rd_stack_1')
#
## push item into stack 2
s.push(2, 'first_stack_2')
s.push(2, 'second_stack_2')
s.push(2, 'third_stack_2')
#
## push item into stack 3
s.push(3, 'FIRST_stack_3')
s.push(3, 'SECOND_stack_3')
s.push(3, 'THIRD_stack_3')
#
print 'Before pop out: '
for i, elm in enumerate(s.stack):
print '\t\t%d)' % i, elm
#
s.pop(1)
s.pop(1)
#s.pop(1)
s.pop(2)
s.pop(2)
#s.pop(2)
#s.pop(3)
s.pop(3)
s.pop(3)
#s.pop(3)
#
print 'After pop out: '
#
for i, elm in enumerate(s.stack):
print '\t\t%d)' % i, elm
May be this can help you a bit...i wrote it by myself
:)
// by ashakiran bhatter
// compile: g++ -std=c++11 test.cpp
// run : ./a.out
// sample output as below
// adding: 1 2 3 4 5 6 7 8 9
// array contents: 9 8 7 6 5 4 3 2 1
// popping now...
// array contents: 8 7 6 5 4 3 2 1
#include <iostream>
#include <cstdint>
#define MAX_LEN 9
#define LOWER 0
#define UPPER 1
#define FULL -1
#define NOT_SET -1
class CStack
{
private:
int8_t array[MAX_LEN];
int8_t stack1_range[2];
int8_t stack2_range[2];
int8_t stack3_range[2];
int8_t stack1_size;
int8_t stack2_size;
int8_t stack3_size;
int8_t stack1_cursize;
int8_t stack2_cursize;
int8_t stack3_cursize;
int8_t stack1_curpos;
int8_t stack2_curpos;
int8_t stack3_curpos;
public:
CStack();
~CStack();
void push(int8_t data);
void pop();
void print();
};
CStack::CStack()
{
stack1_range[LOWER] = 0;
stack1_range[UPPER] = MAX_LEN/3 - 1;
stack2_range[LOWER] = MAX_LEN/3;
stack2_range[UPPER] = (2 * (MAX_LEN/3)) - 1;
stack3_range[LOWER] = 2 * (MAX_LEN/3);
stack3_range[UPPER] = MAX_LEN - 1;
stack1_size = stack1_range[UPPER] - stack1_range[LOWER];
stack2_size = stack2_range[UPPER] - stack2_range[LOWER];
stack3_size = stack3_range[UPPER] - stack3_range[LOWER];
stack1_cursize = stack1_size;
stack2_cursize = stack2_size;
stack3_cursize = stack3_size;
stack1_curpos = stack1_cursize;
stack2_curpos = stack2_cursize;
stack3_curpos = stack3_cursize;
}
CStack::~CStack()
{
}
void CStack::push(int8_t data)
{
if(stack3_cursize != FULL)
{
array[stack3_range[LOWER] + stack3_curpos--] = data;
stack3_cursize--;
} else if(stack2_cursize != FULL) {
array[stack2_range[LOWER] + stack2_curpos--] = data;
stack2_cursize--;
} else if(stack1_cursize != FULL) {
array[stack1_range[LOWER] + stack1_curpos--] = data;
stack1_cursize--;
} else {
std::cout<<"\tstack is full...!"<<std::endl;
}
}
void CStack::pop()
{
std::cout<<"popping now..."<<std::endl;
if(stack1_cursize < stack1_size)
{
array[stack1_range[LOWER] + ++stack1_curpos] = 0;
stack1_cursize++;
} else if(stack2_cursize < stack2_size) {
array[stack2_range[LOWER] + ++stack2_curpos] = 0;
stack2_cursize++;
} else if(stack3_cursize < stack3_size) {
array[stack3_range[LOWER] + ++stack3_curpos] = 0;
stack3_cursize++;
} else {
std::cout<<"\tstack is empty...!"<<std::endl;
}
}
void CStack::print()
{
std::cout<<"array contents: ";
for(int8_t i = stack1_range[LOWER] + stack1_curpos + 1; i <= stack1_range[UPPER]; i++)
std::cout<<" "<<static_cast<int>(array[i]);
for(int8_t i = stack2_range[LOWER] + stack2_curpos + 1; i <= stack2_range[UPPER]; i++)
std::cout<<" "<<static_cast<int>(array[i]);
for(int8_t i = stack3_range[LOWER] + stack3_curpos + 1; i <= stack3_range[UPPER]; i++)
std::cout<<" "<<static_cast<int>(array[i]);
std::cout<<"\n";
}
int main()
{
CStack stack;
std::cout<<"adding: ";
for(uint8_t i = 1; i < 10; i++)
{
std::cout<<" "<<static_cast<int>(i);
stack.push(i);
}
std::cout<<"\n";
stack.print();
stack.pop();
stack.print();
return 0;
}
Perhaps you can implement N number of stacks or queues in the single array. My defination of using single array is that we are using single array to store all the data of all the stacks and queues in the single array, anyhow we can use other N array to keep track of indices of all elements of particular stack or queue.
solution :
store data sequentially to in the array during the time of insertion in any of the stack or queue. and store it's respective index to the index keeping array of that particular stack or queue.
for eg : you have 3 stacks (s1, s2, s3) and you want to implement this using a single array (dataArray[]). Hence we will make 3 other arrays (a1[], a2[], a3[]) for s1, s2 and s3 respectively which will keep track of all of their elements in dataArray[] by saving their respective index.
insert(s1, 10) at dataArray[0] a1[0] = 0;
insert(s2, 20) at dataArray[1] a2[0] = 1;
insert(s3, 30) at dataArray[2] a3[0] = 2;
insert(s1, 40) at dataArray[3] a1[1] = 3;
insert(s3, 50) at dataArray[4] a3[1] = 4;
insert(s3, 60) at dataArray[5] a3[2] = 5;
insert(s2, 30) at dataArray[6] a2[1] = 6;
and so on ...
now we will perform operation in dataArray[] by using a1, a2 and a3 for respective stacks and queues.
to pop an element from s1
return a1[0]
shift all elements to left
do similar approach for other operations too and you can implement any number of stacks and queues in the single array.