Advertisement
vladimirVenkov

Supermarket Queue fast and heavy

Jul 24th, 2018
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.63 KB | None | 0 0
  1. /*
  2. In a supermarket we have a very long queue of people. Usually the people are served in the order of their coming. When someone comes, he / she is appended at the end of the queue. When someone is served, he / she is removed from the front of the queue. Sometimes and old lady comes and the waiting people make a place for her somewhere in the queue. Because the queue could become very long (e.g. few thousand people), the supermarket management organizes a lottery and draws a random name from time to time. After each lottery draw, the management wants to know how many persons having the winning name are currently waiting in the queue.
  3.  
  4. Your task is to write a program to help the supermarket to handle the supermarket queue. It should hold a queue of N items numbered from 0 to N-1, where 0 is the front of the queue and N-1 is the position of the last person (end of the queue). A sample queue is given below:
  5.  
  6. position    0   1   2   3   4   5   6
  7. name    Peter   Mike    Penka   Doncho  Nakov   Asya    Nakov
  8. Your program should be able to process a sequence of the following commands:
  9.  
  10. Append [name] – appends a person with the specified name at the end of the queue. As a result the command prints " OK".
  11. Insert [position] [name] – inserts a person with the specified name at the specified position in the queue (position 0 is just before the first person of the queue and position N is just after the last). In case of success, as a result the command prints " OK". In case the position is invalid, the command does nothing and prints " Error" as a result.
  12. Find [name] – finds how many people with the specified name are currently waiting in the queue. As a result the command prints an integer number ( 0 or more ).
  13. Serve [count] – serves the specified count of people according to their order in the queue. The served people are removed from the front of the queue. In case of success, as a result, the command prints the names of the served people in format "[name1] [name2] …" (at a single line, separated by space, ordered as in the queue). In case the count is invalid (bigger than the number of people in the queue), the command does nothing and prints " Error" as a result.
  14. End – indicates the end of the input commands. Prints nothing and stops the program execution. This command appears only once, at the end of the input sequence of commands.
  15. */
  16.  
  17.  
  18.  
  19. import java.io.BufferedReader;
  20. import java.io.IOException;
  21. import java.io.InputStreamReader;
  22. import java.util.*;
  23.  
  24. public class SupermarketQueue {
  25.  
  26.     public static void main(String[] args) throws IOException {
  27.         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  28.  
  29.         //Que que = new Que();
  30.         Que2 que2 = new Que2();
  31.  
  32.         while (true) {
  33.             String command = br.readLine();
  34.             if (command.equals("End")) {
  35.                 break;
  36.             }
  37.             //call(command, que); //TODO to run simple 11/16 tests solution (much more simple!!!)
  38.             call(command, que2);
  39.         }
  40.     }
  41.  
  42.     private static void call(String command, Que2 que) {
  43.         String[] temp = command.split(" ");
  44.         switch (temp[0]) {
  45.             case "Append": que.append(temp[1]); return;
  46.             case "Insert": que.insert(temp[2], Integer.parseInt(temp[1])); return;
  47.             case "Serve" : que.serve(Integer.parseInt(temp[1])); return;
  48.             case "Find"  : que.findName(temp[1]); return;
  49.             default: return;
  50.         }
  51.     }
  52.     private static class Que{ //TODO "simple" solution -> 11/16 TLE
  53.         List<String> queue;
  54.         Map<String, Integer> namesCount;
  55.  
  56.         private Que() {
  57.             queue = new LinkedList<>(); //fast add at the end and ability to add at index (slow) -> simple
  58.             namesCount = new HashMap<>(); //fast check for names and update
  59.         }
  60.  
  61.         private void append(String name) {
  62.             queue.add(name);
  63.             namesCount.put(name,namesCount.getOrDefault(name, 0) + 1); //combined update/or add name
  64.             System.out.println("OK");
  65.  
  66.         }
  67.  
  68.         private void insert(String name, int position) {
  69.             if (position < 0 || position > queue.size()) { //error check
  70.                 System.out.println("Error");
  71.                 return;
  72.             }
  73.             queue.add(position, name);
  74.             namesCount.put(name,namesCount.getOrDefault(name, 0) + 1);
  75.             System.out.println("OK");
  76.         }
  77.  
  78.         private void findName(String name) {
  79.             System.out.println(namesCount.getOrDefault(name, 0)); //name check returns 0 if no key (name) present
  80.         }
  81.  
  82.         private void serve(int count) {
  83.             if (count > queue.size()) {
  84.                 System.out.println("Error");
  85.                 return;
  86.             }
  87.             int counter = count;
  88.             while (counter > 1) {
  89.                 String served = queue.get(0);
  90.                 queue.remove(0);
  91.                 System.out.print(served + " ");
  92.                 namesCount.put(served, namesCount.get(served) - 1);
  93.                 --counter;
  94.             }
  95.             String served = queue.get(0); //this part is to leave last name without " " space behind it.
  96.             queue.remove(0);        // not needed as it appears !
  97.             System.out.print(served);
  98.             System.out.println();
  99.             namesCount.put(served, namesCount.get(served) - 1);
  100.         }
  101.     }
  102.  
  103.     private static class Que2 { //much more complex TODO to be simplified but 16/16
  104.         private ArrayList<ArrayList<String>> queue;
  105.         private Map<String, Integer> namesCount; //for names (see Queue above)
  106.         int currentIndex; //elements are NOT removed from the long queue !!! therefore no reindexing
  107.         // but need to save current beggining of the queue
  108.         int size; //same as above -> we need to save and update "real" size of the queue!
  109.  
  110.         private Que2() {
  111.             queue = new ArrayList<>();
  112.             namesCount = new HashMap<>();
  113.             currentIndex = 0;
  114.         }
  115.         private void append(String name) {
  116.             ArrayList<String> toAdd = new ArrayList<>(); //next elements are added on the index "0" in new arraylist
  117.             //insert call puts elements in those arraylists instead of reindexing (fast but complicated ...)
  118.             toAdd.add(name);
  119.             queue.add(toAdd);
  120.             ++size;
  121.             namesCount.put(name,namesCount.getOrDefault(name, 0) + 1);
  122.             System.out.println("OK");
  123.  
  124.         }
  125.  
  126.         private void insert(String name, int position) {
  127.             if (position < 0 || position > size) {
  128.                 System.out.println("Error");
  129.                 return;
  130.             }
  131.             if (position == size) { //if this is true directly append at the end of the queue
  132.                 append(name);
  133.                 return;
  134.             }
  135.             if (position == 0) { //insert on "0" position
  136.                 if (size == 0) { //if all till now were served "start" new que by appending at the end
  137.                     append(name);
  138.                     return;
  139.                 } else {
  140.                     queue.get(currentIndex).add(name);//TODO insert on position "0" in non-Empty queue adds the element
  141.                     //TODO  at the end!!! of arraylist currently on this index in queue!
  142.                     //TODO if we have {Ana, Peter, Joro} in the list on "0" position in the que (this is product from previous insertions)
  143.                     //TODO we are adding next name at the END of this list!
  144.                     //TODO later we will see that last elements are served first!
  145.                     //TODO this is all to avoid reindexing in arraylist (slow operation)
  146.                     ++size;
  147.                     namesCount.put(name,namesCount.getOrDefault(name, 0) + 1);
  148.                     System.out.println("OK");
  149.                     return;
  150.                 }
  151.             }
  152.  
  153.             int placeToAdd = currentIndex;
  154.             int counter = position;
  155. //TODO we need to find where to add if position is > 0
  156. //TODO many elements of the queue may have size more than 1 because previous insertions!            
  157.             for (int i = placeToAdd; i < queue.size(); i++) { //we start from current beginning of the que
  158.                 int size = queue.get(i).size();
  159.                 if (counter >= size) { //if current element in the queue has smaller size than the desired position
  160.                     counter -= size; //lower position and go to next element
  161.                     continue;
  162.                 }
  163.                 if (counter == 0) { //we should add at the top(end) of current element! (faster)
  164.                     queue.get(i).add(name);//we should not append as there are elemnts behind current
  165.                     ++this.size; //appending is covered upper in the method
  166.                     namesCount.put(name,namesCount.getOrDefault(name, 0) + 1);
  167.                     System.out.println("OK");
  168.                     return;
  169.                 }
  170.                 queue.get(i).add(size - counter, name); //if we need to add it on position different that last
  171.                 ++this.size;                                //linear time but seems unavoidable???
  172.                 namesCount.put(name,namesCount.getOrDefault(name, 0) + 1);//TODO consider optimisations! As the code is heavy and sorta ugly? :)
  173.                 System.out.println("OK");
  174.                 return;
  175.             }
  176.         }
  177.  
  178.         private void findName(String name) {
  179.             System.out.println(namesCount.getOrDefault(name, 0));//see Que 1
  180.         }
  181.  
  182.         private void serve(int count) {
  183.             if (count > size) {
  184.                 System.out.println("Error");
  185.                 return;
  186.             }
  187.             int counter = count;
  188.             while (counter > 0) {
  189.                 ArrayList<String> served = queue.get(currentIndex); //get current element in the queue (may have more than one names in it!)
  190.                 while (!served.isEmpty() && counter > 0) { //counter may become "0" before served is empty!!!
  191.                     int last = served.size() - 1;
  192.                     String name = served.get(last);
  193.                     served.remove(last);//remove from the end -> fast
  194.                     System.out.print(name + " ");//last name will have space behind -> works
  195.                     namesCount.put(name, namesCount.get(name) - 1);//reduce names count
  196.                     --size;//update size, as we are lowering the queue!
  197.                     --counter;
  198.                     if (served.isEmpty()) { //if isEmpty -> go to next element in the queue
  199.                         ++currentIndex;
  200.                     }
  201.                 }
  202.             }
  203.             System.out.println();
  204.         }
  205.     }
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement