/**
* author : kaidul
**/
using namespace std;
#include <iostream>
#include <cstdio>
#include <queue>
#include <bitset>
#define M 100
struct process {
int processId, arrivalTime, burstTime, priority;
int waitingTime, turnAroundTime, responseTime;
bool operator < (const process& a) const {
if(arrivalTime == a.arrivalTime) return burstTime > a.burstTime;
return arrivalTime > a.arrivalTime;
}
} pArray[M];
struct waitingProcess {
int processId, arrivalTime, burstTime, priority;
bool operator < (const waitingProcess& a) const {
if(burstTime == a.burstTime) return arrivalTime > a.arrivalTime;
return burstTime > a.burstTime;
}
} wp;
priority_queue<process> q;
priority_queue<waitingProcess> waitingList;
bitset <M> taken;
struct timeLine {
int proc, start, end;
} tmline[M];
int nProcess, timeInterval, averageTime;
float throughtputTime;
int main() {
freopen("input.txt", "r", stdin);
cin >> nProcess;
for (int i = 1; i <= nProcess ; i++) {
pArray[i].processId = i;
cin >> pArray[i].arrivalTime >> pArray[i].burstTime >> pArray[i].priority;
q.push(pArray[i]);
}
cin >> timeInterval;
cout << "Shortest Job First - Preemptive : \n";
int i = 1;
process next, top;
waitingProcess waiting;
tmline[0].start = 0, tmline[0].proc = 0, tmline[0].end = 0;
cout << "\nExecution Sequence : \n";
while (!waitingList.empty() || !q.empty()) {
tmline[i].start = tmline[i-1].end;
if(waitingList.empty() && !q.empty()) {
top = q.top();
q.pop();
if(!q.empty()) {
waitingProcess p;
next = q.top();
if(next.arrivalTime < (top.burstTime + tmline[i-1].end)) {
tmline[i].end = next.arrivalTime;
tmline[i].proc = top.processId;
int exeRemain = (top.burstTime + tmline[i-1].end) - next.arrivalTime;
p.processId = top.processId, p.arrivalTime = top.arrivalTime, p.priority = top.priority, p.burstTime = exeRemain;
waitingList.push(p);
} else {
tmline[i].end = tmline[i].start + top.burstTime;
tmline[i].proc = top.processId;
}
} else {
tmline[i].end = tmline[i].start + top.burstTime;
tmline[i].proc = top.processId;
}
} else if(!waitingList.empty() && q.empty()) { // queue khali, waiting list khali na - sobtheke soja case
waitingProcess wt = waitingList.top();
tmline[i].end = tmline[i].start + wt.burstTime;
tmline[i].proc = wt.processId;
waitingList.pop();
} else { // both queue have processes
top = q.top();
waiting = waitingList.top();
if(top.burstTime < waiting.burstTime) {
q.pop();
if(!q.empty()) {
waitingProcess wt;
next = q.top();
if(next.arrivalTime < (top.burstTime + tmline[i-1].end)) {
tmline[i].end = next.arrivalTime;
tmline[i].proc = top.processId;
int exeRemain = (top.burstTime + tmline[i-1].end) - next.arrivalTime;
wt.processId = top.processId, wt.arrivalTime = top.arrivalTime, wt.priority = top.priority, wt.burstTime = exeRemain;
waitingList.push(wt);
} else {
tmline[i].end = tmline[i].start + top.burstTime;
tmline[i].proc = top.processId;
}
} else {
tmline[i].end = tmline[i].start + top.burstTime;
tmline[i].proc = top.burstTime;
}
} else { // waitinglist and queue 2ta tei process ase, waiting er tar burst time kom, so se age execute hobe
q.pop();
waitingList.pop();
waitingProcess wt;
wt.processId = top.processId ,wt.arrivalTime = top.arrivalTime, wt.burstTime = top.burstTime, wt.priority = top.priority;
waitingList.push(wt);
tmline[i].end = tmline[i].start + waiting.burstTime;
tmline[i].proc = waiting.processId;
}
}
cout << tmline[i].start << " " << tmline[i].end << " " << tmline[i].proc << "\n";
i++;
}
cout << "\n";
taken.reset();
int range = i -1;
// calulating response time
for (int i = 1; i <= range; i++) {
if(taken.test(tmline[i].proc)) continue;
pArray[tmline[i].proc].responseTime = tmline[i].start - pArray[tmline[i].proc].arrivalTime;
taken.set(tmline[i].proc, 1);
}
// Calculating Turn-Around Time
taken.reset();
for (int i = range; i >= 1; i--) {
if(taken.test(tmline[i].proc)) continue;
pArray[tmline[i].proc].turnAroundTime = tmline[i].end - pArray[tmline[i].proc].arrivalTime;
taken.set(tmline[i].proc, 1);
}
// Calculating Waiting Time
/**
key: turn-around time = execution(burst) time + waiting time
**/
int total = 0;
for (int i = 1; i <= nProcess; i++ ) {
pArray[i].waitingTime = pArray[i].turnAroundTime - pArray[i].burstTime;
cout << pArray[i].processId << "\n";
cout << "Waiting Time : " << pArray[i].waitingTime << "\n";
total += pArray[i].waitingTime;
cout << "TurnAround Time : " << pArray[i].turnAroundTime << "\n";
cout << "Response Time : " << pArray[i].responseTime << "\n\n";
}
averageTime = total / nProcess;
cout << "Average waiting Time : " << averageTime << "\n";
throughtputTime = (float)nProcess / tmline[range].end;
cout << "Throughput Time : " << throughtputTime << "\n";
return false;
}