diff --git a/src/Global.java b/src/Global.java
index 2813be5fc6818ce1e73393bec6d5e5d7481017be..67914363ce901da998be38f283b35c01f95b344b 100644
--- a/src/Global.java
+++ b/src/Global.java
@@ -4,28 +4,36 @@
  */
 public class Global {
 	
-	private SRTF srtf = new SRTF(); //high priority scheduler
-	private RR rr = new RR(); //low priority scheduler
+	private SRTF srtf = new SRTF(this); //high priority scheduler
+	private RR rr = new RR(this); //low priority scheduler
 	
 	String history = ""; //a string with tha names of task that have taken control so far - I will use this only for the output
 	
 	public void add(Task t) {
-		if (t.isKernel)
+		Main.schedulersEmpty=false;
+		
+		if (t.isKernel) {
 			srtf.add(t);
-		else
+			rr.stop();
+		} else {
 			rr.add(t);
+		}
 	}
 	
 	public void tick() {
+		if(srtf.isEmpty() && rr.isEmpty()) {Main.schedulersEmpty = true; return;}
 	
+		srtf.tick();
+		rr.tick();
+		if (srtf.isEmpty()) rr.start();
 	}
 	
 	/**
-	 * A task is forcibly taking control
+	 * A task is taking control
 	 * @param t the task to be run
 	 */
 	public void changeRunning(Task t) {
-	
+		history += t.name;
 	}
 	
 }
diff --git a/src/Main.java b/src/Main.java
index 1ce56a9a96ce6e02c88eee0fb49136232e52c657..b1e2db716d959fafedee8ca31e85fd3e5f5f5b9e 100644
--- a/src/Main.java
+++ b/src/Main.java
@@ -1,7 +1,77 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+
 public class Main {
 	
+	private static LinkedList<Task> tasks = new LinkedList<>(); //stores all the tasks in ascending order regarding start times
+	private static LinkedList<Task> runningTasks = new LinkedList<>(); //stores a backup pointer of all task because we delete them from tasks when giving to the scheduler; used only for determining waiting times
+	static boolean schedulersEmpty = true; //signals if the schedulers emptied out
+	
+	private static Global scheduler = new Global();
+	
 	public static void main(String[] args) {
-		System.out.println("Hello world!");
+		
+		//reading input
+		//-------------
+		
+		BufferedReader sysIn = new BufferedReader(new InputStreamReader(System.in));
+		
+		String currentLine;
+		try {
+			
+			currentLine = sysIn.readLine();
+			while (!(currentLine==null) && !currentLine.equals("")) {
+				String[] lineContent = currentLine.split(",");
+				Task readTask = new Task(lineContent[0].charAt(0), lineContent[1].equals("0"), Integer.parseInt(lineContent[2]), Integer.parseInt(lineContent[3]));
+				
+				//inserting read task to tasks
+				if (tasks.size() == 0) {tasks.add(readTask);}
+				else {
+					int i=0;
+					while(tasks.size() <= i && tasks.get(i).startTime < readTask.startTime) i++;
+					tasks.add(i, readTask);
+				}
+				
+				currentLine = sysIn.readLine();
+			}
+			
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+		//running simulation
+		//------------------
+		
+		//special case: no tasks
+		if(tasks.size()==0) {System.out.println("\n\n"); return;}
+		
+		for(int now = 0; tasks.size()>0 || !schedulersEmpty; now++) {
+			//adding incoming tasks
+			for(int i=0; i<tasks.size(); i++) {
+				if(tasks.get(i).startTime == now) {
+					scheduler.add(tasks.get(i));
+					runningTasks.add(tasks.get(i));
+					tasks.remove(i);
+				}
+			}
+			
+			//ticking
+			scheduler.tick();
+		}
+		
+		
+		
+		//writing output
+		//--------------
+		System.out.println(scheduler.history);
+		
+		System.out.print(runningTasks.get(0).name + ":" + runningTasks.get(0).getWaitingTime());
+		for(int i = 1; i< runningTasks.size(); i++) {
+			System.out.print("," + runningTasks.get(i).name + ":" + runningTasks.get(i).getWaitingTime());
+		}
+		
 	}
 	
 }
diff --git a/src/RR.java b/src/RR.java
index 0e21b5aead2b67e085f550732e226383619ec2ca..ea965d3120333c69d3efdfb049b1717df3230e96 100644
--- a/src/RR.java
+++ b/src/RR.java
@@ -1,4 +1,4 @@
-import java.util.PriorityQueue;
+import java.util.ArrayDeque;
 import java.util.Queue;
 
 /**
@@ -6,18 +6,29 @@ import java.util.Queue;
  */
 public class RR {
 	
+	private final Global global;
+	
 	private static final int timeSlice = 2; //time in ticks while a task is allowed to run
 	private int runningFor = 0; //the number of timeslices the active task has been running for
 	
-	private Queue<Task> waitingQueue = new PriorityQueue<>(); //inactive tasks
-	private Task activeTask; //the active task; null if there are none
+	private boolean enabled = true;
 	
-	public void start() {
+	private Queue<Task> waitingQueue = new ArrayDeque<>(); //inactive tasks
+	private Task activeTask = null; //the active task; null if there are none
 	
+	public RR(Global global) {
+		this.global = global;
 	}
 	
-	public void stop() {
+	public void start() {
+		enabled = true;
+	}
 	
+	public void stop() {
+		enabled = false;
+		runningFor = 0;
+		if(activeTask!=null) waitingQueue.add(activeTask);
+		activeTask = null;
 	}
 	
 	public void add(Task t) {
@@ -28,7 +39,38 @@ public class RR {
 	 * signals a processor tick
 	 */
 	public void tick() {
+		if(!enabled) {
+			//System.out.println("Running RR: " + ((activeTask == null) ? "null" : activeTask.name));
+			for(Task t : waitingQueue) t.waitOne();
+			return;
+		}
+		
+		runningFor++;
+		
+		//swapping
+		if(waitingQueue.size() > 0 && (runningFor == timeSlice || activeTask == null)) { //we swap if we can and if we need to; we need to when the running period is over or the current task is not running anymore
+			
+			if (activeTask != null) waitingQueue.add(activeTask);
+			activeTask = waitingQueue.remove();
+			
+			global.changeRunning(activeTask);
+			
+			runningFor = 0;
+		}
+		
+		//System.out.println("Running RR: " + ((activeTask == null) ? "null" : activeTask.name));
+		
+		//registering time flow
+		for(Task t : waitingQueue) t.waitOne();
+		if(activeTask!=null) {
+			activeTask.runOne();
+			if(activeTask.remainingTime == 0) activeTask = null;
+		}
+		
+	}
 	
+	public boolean isEmpty() {
+		return activeTask==null && waitingQueue.size()==0;
 	}
 	
 }
diff --git a/src/SRTF.java b/src/SRTF.java
index 925c509251fa0057b953ef36d36f9f3eb11c3ded..6d0d01d9e027ab161511ab23d61252331d5d93f1 100644
--- a/src/SRTF.java
+++ b/src/SRTF.java
@@ -1,23 +1,62 @@
-import java.util.PriorityQueue;
-import java.util.Queue;
+import java.util.LinkedList;
 
 /**
  * An SRTF (shortest remaining time first) scheduler designed for high priority tasks
  */
 public class SRTF {
 	
-	private Queue<Task> waitingQueue = new PriorityQueue<>(); //inactive tasks
-	private Task activeTask; //active task; null if there are none
+	private final Global global;
+	
+	private LinkedList<Task> waitingQueue = new LinkedList<>(); //inactive tasks
+	private Task activeTask = null; //active task; null if there are none
+	
+	private boolean needSwap = true; //stores if the active task should be changed
+	
+	public SRTF(Global global) {
+		this.global = global;
+	}
 	
 	public void add(Task t) {
 		waitingQueue.add(t);
+		
+		if(activeTask == null || t.remainingTime < activeTask.remainingTime) needSwap = true;
 	}
 	
 	/**
 	 * signals a processor tick
 	 */
 	public void tick() {
-	
+		if (isEmpty()) return;
+		
+		//swapping if necessary
+		if (needSwap) {
+			int minIndex = -1; int minValue = Integer.MAX_VALUE;
+			for(int i=0; i<waitingQueue.size(); i++) {
+				if (waitingQueue.get(i).remainingTime < minValue) {minValue = waitingQueue.get(i).remainingTime; minIndex = i;}
+			}
+			
+			Task temp = activeTask;
+			activeTask = waitingQueue.get(minIndex);
+			waitingQueue.remove(minIndex);
+			if(temp != null) waitingQueue.add(temp);
+			
+			global.changeRunning(activeTask);
+			
+			needSwap = false;
+		}
+		
+		//System.out.print("SRTF interrupt: " + activeTask.name + " ");
+		
+		//registering time flowing
+		for(Task t : waitingQueue) t.waitOne();
+		activeTask.runOne();
+		if(activeTask.remainingTime == 0) {
+			needSwap = true;
+			activeTask = null;
+		}
 	}
 	
+	public boolean isEmpty() {
+		return activeTask==null && waitingQueue.size()==0;
+	}
 }