/* * Deque Work stealing problem for CSC 3102 Portfolio */ /* * --REQUIRED METHODS-- * Store(int numLines, int numCustomers) * Customer() * Line() * Enq_back() * Deq_back() * Deq_front() * * --I IMPLEMENTED-- * Restructure() -> makes sure no line has >2 customer in it * TimeSlice() -> Each customer at front of their line scans one item * PrintStore() -> prints each line and the number of items each customer has */ using DequeWSProblem_3102; namespace DequeWSProblem_3102 { public class Customer { public int items; public Customer? next, prev; public Customer() { items = new Random().Next(5, 26); next = null; prev = null; } } public class Line { public Customer? front, back; public Line? nextLine, prevLine; public int sizeOfLine; public Line() { sizeOfLine = 0; front = null; back = null; } /* * Adds a customer to the back of the specified line * This is used in the Store.Enq_Back() function */ public void Enque_Back() { if (front == null) { Customer newCustomer = new Customer(); front = newCustomer; back = newCustomer; } else { Customer newCustomer = new Customer(); newCustomer.next = back; back.prev = newCustomer; back = newCustomer; } sizeOfLine++; } /* * Removes a customer from the back of the specified line * This is used in the Store.Deq_Back() function */ public void Deque_Back() { if (front == null) { return; } else if (sizeOfLine == 1) { front = null; back = null; sizeOfLine = 0; } else { back = back.next; back.prev.next = null; back.prev = null; sizeOfLine--; } } /* * Dequeues the customer at the front of the specified line */ public void Dequeue_Front() { if (front == null) { return; } else if (sizeOfLine == 1) { front = null; back = null; sizeOfLine = 0; } else { front = front.prev; front.next.prev = null; front.next = null; sizeOfLine--; } } } public class Store { public Line? firstLine, lastLine; public int numLines, numCustomers; /* * default constructor for the store class * @numlines - the number of lines you want the store to have * @numCustomers - the number of customers in the store at time of creation */ public Store(int numLines, int numCustomers) { this.numLines = numLines; this.numCustomers = numCustomers; for (int i = 0; i < numLines; i++) { Line line = new Line(); if (i == 0) { firstLine = line; lastLine = line; } else { line.prevLine = lastLine; lastLine.nextLine = line; lastLine = line; } } for (int i = 0; i < numCustomers; i++) { int whichLine = new Random().Next(numLines); var tempLine = firstLine; for (int j = 0; j < whichLine; j++) { tempLine = tempLine.nextLine; } tempLine.Enque_Back(); } this.Restructure(); } /* * Adds a customer to the back of a random line in the store */ public void Enq_Back() { int whichLine = new Random().Next(numLines); var tempLine = firstLine; for (int i = 0; i < whichLine; i++) { tempLine = tempLine.nextLine; } tempLine.Enque_Back(); numCustomers++; this.Restructure(); } /* * Removes a customer from the back of a random line in the store */ public void Deq_Back() { int whichLine = new Random().Next(numLines); var tempLine = firstLine; for (int i = 0; i < whichLine; i++) { tempLine = tempLine.nextLine; } tempLine.Deque_Back(); numCustomers--; this.Restructure(); } /* * Removes the customer at the beginning of a random line */ public void Deq_Front() { int whichLine = new Random().Next(numLines); var tempLine = firstLine; for (int i = 0; i < whichLine; i++) { tempLine = tempLine.nextLine; } tempLine.Dequeue_Front(); numCustomers--; this.Restructure(); } /* * Checks if a line in the store is empty, if so, takes from a line that has >2 customers in it */ public void Restructure() { var tempLine = firstLine; for (int i = 0; i < numLines; i++) //looks through every line to see if there is one that is empty { if(tempLine.sizeOfLine != 0) { tempLine = tempLine.nextLine; } else //finds a line that is empty { var checkLine = firstLine; for (int j = 0; j < numLines; j++) //looks to see if there is a line with >=2 customers than tempLine { if (checkLine.sizeOfLine >= (tempLine.sizeOfLine + 2)) //finds line with >=2 customers than tempLine { while (checkLine.sizeOfLine >= tempLine.sizeOfLine + 2) { if (tempLine.sizeOfLine == 0) { tempLine.front = checkLine.back; tempLine.back = tempLine.front; checkLine.back = checkLine.back.next; checkLine.back.prev = null; tempLine.front.next = null; checkLine.sizeOfLine--; tempLine.sizeOfLine++; } else { tempLine.back = checkLine.back; checkLine.back = checkLine.back.next; checkLine.back.prev = null; var tmp = tempLine.front; while (tmp.prev != null) //tmp will be the last node in the temp Line { tmp = tmp.prev; } tmp.prev = tempLine.back; tempLine.back.next = tmp; checkLine.sizeOfLine--; tempLine.sizeOfLine++; } } break; //breaks from the for loop that found the empty line } else { checkLine = checkLine.nextLine; } } } } } /* * prints each each line, and the amount of customers each have in the line */ public void PrintStore() { var tempLine = firstLine; for (int i = 0; i < numLines; i++) { Console.WriteLine("Line #" + (i + 1)); var tempCustomer = tempLine.front; for (int j = 0; j < tempLine.sizeOfLine; j++) { Console.Write(tempCustomer.items + " "); tempCustomer = tempCustomer.prev; } Console.WriteLine(); tempLine = tempLine.nextLine; } Console.WriteLine(); } /* * Passes one unit of time in our store, so each line will scan one item */ public void TimeSlice() { var tempLine = firstLine; for (int i = 0; i < numLines; i++) { if (tempLine.front == null) //shouldn't happen unless store is empty, or very few people are in the store { Restructure(); tempLine = tempLine.nextLine; } else { if (tempLine.front.items == 0) //shouldn't happen, but handles case where customer has no items { tempLine.Dequeue_Front(); tempLine = tempLine.nextLine; } else { tempLine.front.items--; if (tempLine.front.items == 0) { tempLine.Dequeue_Front(); } tempLine = tempLine.nextLine; } } } } } }