Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
52
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.34 KB | None | 0 0
  1. package sg.edu.nus.cs2020.ps3;
  2.  
  3. import java.util.ArrayList;
  4. import java.util.Collections;
  5. import java.util.List;
  6.  
  7. /* Assumptions:
  8.  * Let the class implementing the IRUNwaySearch be RunwayNode
  9.  * keySuccessor and keyPredecessor returns -1 when the data cannot be found, instead of having errors
  10.  * dataSearch, dataSuccessor, dataPredecessor returns null when the data cannot be found, instead of having errors
  11.  * Standard errors are handled at a higher level,   functions returning int with errors returns -1,
  12.  *                                                  functions returning Objects with errors returns null
  13.  */
  14.  
  15. public class Scheduler implements IRunwayScheduler {
  16.     //The root node of of the tree, initialized as null
  17.     private RunwayNode node;
  18.    
  19.     //Helper to ensure that the input of time is non-negative
  20.     private boolean isValidTiming(int time) {
  21.         if (time < 0) {
  22.             System.out.println("Invalid Timing: Input time cannot be negative");
  23.             return false;
  24.         }
  25.         if (time > 10080) {
  26.             System.out.println("Invalid Timing: Input time is beyond the current week");
  27.             return false;
  28.         }
  29.         return true;
  30.     }
  31.    
  32.     /* Helper function to check if a timing is safe
  33.      * by checking if the successor of time - 3 is within 3 min of input time
  34.      */
  35.     private boolean isSafeTiming(int time) {
  36.         //If time entered is -ve, stop
  37.         if (!isValidTiming(time))
  38.             return false;
  39.        
  40.         //If there are no scheduled planes
  41.         if (node == null)
  42.             return true;
  43.        
  44.         //If the successor of the virtual node at time-3 clashes...
  45.         int clash = node.keySuccessor(time - 3);
  46.         //If there is no successor at all, then definitely safe
  47.         if (clash == -1)
  48.             return true;
  49.        
  50.         //Check if the successor clashes with the suggested time
  51.         return (Math.abs(clash - time) < 3) ?
  52.                 false : true;
  53.     }
  54.    
  55.     @Override
  56.     public boolean requestTimeSlot(int time, String pilot) {
  57.         //If invalid input, reject
  58.         if (!isValidTiming(time))
  59.             return false;
  60.        
  61.         //If there are no scheduled planes
  62.         if (node == null) {
  63.             node = new RunwayNode(time, pilot, null);
  64.             return true;
  65.         }
  66.         //If the timing is not safe, reject
  67.         if (!isSafeTiming(time))
  68.             return false;
  69.         //Else, insert the node and return true
  70.         node.insert(time, pilot);
  71.         return true;
  72.     }
  73.  
  74.     /* There are 4 conditions for getNextFreeSlot
  75.      * -> The suggested timing is clear, return the suggested timing
  76.      * -> The suggested timing is a right border case
  77.      * -> There is a free timing between both the prev and the next that is not before the suggested timing
  78.      * -> Have to look for a timing after the next plane lands
  79.      */
  80.     @Override
  81.     public int getNextFreeSlot(int time) {
  82.         //If the input data is invalid, reject and return sentinel value
  83.         if (!isValidTiming(time))
  84.             return -1;
  85.         //If the timing is safe, or there are no scheduled planes, definitely free
  86.         if (node == null || isSafeTiming(time))
  87.             return time;
  88.        
  89.         int next = node.keySuccessor(time);
  90.         int prev = node.keyPredecessor(time);
  91.        
  92.         //Right Border case
  93.         if (next == -1)
  94.             if (node.search(time)) //The right edge is at time, so return time+3
  95.                 return time + 3;
  96.             else //The right edge is at prev, so return prev.time+3
  97.                 return prev + 3;
  98.  
  99.            
  100.         if (node.search(time) ||         //there is a plane scheduled exactly on the suggested time
  101.                 prev == -1 ||            //left border case
  102.                 next- time < 3 ||   //there is not enough between the suggested time and the next plane's landing time
  103.                 next - prev < 6) {  //no space to fit between both the prev and next time
  104.             int current = next;
  105.             next = node.keySuccessor(current);
  106.            
  107.             //Find a case where there is a 6 or more minute gap between 2 nodes, or the right border case is reached
  108.             //Which means continue until right is not null, and the gap between next and current is less than 6
  109.             while (next != -1 && next - current < 6) {
  110.                 current = next;
  111.                 next = node.keySuccessor(current);
  112.             }
  113.             //return closest time after current
  114.             return current + 3;
  115.         }
  116.         //Can fit between both, and suggested time was too close to prev, so return closest possible time after prev
  117.         return prev + 3;
  118.     }
  119.  
  120.     @Override
  121.     public int getNextPlane(int time) {
  122.         //If the input data is invalid, return sentinel
  123.         if (!isValidTiming(time))
  124.             return -1;
  125.         //If there are no scheduled planes, return sentinel
  126.         if (node == null) {
  127.             System.out.println("There are no scheduled planes");
  128.             return -1;
  129.         }
  130.        
  131.         int next = node.keySuccessor(time);
  132.         //If there is no next plane, notify and return sentinel value
  133.         if (next == -1)
  134.             System.out.println("There are no records beyond " + time);
  135.         return next;
  136.     }
  137.  
  138.     @Override
  139.     public String getPilot(int time) {
  140.         //Reject invalid input and return sentinel value
  141.         if (!isValidTiming(time))
  142.             return null;
  143.         //If there are no scheduled planes, return sentinel
  144.         if (node == null) {
  145.             System.out.println("There are no scheduled planes");
  146.             return null;
  147.         }
  148.         //Find the Plane using the key
  149.         String search = node.dataSearch(time);
  150.        
  151.         //If no plane is scheduled for the time, return sentinel value
  152.         if (search == null)
  153.             System.out.println("Unable to find a plane scheduled for " + time);
  154.  
  155.         //Finally, return the pilot
  156.         return search;
  157.     }
  158.     @Override
  159.     public List<String> getPilots() {
  160.         List<String> ans = new ArrayList<String>();
  161.         //If there are no scheduled planes, so return an empty arraylist
  162.         if (node == null) {
  163.             System.out.println("There are no scheduled planes");
  164.             return ans;    
  165.         }
  166.         //Since time starts from 0, this gets the first entry (based on key)
  167.         int plane = node.keySuccessor(-1);
  168.        
  169.         //Keep track of the pilots to prevent duplicate entries
  170.         int pilotCount = 0;
  171.    
  172.         //Keep finding the successor until null
  173.         while (plane != -1) {
  174.             boolean repeat = false;
  175.             String pilotName = node.dataSearch(plane);
  176.            
  177.             //Check if the new pilot is already in the list
  178.             for (int i=0;i<pilotCount;i++)
  179.                 if (ans.get(i) == pilotName) {
  180.                     repeat = true;
  181.                     //Escape as a repeat has been found
  182.                     break;
  183.                 }
  184.             //Add the new pilot to the list if it's not a duplicate
  185.             if (repeat == false) {
  186.                 ans.add(pilotName);
  187.                 pilotCount++;
  188.             }
  189.             plane = node.keySuccessor(plane);
  190.         }
  191.         //The question asks for the list to be alphabetically sorted
  192.         Collections.sort(ans);
  193.         return ans;
  194.     }
  195.     @Override
  196.     public List<Integer> getPilotSchedule(String pilot) {
  197.         List<Integer> ans = new ArrayList<Integer>();
  198.         //If there are no scheduled planes, so return an empty arraylist
  199.         if (node == null) {
  200.             System.out.println("There are no scheduled planes");
  201.             return ans;    
  202.         }
  203.        
  204.         //Since time starts from 0, this gets the first entry (based on key)
  205.         int plane = node.keySuccessor(-1);
  206.  
  207.         //Keep finding the successor until null    
  208.         while (plane != -1) {
  209.             //If the data is from that pilot, add it to the list
  210.             if (node.dataSearch(plane) == pilot)
  211.                 ans.add(plane);
  212.             plane = node.keySuccessor(plane);
  213.         }
  214.        
  215.         if (ans.isEmpty())
  216.             System.out.println("Unable to find any planes piloted by " + pilot);
  217.         return ans;
  218.     }
  219.    
  220.     public static void main(String[] args) {
  221.        
  222.         //Sample given in question
  223.         Scheduler schedule = new Scheduler();
  224.        
  225.         boolean answer = schedule.requestTimeSlot(300, "Seth");             // Request slot 300
  226.         System.out.println("Answer: " + (answer? "Success!" : "Failure!")); // Success!
  227.            
  228.         answer = schedule.requestTimeSlot(400, "Steven");                   // Request slot 400
  229.         System.out.println("Answer: " + (answer? "Success!" : "Failure!")); // Success!
  230.    
  231.         answer = schedule.requestTimeSlot(302, "Steven");                   // Request slot 302
  232.         System.out.println("Answer: " + (answer? "Success!" : "Failure!")); // Failure!
  233.        
  234.         answer = schedule.requestTimeSlot(398, "Seth");                     // Request slot 398
  235.         System.out.println("Answer: " + (answer? "Success!" : "Failure!")); // Failure!
  236.        
  237.         int nextFree = schedule.getNextFreeSlot(398);                       // When can I land?
  238.         System.out.println("Next free slot: " + nextFree);                  // I can land at 403
  239.        
  240.         answer = schedule.requestTimeSlot(nextFree, "Seth");                // Request next free slot
  241.         System.out.println("Answer: " + (answer? "Success!" : "Failure!")); // Success!
  242.        
  243.         int nextPlane = schedule.getNextPlane(350);                         // When is the next plane landing?
  244.         System.out.println("Next plane: " + nextPlane);                     // At time=400
  245.        
  246.         String pilot = schedule.getPilot(nextPlane);                        // Who is landing then?
  247.         System.out.println("Next pilot: " + pilot);                         // Steven is landing at 400
  248.        
  249.         List<String> pilots = schedule.getPilots();                         // List all the pilots
  250.         for (int i=0;i<pilots.size();i++)
  251.             System.out.println("Pilot " + pilots.get(i));
  252.         // Outputs Seth and Steven (in sorted order, alphabetically)
  253.        
  254.         List<Integer> landingTimes = schedule.getPilotSchedule("Seth");     // When is Seth landing?
  255.         for (int i=0;i<landingTimes.size();i++)
  256.             System.out.println("Time: " + landingTimes.get(i));
  257.         // Outputs that Seth is landing at slot 300 and 403.
  258.        
  259.         //Displays the tree that stores the thing, for fun, only works for my RunwayNode
  260.         System.out.println("\n----- Tree -----");
  261.         schedule.node.displayTree();
  262.         /*   ----- Tree -----
  263.             300-Seth  
  264.             Empty   400-Steven  
  265.             Empty   Empty   Empty   403-Seth   */
  266.        
  267.         //My test cases
  268.         Scheduler test = new Scheduler();
  269.  
  270.         //Invalid input / Empty node tests
  271.         System.out.println("\n\n\n");
  272.         System.out.println("1a: test.getNextFreeSlot(-1): " + test.getNextFreeSlot(-1));                //Error message and -1
  273.         System.out.println("1b: test.getNextPlane(-1): " + test.getNextPlane(-1));                      //Error message and -1
  274.         System.out.println("1c: test.getPilot(-1): " + test.getPilot(-1));                              //Error message and null
  275.         System.out.println("1d: test.requestTimeSlot(-1, <me>): " + test.requestTimeSlot(-1, "me"));    //Error message and false
  276.  
  277.         System.out.println("\n\n");
  278.        
  279.         System.out.println("2a: test.getPilots(): " + test.getPilots());                                //Empty nodes message and blank array of int
  280.         System.out.println("2b: test.getNextFreeSlot(5): " + test.getNextFreeSlot(5));                  //Returns 5
  281.         System.out.println("2c: test.getNextPlane(0): " + test.getNextPlane(0));                        //Empty nodes message and -1
  282.         System.out.println("2d: test.getPilot(5): " + test.getPilot(5));                                //Empty nodes message and null
  283.         System.out.println("2e: test.getPilotSchedule(<>): " + test.getPilotSchedule(""));              //Empty nodes message and blank array of string
  284.         System.out.println("2f: test.getPilotSchedule(<me>): " + test.getPilotSchedule("me"));          //Empty nodes message and blank array of string
  285.  
  286.         System.out.println("\n\n");
  287.        
  288.         //RequestTimeSlot tests    
  289.         //Add first node and check tree
  290.         System.out.println("3a: test.requestTimeSlot(50, <me>): " + test.requestTimeSlot(50, "me"));    //True
  291.         test.node.displayTree();
  292.         System.out.println();
  293.        
  294.         //Clash testing and add more nodes
  295.         for (int i = 47; i <= 53; i++)
  296.             System.out.println("3b: test.requestTimeSlot(" + i + ", <test>): " + test.requestTimeSlot(i, "test"));
  297.         //True for 47 and 53 only
  298.  
  299.         //Adding to tree for next test:
  300.         System.out.println("Adding time <41>: " + test.requestTimeSlot(41, "left"));
  301.         System.out.println("Adding time <59>: " + test.requestTimeSlot(59, "right"));
  302.        
  303.         test.node.displayTree();
  304.         System.out.println();      
  305.        
  306.        
  307.         //Current list: 41, 47, 50, 53, 59
  308.         //getNextFreeSlot Testing
  309.  
  310.         //Right border cases
  311.         System.out.println("4a: test.getNextFreeSlot(60): " + test.getNextFreeSlot(60)); //62
  312.         System.out.println("4a: test.getNextFreeSlot(59): " + test.getNextFreeSlot(59)); //62
  313.        
  314.         //Can fit exactly case
  315.         System.out.println("4a: test.getNextFreeSlot(56): " + test.getNextFreeSlot(56)); //56
  316.        
  317.         //Too close to left, but can fit if pushed right a bit
  318.         System.out.println("4a: test.getNextFreeSlot(42): " + test.getNextFreeSlot(42)); //44
  319.    
  320.         //Totally no space, search for next space
  321.         System.out.println("4a: test.getNextFreeSlot(49): " + test.getNextFreeSlot(49)); //56  
  322.         System.out.println("4a: test.getNextFreeSlot(50): " + test.getNextFreeSlot(50)); //56
  323.         System.out.println("4a: test.getNextFreeSlot(40): " + test.getNextFreeSlot(40)); //44
  324.        
  325.        
  326.         //Pilots are left, me, right and test respectively, in alphabetic order
  327.         System.out.println(test.getPilots());
  328.  
  329.         //Test getNextPlane and getPilot together
  330.         System.out.println(test.getPilot(test.getNextPlane(40))); //left
  331.        
  332.         //Test getPilotSchedule
  333.         System.out.println(test.getPilotSchedule("test")); //47 and 53
  334.         System.out.println(test.getPilotSchedule("fake")); //unable to find notification and empty arraylist
  335.     }  
  336. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement