feat: change up organisation

This commit is contained in:
2023-04-24 11:02:37 +08:00
parent 13f372ec5a
commit dd56398b7d
378 changed files with 4653 additions and 107 deletions

53
labs/cs2030s/Lab1/Array.java Executable file
View File

@@ -0,0 +1,53 @@
/**
* The Array for CS2030S
*
* @author Yadunand Prem
* @version CS2030S AY21/22 Semester 2
*/
class Array<T extends Comparable<T>> {
private T[] array;
public Array(int size) {
// The only way to add values to `array` is via set(), and we can only put
// objects of type T via that method. Thus, it is safe to cast Comparable[]
// to T[].
@SuppressWarnings("unchecked")
T[] temp = (T[]) new Comparable[size];
this.array = temp;
}
public void set(int index, T item) {
this.array[index] = item;
}
public T get(int index) {
return this.array[index];
}
public T min() {
T result = this.array[0];
for (T i : this.array) {
if (i.compareTo(result) < 0) {
result = i;
}
}
return result;
}
public int length() {
return this.array.length;
}
@Override
public String toString() {
StringBuilder s = new StringBuilder("[ ");
for (int i = 0; i < array.length; i++) {
s.append(i + ":" + array[i]);
if (i != array.length - 1) {
s.append(", ");
}
}
return s.append(" ]").toString();
}
}

View File

@@ -0,0 +1,64 @@
class ArrayTest {
public static void main(String[] args) {
CS2030STest i = new CS2030STest();
Array<Integer> a = new Array<Integer>(4);
i.expect("initializing an empty array",
a.toString(), "[ 0:null, 1:null, 2:null, 3:null ]");
a.set(0, 3);
i.expect("set element 0 to 3",
a.toString(), "[ 0:3, 1:null, 2:null, 3:null ]");
a.set(1, 4);
i.expect("set element 1 to 4",
a.toString(), "[ 0:3, 1:4, 2:null, 3:null ]");
a.set(2, 1);
i.expect("set element 2 to 1",
a.toString(), "[ 0:3, 1:4, 2:1, 3:null ]");
a.set(3, 6);
i.expect("set element 3 to 6",
a.toString(), "[ 0:3, 1:4, 2:1, 3:6 ]");
i.expect("get element 0",
a.get(0), 3);
i.expect("get element 1",
a.get(1), 4);
i.expect("get element 2",
a.get(2), 1);
i.expect("get element 3",
a.get(3), 6);
i.expect("smallest element is 1",
a.min(), 1);
i.expect("a.min() does not change the array",
a.toString(), "[ 0:3, 1:4, 2:1, 3:6 ]");
a.set(2, 9);
i.expect("update element 2 to 9",
a.toString(), "[ 0:3, 1:4, 2:9, 3:6 ]");
i.expect("smallest element is now 3",
a.min(), 3);
i.expectCompile("cannot put a non-integer into an array of integer",
"new Array<Integer>(4).set(0, false)", false);
i.expectCompile("cannot get a non-integer from an array of integer",
"String s = new Array<Integer>(4).get(0)", false);
i.expectCompile("cannot create an array of non-comparable element",
"class A {} Array<A> a;", false);
i.expectCompile("cannot create an array of comparable element (but not to itself)",
"class A implements Comparable<Long> {" +
" public int compareTo(Long i) {" +
" return 0; " +
" }" +
"}" +
"Array<A> a;", false);
i.expectCompile("can create an array of comparable element (to itself)",
"class A implements Comparable<A> {" +
" public int compareTo(A i) {" +
" return 0; " +
" }" +
"}" +
"Array<A> a;", true);
}
}

View File

@@ -0,0 +1,50 @@
/**
* The ArrivalEvent is an Event which handles the arrival of a customer
* It decides whether a customer should go into queue or go to a counter
* It also allocates a counter to the customer. This event thus returns either a
* DepartureEvent or a ServiceBeginEvent
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class ArrivalEvent extends Event {
private Customer customer;
private Shop shop;
public ArrivalEvent(Customer customer, Shop shop) {
super(customer.getArrivalTIme());
this.customer = customer;
this.shop = shop;
}
@Override
public Event[] simulate() {
ServiceCounter availableCounter = this.shop.getAvailableCounter();
// check if counters are available. If available, start service for that
// customer
if (availableCounter != null) {
return new Event[] {
new ServiceBeginEvent(this.getTime(), customer, shop, availableCounter) };
}
// if no counters available, check if queue slots avialable in counters
availableCounter = this.shop.findCounterWithQueue();
if (availableCounter != null) {
return new Event[] {
new JoinCounterQueueEvent(this.getTime(), this.customer, availableCounter)
};
}
// if shop queue isn't empty, join shop queue
if (!this.shop.isQueueFull()) {
return new Event[] { new JoinShopQueueEvent(customer, shop) };
}
return new Event[] { new DepartureEvent(this.getTime(), customer) };
}
@Override
public String toString() {
return String.format("%s: %s arrived %s", super.toString(), this.customer, this.shop);
}
}

View File

@@ -0,0 +1,77 @@
import java.net.URI;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
class CS2030STest {
public static final String ANSI_RESET = "\u001B[0m";
public static final String ANSI_RED = "\u001B[31m";
public static final String ANSI_GREEN = "\u001B[32m";
/**
* Test if two objects are equals.
*
* @param test A description of the test.
* @param output The output from an expression.
* @param expect The expected output from that expression.
* @return this object.
*/
public CS2030STest expect(String test, Object output, Object expect) {
System.out.print(test);
if ((expect == null && output == null) || output.equals(expect)) {
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
} else {
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
System.out.println(" expected: " + expect);
System.out.println(" got this: " + output);
}
return this;
}
/**
* Test if an expression compiles with/without error.
*
* @param test A description of the test.
* @param statement The java statement to compile
* @param success Whether the statement is expected to compile or not
* (true if yes; false otherwise)
* @return this object.
*/
public CS2030STest expectCompile(String test, String statement, boolean success) {
System.out.print(test);
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String code) {
super(URI.create("string:///TempClass.java"), Kind.SOURCE);
this.code = "class TempClass {void foo(){" + code + ";}}";
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
boolean noError = ToolProvider
.getSystemJavaCompiler()
.getTask(null, null, new DiagnosticCollector<>(), null, null,
List.of(new JavaSourceFromString(statement)))
.call();
if (noError != success) {
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
if (!success) {
System.out.println(" expected compilation error but it compiles fine.");
} else {
System.out.println(" expected the statement to compile without errors but it does not.");
}
} else {
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
}
return this;
}
}

View File

@@ -0,0 +1,34 @@
/**
* This is a data class which holds information about the Customer.
* It has a incrementing counter for the customer id;
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
public class Customer {
private static int lastId = 0;
private final int id;
private final double serviceTime;
private final double arrivalTIme;
public Customer(double serviceTime, double arrivalTime) {
this.id = lastId++;
this.serviceTime = serviceTime;
this.arrivalTIme = arrivalTime;
}
public double getServiceTime() {
return this.serviceTime;
}
public double getArrivalTIme() {
return arrivalTIme;
}
@Override
public String toString() {
return "C" + id;
}
}

View File

@@ -0,0 +1,28 @@
/**
* The DepartureEvent is an Event which handles the end of a service.
* It handles allocating customers in queue to a counter.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class DepartureEvent extends Event {
private Customer customer;
public DepartureEvent(double time, Customer customer) {
super(time);
this.customer = customer;
}
@Override
public String toString() {
return String.format("%s: %s departed", super.toString(), this.customer);
}
@Override
public Event[] simulate() {
// when customer departs, check if there are customers in queue
return new Event[] {};
}
}

View File

@@ -0,0 +1,72 @@
/**
* The Event class is an abstract class that encapsulates a
* discrete event to be simulated. An event encapsulates the
* time the event occurs. A subclass of event _must_ override
* the simulate() method to implement the logic of the
* simulation when this event is simulated. The simulate method
* returns an array of events, which the simulator will then
* add to the event queue. Note that an event also implements
* the Comparable interface so that a PriorityQueue can
* arrange the events in the order of event time.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
abstract class Event implements Comparable<Event> {
/** The time this event occurs in the simulation. */
private final double time;
/**
* Creates an event that occurs at the given time.
*
* @param time The time the event occurs.
*/
public Event(double time) {
this.time = time;
}
/**
* Getter to return the time of this event.
*
* @return The time this event occurs.
*/
public double getTime() {
return this.time;
}
/**
* Compare this event with a given event e.
*
* @param e The other event to compare to.
* @return 1 if this event occurs later than e;
* 0 if they occur the same time;
* -1 if this event occurs earlier.
*/
@Override
public int compareTo(Event e) {
if (this.time > e.time) {
return 1;
} else if (this.time == e.time) {
return 0;
} else {
return -1;
}
}
/**
* Return the string representation this event.
*
* @return A string consists of the time this event occurs.
*/
@Override
public String toString() {
return String.format("%.3f", this.time);
}
/**
* Simulate this event.
*
* @return An array of new events to be scheduled by the simulator.
*/
public abstract Event[] simulate();
}

View File

@@ -0,0 +1,23 @@
public class JoinCounterQueueEvent extends Event {
private Customer customer;
private ServiceCounter counter;
public JoinCounterQueueEvent(double time, Customer customer, ServiceCounter counter) {
super(time);
this.customer = customer;
this.counter = counter;
}
@Override
public Event[] simulate() {
this.counter.joinQueue(customer);
return new Event[] {};
}
@Override
public String toString() {
return String.format("%s: %s joined counter queue (at %s)",
super.toString(),
this.customer, this.counter);
}
}

View File

@@ -0,0 +1,24 @@
class JoinShopQueueEvent extends Event {
private Customer customer;
private Shop shop;
public JoinShopQueueEvent(Customer customer, Shop shop) {
super(customer.getArrivalTIme());
this.customer = customer;
this.shop = shop;
}
@Override
public Event[] simulate() {
this.shop.joinQueue(customer);
return new Event[] {};
}
@Override
public String toString() {
return String.format("%s: %s joined shop queue %s",
super.toString(),
this.customer, this.shop);
}
}

View File

@@ -0,0 +1,26 @@
import java.util.Scanner;
/**
* The main class for CS2030S Lab 1.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class Lab1 {
public static void main(String[] args) {
// Create a scanner to read from standard input.
Scanner sc = new Scanner(System.in);
// Create a simulation. The ShopSimulation
// constructor will read the simulation parameters
// and initial events using the scanner.
Simulation simulation = new ShopSimulation(sc);
// Create a new simulator and run the simulation
new Simulator(simulation).run();
// Clean up the scanner.
sc.close();
}
}

View File

@@ -0,0 +1,26 @@
import java.util.Scanner;
/**
* The main class for CS2030S Lab 1.
*
* @author Wei Tsang
* @version CS2030S AY20/21 Semester 2
*/
class Lab2 {
public static void main(String[] args) {
// Create a scanner to read from standard input.
Scanner sc = new Scanner(System.in);
// Create a simulation. The ShopSimulation
// constructor will read the simulation parameters
// and initial events using the scanner.
Simulation simulation = new ShopSimulation(sc);
// Create a new simulator and run the simulation
new Simulator(simulation).run();
// Clean up the scanner.
sc.close();
}
}

26
labs/cs2030s/Lab1/Lab3.java Executable file
View File

@@ -0,0 +1,26 @@
import java.util.Scanner;
/**
* The main class for CS2030S Lab 3.
*
* @author Wei Tsang
* @version CS2030S AY21/22 Semester 2
*/
class Lab3 {
public static void main(String[] args) {
// Create a scanner to read from standard input.
Scanner sc = new Scanner(System.in);
// Create a simulation. The ShopSimulation
// constructor will read the simulation parameters
// and initial events using the scanner.
Simulation simulation = new ShopSimulation(sc);
// Create a new simulator and run the simulation
new Simulator(simulation).run();
// Clean up the scanner.
sc.close();
}
}

View File

@@ -0,0 +1,17 @@
CLASSES := $(wildcard *.java)
default: classes
lab1:
java Lab1
lab2:
java Lab2
classes: $(CLASSES:.java=.class)
%.class : %.java
javac "$<"
clean:
$(RM) *.class

View File

@@ -0,0 +1,125 @@
/**
* The Queue class implements a simple FIFO data structure
* with limited capacity that can store any Object instances.
* Not to be confused with java.util.Queue.
*
* @author Yadunand Prem
* @version CS2030S AY21/22 Semester 2
*/
class Queue<T> {
/** An array to store the items in the queue. */
private T[] items;
/** Index of the first element in the queue. */
private int first;
/** Index of the last element in the queue. */
private int last;
/** Maximum size of the queue. */
private int maxSize;
/** Number of elements in the queue. */
private int len;
/**
* Constructor for a queue.
*
* @param size The maximum num of elements we can put in the queue.
*/
public Queue(int size) {
this.maxSize = size;
// The only way to add values to `items` is via enq(), and we can only put
// objects of type T via that method. Thus, it is safe to cast Comparable[]
// to T[].
@SuppressWarnings("unchecked")
T[] temp = (T[]) new Object[size];
this.items = temp;
this.first = -1;
this.last = -1;
this.len = 0;
}
/**
* Add the object e into the queue.
*
* @param e The item to put in the queue.
* @return false if the queue is full; true if e is added successfully.
*/
public boolean enq(T e) {
if (this.isFull()) {
return false;
}
if (this.isEmpty()) {
this.first = 0;
this.last = 0;
} else {
this.last = (this.last + 1) % this.maxSize;
}
this.items[last] = e;
this.len += 1;
return true;
}
/**
* Remove the object from the queue.
*
* @return null if the queue is empty; the object removed from the queue
* otherwise.
*/
public T deq() {
if (this.isEmpty()) {
return null;
}
T item = this.items[this.first];
this.first = (this.first + 1) % this.maxSize;
this.len -= 1;
return item;
}
/**
* Checks if the queue is full.
*
* @return true if the queue is full; false otherwise.
*/
boolean isFull() {
return (this.len == this.maxSize);
}
/**
* Checks if the queue is empty.
*
* @return true if the queue is empty; false otherwise.
*/
boolean isEmpty() {
return (this.len == 0);
}
/**
* Return the number of elements in the queue.
*
* @return The number of elements in the queue.
*/
public int length() {
return this.len;
}
/**
* Returns the string representation of the queue.
*
* @return A string consisting of the string representation of
* every object in the queue.
*/
@Override
public String toString() {
String str = "[ ";
int i = this.first;
int count = 0;
while (count < this.len) {
str += this.items[i] + " ";
i = (i + 1) % this.maxSize;
count++;
}
return str + "]";
}
}

View File

@@ -0,0 +1,23 @@
class QueueTest {
public static void main(String[] args) {
CS2030STest i = new CS2030STest();
Queue<Integer> q = new Queue<Integer>(2);
i.expect("insert 4 into a queue of integer",
q.enq(4), true);
i.expect("insert 8 into a queue of integer",
q.enq(8), true);
i.expect("insert 0 into a full queue",
q.enq(0), false);
i.expect("remove 4 from queue",
q.deq(), 4);
i.expect("remove 8 from queue",
q.deq(), 8);
i.expect("cannot deque anymore",
q.deq(), null);
i.expectCompile("cannot deque a non-integer from a queue of integer",
"String s = new Queue<Integer>(3).deq();", false);
i.expectCompile("cannot insert a non-integer into a queue of integer",
"new Queue<Integer>(3).enqueue(false);", false);
}
}

View File

@@ -0,0 +1,34 @@
/**
* The ServiceBeginEvent is an Event which handles the starting of a service.
* It handles occupying a counter and also generating a serviceEndEvent
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class ServiceBeginEvent extends Event {
private ServiceCounter counter;
private Customer customer;
private Shop shop;
public ServiceBeginEvent(double time, Customer customer, Shop shop, ServiceCounter counter) {
super(time);
this.customer = customer;
this.shop = shop;
this.counter = counter;
}
@Override
public String toString() {
return super.toString()
+ String.format(": %s service begin (by %s)", this.customer, this.counter);
}
@Override
public Event[] simulate() {
this.counter.occupy();
double endTime = this.getTime() + this.customer.getServiceTime();
return new Event[] {
new ServiceEndEvent(endTime, this.customer, this.shop, this.counter) };
}
}

View File

@@ -0,0 +1,64 @@
/**
* This is a data class which holds information about a counter. It has a
* incrementing counter for the conuter Id.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
public class ServiceCounter implements Comparable<ServiceCounter> {
private static int lastId;
private final int id;
private boolean available;
private Queue<Customer> queue;
public boolean isAvailable() {
return available;
}
public void occupy() {
this.available = false;
}
public void free() {
this.available = true;
}
public boolean isQueueFull() {
return this.queue.isFull();
}
public boolean isQueueEmpty() {
return this.queue.isEmpty();
}
public void joinQueue(Customer customer) {
this.queue.enq(customer);
}
public Customer leaveQueue() {
return this.queue.deq();
}
public ServiceCounter(int queueSize) {
this.id = lastId++;
this.available = true;
this.queue = new Queue<Customer>(queueSize);
}
@Override
public String toString() {
return String.format("S%s %s", id, this.queue);
}
@Override
public int compareTo(ServiceCounter o) {
if (this.queue.length() < o.queue.length()) {
return -1;
}
if (this.id < o.id) {
return -1;
}
return 1;
}
}

View File

@@ -0,0 +1,58 @@
/**
* The ServiceEndEvent is an Event which handles the end of a service.
* It handles freeing the counter and also generating a departure event
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class ServiceEndEvent extends Event {
private ServiceCounter counter;
private Customer customer;
private Shop shop;
public ServiceEndEvent(double time, Customer customer, Shop shop, ServiceCounter counter) {
super(time);
this.customer = customer;
this.shop = shop;
this.counter = counter;
}
@Override
public String toString() {
return super.toString()
+ String.format(": %s service done (by %s)", this.customer, this.counter);
}
@Override
public Event[] simulate() {
// if there are customers in the counter queue, they will be serviced next.
// Customers in the shop queue will then be added to the counter queue
if (!this.counter.isQueueEmpty()) {
Customer serviceCustomer = this.counter.leaveQueue();
if (!this.shop.isQueueEmpty()) {
return new Event[] {
new DepartureEvent(this.getTime(), this.customer),
new ServiceBeginEvent(this.getTime(), serviceCustomer, this.shop, this.counter),
new JoinCounterQueueEvent(this.getTime(), this.shop.leaveQueue(), counter)
};
}
return new Event[] {
new DepartureEvent(this.getTime(), this.customer),
new ServiceBeginEvent(this.getTime(), serviceCustomer, this.shop, this.counter),
};
}
// There can also be the case where the counter queue may be empty but there are
// customers in the shop queue.
if (!this.shop.isQueueEmpty()) {
return new Event[] {
new DepartureEvent(this.getTime(), this.customer),
new ServiceBeginEvent(this.getTime(), this.shop.leaveQueue(), this.shop, this.counter),
};
}
// else there are no more customers in the queue, and the counter can be freed
this.counter.free();
return new Event[] { new DepartureEvent(this.getTime(), this.customer) };
}
}

View File

@@ -0,0 +1,67 @@
/**
* Shop is a data class which holds information about a shop.
* It stores the list of counters and the queue in which new customers can join.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
public class Shop {
private Array<ServiceCounter> counters;
private Queue<Customer> queue;
public Shop(int numOfCounters, int shopQueueSize, int counterQueueSize) {
this.counters = new Array<ServiceCounter>(numOfCounters);
for (int i = 0; i < numOfCounters; i++) {
this.counters.set(i, new ServiceCounter(counterQueueSize));
}
this.queue = new Queue<Customer>(shopQueueSize);
}
/**
* getAvailableCounter returns the first available counter it finds.
* If there are none, returns null
*
* @return the available counter or null if none found
*/
public ServiceCounter getAvailableCounter() {
for (int i = 0; i < this.counters.length(); i++) {
ServiceCounter counter = this.counters.get(i);
if (counter.isAvailable()) {
return counter;
}
}
return null;
}
public boolean isQueueFull() {
return this.queue.isFull();
}
public boolean isQueueEmpty() {
return this.queue.isEmpty();
}
public void joinQueue(Customer customer) {
this.queue.enq(customer);
}
public Customer leaveQueue() {
return this.queue.deq();
}
public ServiceCounter findCounterWithQueue() {
ServiceCounter minCounter = this.counters.min();
if (!minCounter.isQueueFull()) {
return minCounter;
}
return null;
}
@Override
public String toString() {
return this.queue.toString();
}
}

View File

@@ -0,0 +1,53 @@
import java.util.Scanner;
/**
* This class implements a shop simulation.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
class ShopSimulation extends Simulation {
/**
* The list of customer arrival events to populate
* the simulation with.
*/
private Event[] initEvents;
/**
* Constructor for a shop simulation.
*
* @param sc A scanner to read the parameters from. The first
* integer scanned is the number of customers; followed
* by the number of service counters. Next is a
* sequence of (arrival time, service time) pair, each
* pair represents a customer.
*/
public ShopSimulation(Scanner sc) {
initEvents = new Event[sc.nextInt()];
int numOfCounters = sc.nextInt();
int maxCounterQueueSize = sc.nextInt();
int maxShopQueueSize = sc.nextInt();
Shop shop = new Shop(numOfCounters, maxShopQueueSize, maxCounterQueueSize);
int id = 0;
while (sc.hasNextDouble()) {
double arrivalTime = sc.nextDouble();
double serviceTime = sc.nextDouble();
initEvents[id] = new ArrivalEvent(new Customer(serviceTime, arrivalTime), shop);
id += 1;
}
}
/**
* Retrieve an array of events to populate the
* simulator with.
*
* @return An array of events for the simulator.
*/
@Override
public Event[] getInitialEvents() {
return initEvents;
}
}

View File

@@ -0,0 +1,20 @@
/**
* This class is a general abstract class that
* encapsulates a simulation. To implement a
* simulation, inherit from this class and implement
* the `getInitialEvents` method.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
abstract class Simulation {
/**
* An abstract method to return an array of events
* used to initialize the simulation.
*
* @return An array of initial events that the
* simulator can use to kick-start the
* simulation.
*/
public abstract Event[] getInitialEvents();
}

View File

@@ -0,0 +1,51 @@
import java.util.PriorityQueue;
/**
* This class implements a discrete event simulator.
* The simulator maintains a priority queue of events.
* It runs through the events and simulates each one until
* the queue is empty.
*
* @author Yadunand Prem
* @version CS2030S AY22/23 Semester 2
*/
public class Simulator {
/** The event queue. */
private final PriorityQueue<Event> events;
/**
* The constructor for a simulator. It takes in
* a simulation as an argument, and calls the
* getInitialEvents method of that simulation to
* initialize the event queue.
*
* @param simulation The simulation to simulate.
*/
public Simulator(Simulation simulation) {
this.events = new PriorityQueue<Event>();
for (Event e : simulation.getInitialEvents()) {
this.events.add(e);
}
}
/**
* Run the simulation until no more events is in
* the queue. For each event in the queue (in
* increasing order of time), print out its string
* representation, then simulate it. If the
* simulation returns one or more events, add them
* to the queue, and repeat.
*/
public void run() {
Event event = this.events.poll();
while (event != null) {
System.out.println(event);
Event[] newEvents = event.simulate();
for (Event e : newEvents) {
this.events.add(e);
}
event = this.events.poll();
}
return;
}
}

View File

@@ -0,0 +1,4 @@
3 1
1.0 1.0
3.0 1.0
5.0 1.0

View File

@@ -0,0 +1,4 @@
3 1
1.1 2.0
2.2 2.0
3.3 2.0

View File

@@ -0,0 +1,6 @@
5 2
1.0 1.0
1.2 1.0
1.4 1.0
1.6 1.0
2.1 1.0

View File

@@ -0,0 +1,5 @@
4 2
1.0 1.0
1.1 1.0
2.2 1.0
2.3 1.0

View File

@@ -0,0 +1,4 @@
3 2
1.0 4
2.1 1
4.2 1

View File

@@ -0,0 +1,4 @@
3 1 2
1.0 1.0
3.0 1.0
5.0 1.0

View File

@@ -0,0 +1,6 @@
5 2 2
1.0 1.5
1.2 1.0
1.4 1.0
1.6 1.0
2.1 1.0

View File

@@ -0,0 +1,4 @@
3 1 2
1.1 2.0
2.2 2.0
3.3 2.0

View File

@@ -0,0 +1,7 @@
6 1 2
1.1 2
1.2 2
1.3 2
1.4 2
4.0 2
5.0 2

View File

@@ -0,0 +1,7 @@
6 1 3
1.1 2
1.2 2
1.3 2
1.4 2
4.0 2
5.0 2

View File

@@ -0,0 +1,5 @@
4 2 1
1.0 1.0
1.1 1.0
2.2 1.0
2.3 1.0

View File

@@ -0,0 +1,5 @@
4 2 2
1.0 1.0
1.1 1.0
2.2 1.0
2.3 1.0

View File

@@ -0,0 +1,4 @@
3 2 1
1.0 4
2.1 1
4.2 1

View File

@@ -0,0 +1,6 @@
5 2 1
1.0 1.0
1.2 1.0
1.4 1.0
1.6 1.0
2.1 1.0

View File

@@ -0,0 +1,6 @@
5 2 2
1.0 1.0
1.2 1.0
1.4 1.0
1.6 1.0
2.1 1.0

View File

@@ -0,0 +1,4 @@
3 1 0 2
1.0 1.0
3.0 1.0
5.0 1.0

View File

@@ -0,0 +1,6 @@
5 2 0 2
1.0 1.5
1.2 1.0
1.4 1.0
1.6 1.0
2.1 1.0

View File

@@ -0,0 +1,6 @@
5 1 2 0
1.0 1.0
1.1 1.0
1.2 1.0
1.3 1.0
1.4 1.0

View File

@@ -0,0 +1,12 @@
11 3 3 0
1.0 2
1.1 1
1.2 1
1.3 1
1.4 1
1.5 2
1.6 2
1.7 2
1.8 2
1.9 2
2.15 1

View File

@@ -0,0 +1,12 @@
11 3 3 0
1.0 2
1.1 1
1.2 1
1.3 1
1.4 1
1.5 2
1.6 2
1.7 2
1.8 2
1.9 2
2.25 1

View File

@@ -0,0 +1,13 @@
12 3 2 2
1.0 2
1.1 2
1.2 2
1.3 2
1.4 2
1.5 2
1.6 2
1.7 2
1.8 2
1.9 2
2.0 2
2.1 2

View File

@@ -0,0 +1,13 @@
12 3 2 3
1.0 2
1.1 3
1.2 2
1.3 3
1.4 2
1.5 3
1.6 2
1.7 3
1.8 2
1.9 3
2.0 2
2.1 3

View File

@@ -0,0 +1,4 @@
3 1 0 2
1.1 2.0
2.2 2.0
3.3 2.0

View File

@@ -0,0 +1,7 @@
6 1 0 2
1.1 2
1.2 2
1.3 2
1.4 2
4.0 2
5.0 2

View File

@@ -0,0 +1,7 @@
6 1 0 3
1.1 2
1.2 2
1.3 2
1.4 2
4.0 2
5.0 2

View File

@@ -0,0 +1,5 @@
4 2 0 1
1.0 1.0
1.1 1.0
2.2 1.0
2.3 1.0

View File

@@ -0,0 +1,5 @@
4 2 0 2
1.0 1.0
1.1 1.0
2.2 1.0
2.3 1.0

View File

@@ -0,0 +1,4 @@
3 2 0 1
1.0 4
2.1 1
4.2 1

View File

@@ -0,0 +1,6 @@
5 2 0 1
1.0 1.0
1.2 1.0
1.4 1.0
1.6 1.0
2.1 1.0

View File

@@ -0,0 +1,6 @@
5 2 0 2
1.0 1.0
1.2 1.0
1.4 1.0
1.6 1.0
2.1 1.0

View File

@@ -0,0 +1,55 @@
jshell> /open Array.java
jshell> Integer i
jshell> String s
jshell> Array<Integer> a;
jshell> a = new Array<Integer>(4);
jshell> a.set(0, 3);
jshell> a.set(1, 6);
jshell> a.set(2, 4);
jshell> a.set(3, 1);
jshell> a.set(0, "huat");
| Error:
| incompatible types: java.lang.String cannot be converted to java.lang.Integer
| a.set(0, "huat");
| ^----^
jshell> i = a.get(0)
jshell> i
i ==> 3
jshell> i = a.get(1)
jshell> i
i ==> 6
jshell> i = a.get(2)
jshell> i
i ==> 4
jshell> i = a.get(3)
jshell> i
i ==> 1
jshell> s = a.get(0)
| Error:
| incompatible types: java.lang.Integer cannot be converted to java.lang.String
| s = a.get(0)
| ^------^
jshell> i = a.min()
jshell> i
i ==> 1
jshell> a.set(3,9);
jshell> i = a.min()
jshell> i
i ==> 3
jshell> // try something not comparable
jshell> class A {}
jshell> Array<A> a;
| Error:
| type argument A is not within bounds of type-variable T
| Array<A> a;
| ^
jshell> class A implements Comparable<Long> { public int compareTo(Long i) { return 0; } }
jshell> Array<A> a;
| Error:
| type argument A is not within bounds of type-variable T
| Array<A> a;
| ^
jshell> // try something comparable
jshell> class A implements Comparable<A> { public int compareTo(A a) { return 0; } }
jshell> Array<A> a;
jshell>

View File

@@ -0,0 +1,12 @@
1.000: Customer 0 arrives
1.000: Customer 0 service begin (by Counter 0)
2.000: Customer 0 service done (by Counter 0)
2.000: Customer 0 departed
3.000: Customer 1 arrives
3.000: Customer 1 service begin (by Counter 0)
4.000: Customer 1 service done (by Counter 0)
4.000: Customer 1 departed
5.000: Customer 2 arrives
5.000: Customer 2 service begin (by Counter 0)
6.000: Customer 2 service done (by Counter 0)
6.000: Customer 2 departed

View File

@@ -0,0 +1,10 @@
1.100: Customer 0 arrives
1.100: Customer 0 service begin (by Counter 0)
2.200: Customer 1 arrives
2.200: Customer 1 departed
3.100: Customer 0 service done (by Counter 0)
3.100: Customer 0 departed
3.300: Customer 2 arrives
3.300: Customer 2 service begin (by Counter 0)
5.300: Customer 2 service done (by Counter 0)
5.300: Customer 2 departed

View File

@@ -0,0 +1,16 @@
1.000: Customer 0 arrives
1.000: Customer 0 service begin (by Counter 0)
1.200: Customer 1 arrives
1.200: Customer 1 service begin (by Counter 1)
1.400: Customer 2 arrives
1.400: Customer 2 departed
1.600: Customer 3 arrives
1.600: Customer 3 departed
2.000: Customer 0 service done (by Counter 0)
2.000: Customer 0 departed
2.100: Customer 4 arrives
2.100: Customer 4 service begin (by Counter 0)
2.200: Customer 1 service done (by Counter 1)
2.200: Customer 1 departed
3.100: Customer 4 service done (by Counter 0)
3.100: Customer 4 departed

View File

@@ -0,0 +1,16 @@
1.000: Customer 0 arrives
1.000: Customer 0 service begin (by Counter 0)
1.100: Customer 1 arrives
1.100: Customer 1 service begin (by Counter 1)
2.000: Customer 0 service done (by Counter 0)
2.000: Customer 0 departed
2.100: Customer 1 service done (by Counter 1)
2.100: Customer 1 departed
2.200: Customer 2 arrives
2.200: Customer 2 service begin (by Counter 0)
2.300: Customer 3 arrives
2.300: Customer 3 service begin (by Counter 1)
3.200: Customer 2 service done (by Counter 0)
3.200: Customer 2 departed
3.300: Customer 3 service done (by Counter 1)
3.300: Customer 3 departed

View File

@@ -0,0 +1,12 @@
1.000: Customer 0 arrives
1.000: Customer 0 service begin (by Counter 0)
2.100: Customer 1 arrives
2.100: Customer 1 service begin (by Counter 1)
3.100: Customer 1 service done (by Counter 1)
3.100: Customer 1 departed
4.200: Customer 2 arrives
4.200: Customer 2 service begin (by Counter 1)
5.000: Customer 0 service done (by Counter 0)
5.000: Customer 0 departed
5.200: Customer 2 service done (by Counter 1)
5.200: Customer 2 departed

View File

@@ -0,0 +1,12 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0)
2.000: C0 service done (by S0)
2.000: C0 departed
3.000: C1 arrived [ ]
3.000: C1 service begin (by S0)
4.000: C1 service done (by S0)
4.000: C1 departed
5.000: C2 arrived [ ]
5.000: C2 service begin (by S0)
6.000: C2 service done (by S0)
6.000: C2 departed

View File

@@ -0,0 +1,20 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0)
1.200: C1 arrived [ ]
1.200: C1 service begin (by S1)
1.400: C2 arrived [ ]
1.400: C2 joined queue [ ]
1.600: C3 arrived [ C2 ]
1.600: C3 joined queue [ C2 ]
2.100: C4 arrived [ C2 C3 ]
2.100: C4 departed
2.200: C1 service done (by S1)
2.200: C1 departed
2.200: C2 service begin (by S1)
2.500: C0 service done (by S0)
2.500: C0 departed
2.500: C3 service begin (by S0)
3.200: C2 service done (by S1)
3.200: C2 departed
3.500: C3 service done (by S0)
3.500: C3 departed

View File

@@ -0,0 +1,14 @@
1.100: C0 arrived [ ]
1.100: C0 service begin (by S0)
2.200: C1 arrived [ ]
2.200: C1 joined queue [ ]
3.100: C0 service done (by S0)
3.100: C0 departed
3.100: C1 service begin (by S0)
3.300: C2 arrived [ ]
3.300: C2 joined queue [ ]
5.100: C1 service done (by S0)
5.100: C1 departed
5.100: C2 service begin (by S0)
7.100: C2 service done (by S0)
7.100: C2 departed

View File

@@ -0,0 +1,23 @@
1.100: C0 arrived [ ]
1.100: C0 service begin (by S0)
1.200: C1 arrived [ ]
1.200: C1 joined queue [ ]
1.300: C2 arrived [ C1 ]
1.300: C2 joined queue [ C1 ]
1.400: C3 arrived [ C1 C2 ]
1.400: C3 departed
3.100: C0 service done (by S0)
3.100: C0 departed
3.100: C1 service begin (by S0)
4.000: C4 arrived [ C2 ]
4.000: C4 joined queue [ C2 ]
5.000: C5 arrived [ C2 C4 ]
5.000: C5 departed
5.100: C1 service done (by S0)
5.100: C1 departed
5.100: C2 service begin (by S0)
7.100: C2 service done (by S0)
7.100: C2 departed
7.100: C4 service begin (by S0)
9.100: C4 service done (by S0)
9.100: C4 departed

View File

@@ -0,0 +1,26 @@
1.100: C0 arrived [ ]
1.100: C0 service begin (by S0)
1.200: C1 arrived [ ]
1.200: C1 joined queue [ ]
1.300: C2 arrived [ C1 ]
1.300: C2 joined queue [ C1 ]
1.400: C3 arrived [ C1 C2 ]
1.400: C3 joined queue [ C1 C2 ]
3.100: C0 service done (by S0)
3.100: C0 departed
3.100: C1 service begin (by S0)
4.000: C4 arrived [ C2 C3 ]
4.000: C4 joined queue [ C2 C3 ]
5.000: C5 arrived [ C2 C3 C4 ]
5.000: C5 departed
5.100: C1 service done (by S0)
5.100: C1 departed
5.100: C2 service begin (by S0)
7.100: C2 service done (by S0)
7.100: C2 departed
7.100: C3 service begin (by S0)
9.100: C3 service done (by S0)
9.100: C3 departed
9.100: C4 service begin (by S0)
11.100: C4 service done (by S0)
11.100: C4 departed

View File

@@ -0,0 +1,16 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0)
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1)
2.000: C0 service done (by S0)
2.000: C0 departed
2.100: C1 service done (by S1)
2.100: C1 departed
2.200: C2 arrived [ ]
2.200: C2 service begin (by S0)
2.300: C3 arrived [ ]
2.300: C3 service begin (by S1)
3.200: C2 service done (by S0)
3.200: C2 departed
3.300: C3 service done (by S1)
3.300: C3 departed

View File

@@ -0,0 +1,16 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0)
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1)
2.000: C0 service done (by S0)
2.000: C0 departed
2.100: C1 service done (by S1)
2.100: C1 departed
2.200: C2 arrived [ ]
2.200: C2 service begin (by S0)
2.300: C3 arrived [ ]
2.300: C3 service begin (by S1)
3.200: C2 service done (by S0)
3.200: C2 departed
3.300: C3 service done (by S1)
3.300: C3 departed

View File

@@ -0,0 +1,12 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0)
2.100: C1 arrived [ ]
2.100: C1 service begin (by S1)
3.100: C1 service done (by S1)
3.100: C1 departed
4.200: C2 arrived [ ]
4.200: C2 service begin (by S1)
5.000: C0 service done (by S0)
5.000: C0 departed
5.200: C2 service done (by S1)
5.200: C2 departed

View File

@@ -0,0 +1,20 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0)
1.200: C1 arrived [ ]
1.200: C1 service begin (by S1)
1.400: C2 arrived [ ]
1.400: C2 joined queue [ ]
1.600: C3 arrived [ C2 ]
1.600: C3 departed
2.000: C0 service done (by S0)
2.000: C0 departed
2.000: C2 service begin (by S0)
2.100: C4 arrived [ ]
2.100: C4 joined queue [ ]
2.200: C1 service done (by S1)
2.200: C1 departed
2.200: C4 service begin (by S1)
3.000: C2 service done (by S0)
3.000: C2 departed
3.200: C4 service done (by S1)
3.200: C4 departed

View File

@@ -0,0 +1,23 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0)
1.200: C1 arrived [ ]
1.200: C1 service begin (by S1)
1.400: C2 arrived [ ]
1.400: C2 joined queue [ ]
1.600: C3 arrived [ C2 ]
1.600: C3 joined queue [ C2 ]
2.000: C0 service done (by S0)
2.000: C0 departed
2.000: C2 service begin (by S0)
2.100: C4 arrived [ C3 ]
2.100: C4 joined queue [ C3 ]
2.200: C1 service done (by S1)
2.200: C1 departed
2.200: C3 service begin (by S1)
3.000: C2 service done (by S0)
3.000: C2 departed
3.000: C4 service begin (by S0)
3.200: C3 service done (by S1)
3.200: C3 departed
4.000: C4 service done (by S0)
4.000: C4 departed

View File

@@ -0,0 +1,12 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
2.000: C0 service done (by S0 [ ])
2.000: C0 departed
3.000: C1 arrived [ ]
3.000: C1 service begin (by S0 [ ])
4.000: C1 service done (by S0 [ ])
4.000: C1 departed
5.000: C2 arrived [ ]
5.000: C2 service begin (by S0 [ ])
6.000: C2 service done (by S0 [ ])
6.000: C2 departed

View File

@@ -0,0 +1,20 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.200: C1 arrived [ ]
1.200: C1 service begin (by S1 [ ])
1.400: C2 arrived [ ]
1.400: C2 joined shop queue [ ]
1.600: C3 arrived [ C2 ]
1.600: C3 joined shop queue [ C2 ]
2.100: C4 arrived [ C2 C3 ]
2.100: C4 departed
2.200: C1 service done (by S1 [ ])
2.200: C1 departed
2.200: C2 service begin (by S1 [ ])
2.500: C0 service done (by S0 [ ])
2.500: C0 departed
2.500: C3 service begin (by S0 [ ])
3.200: C2 service done (by S1 [ ])
3.200: C2 departed
3.500: C3 service done (by S0 [ ])
3.500: C3 departed

View File

@@ -0,0 +1,18 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.100: C1 arrived [ ]
1.100: C1 joined counter queue (at S0 [ ])
1.200: C2 arrived [ ]
1.200: C2 joined counter queue (at S0 [ C1 ])
1.300: C3 arrived [ ]
1.300: C3 departed
1.400: C4 arrived [ ]
1.400: C4 departed
2.000: C0 service done (by S0 [ C1 C2 ])
2.000: C0 departed
2.000: C1 service begin (by S0 [ C2 ])
3.000: C1 service done (by S0 [ C2 ])
3.000: C1 departed
3.000: C2 service begin (by S0 [ ])
4.000: C2 service done (by S0 [ ])
4.000: C2 departed

View File

@@ -0,0 +1,52 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1 [ ])
1.200: C2 arrived [ ]
1.200: C2 service begin (by S2 [ ])
1.300: C3 arrived [ ]
1.300: C3 joined counter queue (at S0 [ ])
1.400: C4 arrived [ ]
1.400: C4 joined counter queue (at S1 [ ])
1.500: C5 arrived [ ]
1.500: C5 joined counter queue (at S2 [ ])
1.600: C6 arrived [ ]
1.600: C6 joined counter queue (at S0 [ C3 ])
1.700: C7 arrived [ ]
1.700: C7 joined counter queue (at S1 [ C4 ])
1.800: C8 arrived [ ]
1.800: C8 joined counter queue (at S2 [ C5 ])
1.900: C9 arrived [ ]
1.900: C9 joined counter queue (at S0 [ C3 C6 ])
2.100: C1 service done (by S1 [ C4 C7 ])
2.100: C1 departed
2.100: C4 service begin (by S1 [ C7 ])
2.150: C10 arrived [ ]
2.150: C10 joined counter queue (at S1 [ C7 ])
2.200: C2 service done (by S2 [ C5 C8 ])
2.200: C2 departed
2.200: C5 service begin (by S2 [ C8 ])
3.000: C0 service done (by S0 [ C3 C6 C9 ])
3.000: C0 departed
3.000: C3 service begin (by S0 [ C6 C9 ])
3.100: C4 service done (by S1 [ C7 C10 ])
3.100: C4 departed
3.100: C7 service begin (by S1 [ C10 ])
4.000: C3 service done (by S0 [ C6 C9 ])
4.000: C3 departed
4.000: C6 service begin (by S0 [ C9 ])
4.200: C5 service done (by S2 [ C8 ])
4.200: C5 departed
4.200: C8 service begin (by S2 [ ])
5.100: C7 service done (by S1 [ C10 ])
5.100: C7 departed
5.100: C10 service begin (by S1 [ ])
6.000: C6 service done (by S0 [ C9 ])
6.000: C6 departed
6.000: C9 service begin (by S0 [ ])
6.100: C10 service done (by S1 [ ])
6.100: C10 departed
6.200: C8 service done (by S2 [ ])
6.200: C8 departed
8.000: C9 service done (by S0 [ ])
8.000: C9 departed

View File

@@ -0,0 +1,52 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1 [ ])
1.200: C2 arrived [ ]
1.200: C2 service begin (by S2 [ ])
1.300: C3 arrived [ ]
1.300: C3 joined counter queue (at S0 [ ])
1.400: C4 arrived [ ]
1.400: C4 joined counter queue (at S1 [ ])
1.500: C5 arrived [ ]
1.500: C5 joined counter queue (at S2 [ ])
1.600: C6 arrived [ ]
1.600: C6 joined counter queue (at S0 [ C3 ])
1.700: C7 arrived [ ]
1.700: C7 joined counter queue (at S1 [ C4 ])
1.800: C8 arrived [ ]
1.800: C8 joined counter queue (at S2 [ C5 ])
1.900: C9 arrived [ ]
1.900: C9 joined counter queue (at S0 [ C3 C6 ])
2.100: C1 service done (by S1 [ C4 C7 ])
2.100: C1 departed
2.100: C4 service begin (by S1 [ C7 ])
2.200: C2 service done (by S2 [ C5 C8 ])
2.200: C2 departed
2.200: C5 service begin (by S2 [ C8 ])
2.250: C10 arrived [ ]
2.250: C10 joined counter queue (at S1 [ C7 ])
3.000: C0 service done (by S0 [ C3 C6 C9 ])
3.000: C0 departed
3.000: C3 service begin (by S0 [ C6 C9 ])
3.100: C4 service done (by S1 [ C7 C10 ])
3.100: C4 departed
3.100: C7 service begin (by S1 [ C10 ])
4.000: C3 service done (by S0 [ C6 C9 ])
4.000: C3 departed
4.000: C6 service begin (by S0 [ C9 ])
4.200: C5 service done (by S2 [ C8 ])
4.200: C5 departed
4.200: C8 service begin (by S2 [ ])
5.100: C7 service done (by S1 [ C10 ])
5.100: C7 departed
5.100: C10 service begin (by S1 [ ])
6.000: C6 service done (by S0 [ C9 ])
6.000: C6 departed
6.000: C9 service begin (by S0 [ ])
6.100: C10 service done (by S1 [ ])
6.100: C10 departed
6.200: C8 service done (by S2 [ ])
6.200: C8 departed
8.000: C9 service done (by S0 [ ])
8.000: C9 departed

View File

@@ -0,0 +1,56 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1 [ ])
1.200: C2 arrived [ ]
1.200: C2 service begin (by S2 [ ])
1.300: C3 arrived [ ]
1.300: C3 joined counter queue (at S0 [ ])
1.400: C4 arrived [ ]
1.400: C4 joined counter queue (at S1 [ ])
1.500: C5 arrived [ ]
1.500: C5 joined counter queue (at S2 [ ])
1.600: C6 arrived [ ]
1.600: C6 joined counter queue (at S0 [ C3 ])
1.700: C7 arrived [ ]
1.700: C7 joined counter queue (at S1 [ C4 ])
1.800: C8 arrived [ ]
1.800: C8 joined counter queue (at S2 [ C5 ])
1.900: C9 arrived [ ]
1.900: C9 joined shop queue [ ]
2.000: C10 arrived [ C9 ]
2.000: C10 joined shop queue [ C9 ]
2.100: C11 arrived [ C9 C10 ]
2.100: C11 departed
3.000: C0 service done (by S0 [ C3 C6 ])
3.000: C0 departed
3.000: C9 joined counter queue (at S0 [ C6 ])
3.000: C3 service begin (by S0 [ C6 C9 ])
3.100: C1 service done (by S1 [ C4 C7 ])
3.100: C1 departed
3.100: C10 joined counter queue (at S1 [ C7 ])
3.100: C4 service begin (by S1 [ C7 C10 ])
3.200: C2 service done (by S2 [ C5 C8 ])
3.200: C2 departed
3.200: C5 service begin (by S2 [ C8 ])
5.000: C3 service done (by S0 [ C6 C9 ])
5.000: C3 departed
5.000: C6 service begin (by S0 [ C9 ])
5.100: C4 service done (by S1 [ C7 C10 ])
5.100: C4 departed
5.100: C7 service begin (by S1 [ C10 ])
5.200: C5 service done (by S2 [ C8 ])
5.200: C5 departed
5.200: C8 service begin (by S2 [ ])
7.000: C6 service done (by S0 [ C9 ])
7.000: C6 departed
7.000: C9 service begin (by S0 [ ])
7.100: C7 service done (by S1 [ C10 ])
7.100: C7 departed
7.100: C10 service begin (by S1 [ ])
7.200: C8 service done (by S2 [ ])
7.200: C8 departed
9.000: C9 service done (by S0 [ ])
9.000: C9 departed
9.100: C10 service done (by S1 [ ])
9.100: C10 departed

View File

@@ -0,0 +1,60 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1 [ ])
1.200: C2 arrived [ ]
1.200: C2 service begin (by S2 [ ])
1.300: C3 arrived [ ]
1.300: C3 joined counter queue (at S0 [ ])
1.400: C4 arrived [ ]
1.400: C4 joined counter queue (at S1 [ ])
1.500: C5 arrived [ ]
1.500: C5 joined counter queue (at S2 [ ])
1.600: C6 arrived [ ]
1.600: C6 joined counter queue (at S0 [ C3 ])
1.700: C7 arrived [ ]
1.700: C7 joined counter queue (at S1 [ C4 ])
1.800: C8 arrived [ ]
1.800: C8 joined counter queue (at S2 [ C5 ])
1.900: C9 arrived [ ]
1.900: C9 joined shop queue [ ]
2.000: C10 arrived [ C9 ]
2.000: C10 joined shop queue [ C9 ]
2.100: C11 arrived [ C9 C10 ]
2.100: C11 joined shop queue [ C9 C10 ]
3.000: C0 service done (by S0 [ C3 C6 ])
3.000: C0 departed
3.000: C9 joined counter queue (at S0 [ C6 ])
3.000: C3 service begin (by S0 [ C6 C9 ])
3.200: C2 service done (by S2 [ C5 C8 ])
3.200: C2 departed
3.200: C10 joined counter queue (at S2 [ C8 ])
3.200: C5 service begin (by S2 [ C8 C10 ])
4.100: C1 service done (by S1 [ C4 C7 ])
4.100: C1 departed
4.100: C11 joined counter queue (at S1 [ C7 ])
4.100: C4 service begin (by S1 [ C7 C11 ])
6.000: C3 service done (by S0 [ C6 C9 ])
6.000: C3 departed
6.000: C6 service begin (by S0 [ C9 ])
6.100: C4 service done (by S1 [ C7 C11 ])
6.100: C4 departed
6.100: C7 service begin (by S1 [ C11 ])
6.200: C5 service done (by S2 [ C8 C10 ])
6.200: C5 departed
6.200: C8 service begin (by S2 [ C10 ])
8.000: C6 service done (by S0 [ C9 ])
8.000: C6 departed
8.000: C9 service begin (by S0 [ ])
8.200: C8 service done (by S2 [ C10 ])
8.200: C8 departed
8.200: C10 service begin (by S2 [ ])
9.100: C7 service done (by S1 [ C11 ])
9.100: C7 departed
9.100: C11 service begin (by S1 [ ])
10.200: C10 service done (by S2 [ ])
10.200: C10 departed
11.000: C9 service done (by S0 [ ])
11.000: C9 departed
12.100: C11 service done (by S1 [ ])
12.100: C11 departed

View File

@@ -0,0 +1,14 @@
1.100: C0 arrived [ ]
1.100: C0 service begin (by S0 [ ])
2.200: C1 arrived [ ]
2.200: C1 joined shop queue [ ]
3.100: C0 service done (by S0 [ ])
3.100: C0 departed
3.100: C1 service begin (by S0 [ ])
3.300: C2 arrived [ ]
3.300: C2 joined shop queue [ ]
5.100: C1 service done (by S0 [ ])
5.100: C1 departed
5.100: C2 service begin (by S0 [ ])
7.100: C2 service done (by S0 [ ])
7.100: C2 departed

View File

@@ -0,0 +1,23 @@
1.100: C0 arrived [ ]
1.100: C0 service begin (by S0 [ ])
1.200: C1 arrived [ ]
1.200: C1 joined shop queue [ ]
1.300: C2 arrived [ C1 ]
1.300: C2 joined shop queue [ C1 ]
1.400: C3 arrived [ C1 C2 ]
1.400: C3 departed
3.100: C0 service done (by S0 [ ])
3.100: C0 departed
3.100: C1 service begin (by S0 [ ])
4.000: C4 arrived [ C2 ]
4.000: C4 joined shop queue [ C2 ]
5.000: C5 arrived [ C2 C4 ]
5.000: C5 departed
5.100: C1 service done (by S0 [ ])
5.100: C1 departed
5.100: C2 service begin (by S0 [ ])
7.100: C2 service done (by S0 [ ])
7.100: C2 departed
7.100: C4 service begin (by S0 [ ])
9.100: C4 service done (by S0 [ ])
9.100: C4 departed

View File

@@ -0,0 +1,26 @@
1.100: C0 arrived [ ]
1.100: C0 service begin (by S0 [ ])
1.200: C1 arrived [ ]
1.200: C1 joined shop queue [ ]
1.300: C2 arrived [ C1 ]
1.300: C2 joined shop queue [ C1 ]
1.400: C3 arrived [ C1 C2 ]
1.400: C3 joined shop queue [ C1 C2 ]
3.100: C0 service done (by S0 [ ])
3.100: C0 departed
3.100: C1 service begin (by S0 [ ])
4.000: C4 arrived [ C2 C3 ]
4.000: C4 joined shop queue [ C2 C3 ]
5.000: C5 arrived [ C2 C3 C4 ]
5.000: C5 departed
5.100: C1 service done (by S0 [ ])
5.100: C1 departed
5.100: C2 service begin (by S0 [ ])
7.100: C2 service done (by S0 [ ])
7.100: C2 departed
7.100: C3 service begin (by S0 [ ])
9.100: C3 service done (by S0 [ ])
9.100: C3 departed
9.100: C4 service begin (by S0 [ ])
11.100: C4 service done (by S0 [ ])
11.100: C4 departed

View File

@@ -0,0 +1,16 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1 [ ])
2.000: C0 service done (by S0 [ ])
2.000: C0 departed
2.100: C1 service done (by S1 [ ])
2.100: C1 departed
2.200: C2 arrived [ ]
2.200: C2 service begin (by S0 [ ])
2.300: C3 arrived [ ]
2.300: C3 service begin (by S1 [ ])
3.200: C2 service done (by S0 [ ])
3.200: C2 departed
3.300: C3 service done (by S1 [ ])
3.300: C3 departed

View File

@@ -0,0 +1,16 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.100: C1 arrived [ ]
1.100: C1 service begin (by S1 [ ])
2.000: C0 service done (by S0 [ ])
2.000: C0 departed
2.100: C1 service done (by S1 [ ])
2.100: C1 departed
2.200: C2 arrived [ ]
2.200: C2 service begin (by S0 [ ])
2.300: C3 arrived [ ]
2.300: C3 service begin (by S1 [ ])
3.200: C2 service done (by S0 [ ])
3.200: C2 departed
3.300: C3 service done (by S1 [ ])
3.300: C3 departed

View File

@@ -0,0 +1,12 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
2.100: C1 arrived [ ]
2.100: C1 service begin (by S1 [ ])
3.100: C1 service done (by S1 [ ])
3.100: C1 departed
4.200: C2 arrived [ ]
4.200: C2 service begin (by S1 [ ])
5.000: C0 service done (by S0 [ ])
5.000: C0 departed
5.200: C2 service done (by S1 [ ])
5.200: C2 departed

View File

@@ -0,0 +1,20 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.200: C1 arrived [ ]
1.200: C1 service begin (by S1 [ ])
1.400: C2 arrived [ ]
1.400: C2 joined shop queue [ ]
1.600: C3 arrived [ C2 ]
1.600: C3 departed
2.000: C0 service done (by S0 [ ])
2.000: C0 departed
2.000: C2 service begin (by S0 [ ])
2.100: C4 arrived [ ]
2.100: C4 joined shop queue [ ]
2.200: C1 service done (by S1 [ ])
2.200: C1 departed
2.200: C4 service begin (by S1 [ ])
3.000: C2 service done (by S0 [ ])
3.000: C2 departed
3.200: C4 service done (by S1 [ ])
3.200: C4 departed

View File

@@ -0,0 +1,23 @@
1.000: C0 arrived [ ]
1.000: C0 service begin (by S0 [ ])
1.200: C1 arrived [ ]
1.200: C1 service begin (by S1 [ ])
1.400: C2 arrived [ ]
1.400: C2 joined shop queue [ ]
1.600: C3 arrived [ C2 ]
1.600: C3 joined shop queue [ C2 ]
2.000: C0 service done (by S0 [ ])
2.000: C0 departed
2.000: C2 service begin (by S0 [ ])
2.100: C4 arrived [ C3 ]
2.100: C4 joined shop queue [ C3 ]
2.200: C1 service done (by S1 [ ])
2.200: C1 departed
2.200: C3 service begin (by S1 [ ])
3.000: C2 service done (by S0 [ ])
3.000: C2 departed
3.000: C4 service begin (by S0 [ ])
3.200: C3 service done (by S1 [ ])
3.200: C3 departed
4.000: C4 service done (by S0 [ ])
4.000: C4 departed

View File

@@ -0,0 +1,34 @@
jshell> /open Queue.java
jshell> Integer i;
jshell> String s;
jshell> boolean b;
jshell> Queue<Integer> q = new Queue<Integer>(2);
jshell> b = q.enq(4);
jshell> b
b ==> true
jshell> b = q.enq(8);
jshell> b
b ==> true
jshell> b = q.enq(0);
jshell> b
b ==> false
jshell> s = q.deq();
| Error:
| incompatible types: java.lang.Integer cannot be converted to java.lang.String
| s = q.deq();
| ^-----^
jshell> i = q.deq();
jshell> i
i ==> 4
jshell> i = q.deq();
jshell> i
i ==> 8
jshell> i = q.deq();
jshell> i
i ==> null
jshell> q.enq("hello");
| Error:
| incompatible types: java.lang.String cannot be converted to java.lang.Integer
| q.enq("hello");
| ^-----^
jshell>

77
labs/cs2030s/Lab1/test.sh Executable file
View File

@@ -0,0 +1,77 @@
#!/bin/bash
set -o nounset
function control_c() {
if [ -e $out ]
then
rm -f $out
fi
}
trap control_c INT
if [ $# -ne 1 ]
then
echo "usage: $0 <main class>"
exit 1
fi
PROG=$1
if [ ! -e $PROG.class ]
then
echo "$PROG.class does not exist. Have you compiled it with make or javac?"
exit 1
fi
num_failed=0
i=1
while true
do
if [ -e inputs/$PROG.$i.in ]
then
if [ $(uname) == "Darwin" ]
then
out=$(mktemp -t $PROG)
else
out=$(mktemp --suffix=$PROG)
fi
java $PROG < inputs/$PROG.$i.in > $out
status="$?"
if [ "$status" -ne "0" ]
then
echo "$PROG: return non-zero status $status for test case $i"
# cat inputs/$PROG.$i.in
num_failed=$((num_failed + 1))
else
if [ -e $out ]
then
if [ `diff -bB $out outputs/$PROG.$i.out | wc -l` -ne 0 ]
then
echo "$PROG test $i: failed"
#cat inputs/$PROG.$i.in
num_failed=$((num_failed + 1))
else
echo "$PROG test $i: passed"
fi
rm -f $out
else
echo "$PROG: cannot find output file. Execution interrupted?"
num_failed=$((num_failed + 1))
fi
fi
i=$((i + 1))
else
break
fi
done
if [ $i -eq 1 ]
then
echo "$PROG: no test cases found 🤷"
elif [ $num_failed -eq 0 ]
then
echo "$PROG: passed everything 🎉"
fi
# Run style checker
#java -jar ~cs2030s/bin/checkstyle.jar -c ~cs2030s/bin/cs2030_checks.xml *.java
java -jar ./checkstyle.jar -c ./cs2030_checks.xml *.java
# vim:noexpandtab:sw=4:ts=4

View File

@@ -0,0 +1,12 @@
/**
* The Action interface that can be called
* on an object of type T to act.
* Contains a single abstract method call.
* CS2030S Lab 4
* AY22/23 Semester 1
* @author Yadunand Prem (10B)
*/
interface Action<T> {
void call(T item);
}

View File

@@ -0,0 +1,13 @@
/**
* The Actionable interface that can
* act when given an action.
* Contains a single abstract method act.
* CS2030S Lab 4
* AY22/23 Semester 1
* @author Yadunand Prem (10B)
*/
// act consumes the T and passes it to action, thus super
interface Actionable<T> {
public void act(Action<? super T> action);
}

View File

@@ -0,0 +1,14 @@
/**
* The Applicable interface that can probably
* transform if given something that is
* probably an Immutator.
* Contains a single abstract method apply.
* CS2030S Lab 4
* AY22/23 Semester 1
*
* @author Yadunand Prem (10B)
*/
interface Applicable<T> {
<R> Applicable<R> apply(Probably<? extends Immutator<? extends R, ? super T>> probablyImmutator);
}

View File

@@ -0,0 +1,75 @@
import java.net.URI;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
class CS2030STest {
private static final String ANSI_RESET = "\u001B[0m";
private static final String ANSI_RED = "\u001B[31m";
private static final String ANSI_GREEN = "\u001B[32m";
public void expect(String test, Object output, Object expect) {
System.out.print(test);
if ((expect == null && output == null) || output.equals(expect)) {
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
} else {
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
System.out.println(" expected: " + expect);
System.out.println(" got this: " + output);
}
}
public static String clean(String txt) {
String res = "";
for (int i=0; i<txt.length(); i++) {
if (txt.charAt(i) != '\r' && txt.charAt(i) != '\n') {
res += txt.charAt(i);
}
}
return res;
}
public void expectPrint(String test, Object expect, ByteArrayOutputStream baos, PrintStream old) {
System.out.flush();
System.setOut(old);
expect(test, CS2030STest.clean(baos.toString()), expect);
}
public void expectCompile(String test, String statement, boolean success) {
System.out.print(test);
class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String code) {
super(URI.create("string:///TempClass.java"), Kind.SOURCE);
this.code = "class TempClass {void foo(){" + code + ";}}";
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
boolean noError = ToolProvider
.getSystemJavaCompiler()
.getTask(null, null, new DiagnosticCollector<>(), null, null,
List.of(new JavaSourceFromString(statement)))
.call();
if (noError != success) {
System.out.println(".. " + ANSI_RED + "failed" + ANSI_RESET);
if (!success) {
System.out.println(" expected compilation error but it compiles fine.");
} else {
System.out.println(" expected the statement to compile without errors but it does not.");
}
} else {
System.out.println(".. " + ANSI_GREEN + "ok" + ANSI_RESET);
}
}
}

View File

@@ -0,0 +1,12 @@
/**
* The Immutator interface that can transform
* to type T2, an object of type T1.
* Contains a single abstract method invoke.
* CS2030S Lab 4
* AY22/23 Semester 1
* @author Yadunand Prem (10B)
*/
interface Immutator<R, P> {
public R invoke(P param);
}

View File

@@ -0,0 +1,13 @@
/**
* The Immutatorable interface that can
* transform when given something that is
* Immutator.
* Contains a single abstract method transform.
* CS2030S Lab 4
* AY22/23 Semester 1
* @author Yadunand Prem (10B)
*/
interface Immutatorable<T> {
public <R> Immutatorable<R> transform(Immutator<? extends R, ? super T> immutator);
}

View File

@@ -0,0 +1,15 @@
/**
* A generic Immutator that takes in an object
* that is T and returns an object that is probably T.
* CS2030S Lab 4
* AY22/23 Semester 1
*
* @author Yadunand Prem (10B)
*/
class Improbable<T> implements Immutator<Probably<T>, T> {
@Override
public Probably<T> invoke(T param) {
return Probably.just(param);
}
}

View File

@@ -0,0 +1,27 @@
/**
* A non-generic Immutator with parameter
* div and mod that takes in an integer val
* and return the boolean value by checking
* if the given value is equal to mod when
* divided by div.
* CS2030S Lab 4
* AY22/23 Semester 1
*
* @author Yadunand Prem (10B)
*/
class IsModEq implements Immutator<Boolean, Integer> {
private int div;
private int check;
public IsModEq(int div, int check) {
this.div = div;
this.check = check;
}
@Override
public Boolean invoke(Integer val) {
return val % div == check;
}
}

247
labs/cs2030s/Lab4/Lab4.java Normal file
View File

@@ -0,0 +1,247 @@
import java.util.Scanner;
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
/**
* The main class for CS2030S Lab 4.
*
* @author Wei Tsang
* @version CS2030S AY21/22 Semester 2
*/
class Lab4 {
/**
* Inner class for testing.
*/
static class Incr implements Immutator<Integer,Integer> {
public Integer invoke(Integer t1) {
return t1 + 1;
}
}
/**
* Inner class for testing.
*/
static class Length implements Immutator<Integer,String> {
public Integer invoke(String t1) {
return t1.length();
}
}
/**
* Helper method to clean a string from
* any newline.
*
* @param txt Input string.
* @return The cleaned string.
*/
public static String clean(String txt) {
String res = "";
for (int i=0; i<txt.length(); i++) {
if (txt.charAt(i) != '\r' && txt.charAt(i) != '\n') {
res += txt.charAt(i);
}
}
return res;
}
public static void main(String[] args) {
// Create a scanner to read from standard input.
Scanner sc = new Scanner(System.in);
// Read a single integer from the test file
// and then run the appropriate test case
switch (sc.nextInt()) {
case 1:
test1();
break;
case 2:
test2();
break;
case 3:
test3();
break;
case 4:
test4();
break;
case 5:
test5();
break;
case 6:
test6();
break;
}
// Clean up the scanner.
sc.close();
}
/**
* Test #1.
*/
public static void test1() {
PrintStream old = System.out;
ByteArrayOutputStream baos;
PrintStream ps;
try {
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
new Print().call(17);
System.out.flush();
System.setOut(old);
System.out.println(Lab4.clean(baos.toString()));
} catch(Exception e) {
System.out.println("Error occurred");
}
try {
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
new Print().call("string");
System.out.flush();
System.setOut(old);
System.out.println(Lab4.clean(baos.toString()));
} catch(Exception e) {
System.out.println("Error occurred");
}
}
/**
* Test #2.
*/
public static void test2() {
PrintStream old = System.out;
ByteArrayOutputStream baos;
PrintStream ps;
try {
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
Probably.just(4).act(new Print());
System.out.flush();
System.setOut(old);
System.out.println(Lab4.clean(baos.toString()));
} catch(Exception e) {
System.out.println("Error occurred");
}
try {
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
Probably.just("string").act(new Print());
System.out.flush();
System.setOut(old);
System.out.println(Lab4.clean(baos.toString()));
} catch(Exception e) {
System.out.println("Error occurred");
}
try {
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
Probably.none().act(new Print());
System.out.flush();
System.setOut(old);
System.out.println(Lab4.clean(baos.toString()));
} catch(Exception e) {
System.out.println("Error occurred");
}
}
/**
* Test #3.
*/
public static void test3() {
try {
System.out.println(new Incr().invoke(4).toString());
System.out.println(new Incr().invoke(new Incr().invoke(4)).toString());
System.out.println(new Length().invoke("string").toString());
System.out.println(new Incr().invoke(new Length().invoke("string")).toString());
System.out.println(new Improbable<Integer>().invoke(1).toString());
System.out.println(new Improbable<String>().invoke(null).toString());
System.out.println(new Improbable<Integer>().invoke(1).transform(new Incr()).toString());
System.out.println(new Improbable<>().invoke(new Improbable<Integer>().invoke(1)).toString());
} catch(Exception e) {
System.out.println("Error occurred");
}
}
/**
* Test #4.
*/
public static void test4() {
try {
System.out.println(Probably.just(4).transform(new Incr()).toString());
System.out.println(Probably.just(4).transform(new Incr()).transform(new Incr()).toString());
System.out.println(Probably.just("string").transform(new Length()).toString());
System.out.println(Probably.just("string").transform(new Length()).transform(new Incr()).toString());
System.out.println(Probably.<Integer>none().transform(new Incr()).toString());
System.out.println(Probably.<String>none().transform(new Length()).toString());
System.out.println(Probably.<String>just(null).transform(new Length()).transform(new Incr()).toString());
} catch(Exception e) {
System.out.println("Error occurred");
}
}
/**
* Test #5.
*/
public static void test5() {
Probably<Immutator<Integer,Integer>> justIncr = Probably.just(new Incr());
Probably<Immutator<Integer,String>> justLength = Probably.just(new Length());
Probably<Immutator<Integer,Integer>> noIncr = Probably.none();
Probably<Immutator<Integer,String>> noLength = Probably.none();
try {
System.out.println(Probably.just(17).check(new IsModEq(3,2)).toString());
System.out.println(Probably.just(18).check(new IsModEq(3,2)).toString());
System.out.println(Probably.just(16).transform(new Incr()).check(new IsModEq(3,2)).toString());
System.out.println(Probably.just("string").transform(new Length()).transform(new Incr()).transform(new Incr()).check(new IsModEq(3,2)).toString());
System.out.println(Probably.<Integer>just(null).check(new IsModEq(0,2)).toString());
} catch(Exception e) {
System.out.println("Error occurred");
}
}
/**
* Test #6.
*/
public static void test6() {
Probably<Immutator<Integer,Integer>> justIncr = Probably.just(new Incr());
Probably<Immutator<Integer,String>> justLength = Probably.just(new Length());
Probably<Immutator<Integer,Integer>> noIncr = Probably.none();
Probably<Immutator<Integer,String>> noLength = Probably.none();
try {
System.out.println(Probably.just(17).apply(justIncr).toString());
System.out.println(Probably.<Integer>none().apply(justIncr).toString());
System.out.println(Probably.just(17).apply(noIncr).toString());
System.out.println(Probably.<Integer>none().apply(noIncr).toString());
System.out.println(Probably.just("string").apply(justLength).toString());
System.out.println(Probably.<String>none().apply(justLength).toString());
System.out.println(Probably.just("string").apply(noLength).toString());
System.out.println(Probably.<String>none().apply(noLength).toString());
} catch(Exception e) {
System.out.println("Error occurred");
}
}
}

BIN
labs/cs2030s/Lab4/Lab4.pdf Normal file

Binary file not shown.

View File

@@ -0,0 +1,60 @@
interface Function<T, R> {
R apply(T t);
}
interface Functor<T, F extends Functor<?, ?>> {
<R> F map(Function<T, R> f);
}
class Identity<T> implements Functor<T, Identity<?>> {
private final T value;
public Identity(T value) {
this.value = value;
}
@Override
public <R> Identity<R> map(Function<T, R> f) {
final R result = f.apply(this.value);
return new Identity<>(result);
}
}
class Incr implements Immutator<Integer, Integer> {
@Override
public Integer invoke(Integer param) {
return param + 1;
}
}
class Length implements Immutator<Integer, String> {
@Override
public Integer invoke(String param) {
return param.length();
}
}
class Print implements Action<Object> {
@Override
public void call(Object item) {
System.out.println(item);
}
}
class MyTest {
public static void main(String[] args) {
Probably<Integer> maybeInt = Probably.just(10);
maybeInt.act(new Print());
System.out.println(Probably.just(2030).check(new IsModEq(0, 2)));
Identity<String> idString = new Identity<>("abc");
Identity<Integer> idInt = idString.map(String::length);
}
}

View File

@@ -0,0 +1,17 @@
/**
* A non-generic Action to print the String
* representation of the object.
* CS2030S Lab 4
* AY22/23 Semester 1
*
* @author Yadunand Prem (10B)
*/
class Print implements Action<Object> {
@Override
public void call(Object item) {
System.out.println(item);
}
}

View File

@@ -0,0 +1,134 @@
/**
* This class implements something that
* probably is just a value but may be nothing.
* We will never return null in this class, but
* we may return something that contains nothing
* where the nothing is a null.
*
* @author Yadunand Prem (10B)
* @version CS2030S AY22/23 Semester 1
*/
class Probably<T> implements Actionable<T>, Immutatorable<T>, Applicable<T> {
private final T value;
private static final Probably<?> NONE = new Probably<>(null);
/**
* Private constructor, can only be invoked inside.
* This is called a factory method. We can only
* create this using the two public static method.
*
* @param value T
*/
private Probably(T value) {
this.value = value;
}
/**
* It is probably nothing, no value inside.
*
* @param <T> type T
* @return The shared NOTHING.
*/
public static <T> Probably<T> none() {
@SuppressWarnings("unchecked")
Probably<T> res = (Probably<T>) NONE;
return res;
}
/**
* It is probably just the given value.
* Unless the value is null, then nothing is
* given again.
*
* @param <T> type T
*
* @param value Probably this is the value
* unless it is null then we say
* that there is no
* @return The given value or nothing but
* never null.
*/
public static <T> Probably<T> just(T value) {
if (value == null) {
return none();
}
return new Probably<>(value);
}
/**
* Check for equality between something that
* is probably a value but maybe nothing.
*
* @param obj The other value to be compared.
* @return True if the two values are equal,
* false otherwise.
*/
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Probably<?>) {
Probably<?> some = (Probably<?>) obj;
if (this.value == some.value) {
return true;
}
if (this.value == null || some.value == null) {
return false;
}
return this.value.equals(some.value);
}
return false;
}
/**
* String representation of something that
* is probably a value but maybe nothing.
*
* @return The string representation.
*/
@Override
public String toString() {
if (this.value == null) {
return "<>";
} else {
return "<" + this.value.toString() + ">";
}
}
@Override
public void act(Action<? super T> action) {
if (this.value == null) {
return;
}
action.call(this.value);
}
public Probably<T> check(Immutator<Boolean, ? super T> eq) {
if (this.value == null) {
return none();
}
if (eq.invoke(this.value)) {
return this;
}
return none();
}
@Override
public <R> Probably<R> transform(Immutator<? extends R, ? super T> immutator) {
if (this.value == null) {
return none();
}
return just(immutator.invoke(this.value));
}
@Override
public <R> Probably<R> apply(Probably<? extends Immutator<? extends R, ? super T>> probablyImmutator) {
if (probablyImmutator.value != null) {
return this.transform(probablyImmutator.value);
}
return none();
}
}

View File

@@ -0,0 +1,32 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
class Test1 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
PrintStream old = System.out;
ByteArrayOutputStream baos;
PrintStream ps;
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
new Print().call(17);
we.expectPrint("new Print().call(17)",
"17",
baos,
old);
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
new Print().call("string");
we.expectPrint("new Print().call(\"string\")",
"string",
baos,
old);
}
}

View File

@@ -0,0 +1,42 @@
import java.io.PrintStream;
import java.io.ByteArrayOutputStream;
class Test2 {
public static void main(String[] args) {
CS2030STest we = new CS2030STest();
PrintStream old = System.out;
ByteArrayOutputStream baos;
PrintStream ps;
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
Probably.just(4).act(new Print());
we.expectPrint("Probably.just(4).act(new Print())",
"4",
baos,
old);
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
Probably.just("string").act(new Print());
we.expectPrint("Probably.just(\"string\").act(new Print())",
"string",
baos,
old);
baos = new ByteArrayOutputStream();
ps = new PrintStream(baos);
System.setOut(ps);
Probably.none().act(new Print());
we.expectPrint("Probably.none().act(new Print())",
"",
baos,
old);
}
}

Some files were not shown because too many files have changed in this diff Show More