Scheduling is how the processor decides which jobs (processes) get to use the processor and for how long. This can cause a lot of problems. Like a really long process taking the entire CPU and freezing all the other processes. One solution is Round-Robin, which today you will be implementing.

Round-Robin works by queuing jobs in a First In First Out fashion, but the processes are only given a short slice of time. If a processes is not finished in that time slice, it yields the proccessor and goes to the back of the queue.

For this Kata you will be implementing the 
```python
  def roundRobin(jobs, slice, index):
```

It takes in:

    1. "jobs" a non-empty positive integer array. It represents the queue and clock-cycles(cc) remaining till the job[i] is finished.

    2. "slice" a positive integer. It is the amount of clock-cycles that each job is given till the job yields to the next job in the queue.

    3. "index" a positive integer. Which is the index of the job we're interested in.

roundRobin returns:

    1. the number of cc till the job at index is finished.

Here's an example:
```
roundRobin([10,20,1], 5, 0) 
at 0cc [10,20,1] jobs[0] starts
after 5cc [5,20,1] jobs[0] yields, jobs[1] starts
after 10cc [5,15,1] jobs[1] yields, jobs[2] starts
after 11cc [5,15,0] jobs[2] finishes, jobs[0] starts
after 16cc [0,15,0] jobs[0] finishes
```

so:
```
roundRobin([10,20,1], 5, 0) == 16
```

**You can assume that the processor can switch jobs between cc so it does not add to the total time.

Difficulty: introductory

Starter code:

def roundRobin(jobs, slice, index):
	

Solutions:
def roundRobin(jobs, slice, index):
    total_cc = 0
    while True:
        for idx in range(len(jobs)):
            cc = min(jobs[idx], slice)
            jobs[idx] -= cc
            total_cc += cc
            if idx == index and jobs[idx] == 0:
                return total_cc

def roundRobin(jobs, slice, index):
    q = (jobs[index] - 1) // slice
    return (
        sum(min(x, (q+1) * slice) for x in jobs[:index+1]) +
        sum(min(x, q * slice)     for x in jobs[index+1:])
    )

def roundRobin(jobs, slice, index):
    i, res, jobs = 0, 0, jobs[:]
    while jobs[index]:
        res += min(slice, jobs[i])
        jobs[i] = max(0, jobs[i]-slice)
        i = (i+1)%len(jobs)
    return res

def roundRobin(jobs, slice, index):
    cc = i = 0
    while jobs[index] > 0:
        cc += min(slice, jobs[i])
        jobs[i] = max(0, jobs[i] - slice)
        i = (i + 1) % len(jobs)
    return cc


import math

def ceil(value, step):
    return math.ceil(value / step) * step

def floor(value, step):
    return math.floor(value / step) * step

def roundRobin(jobs, frame, index):
    for i in range(index):
        jobs[i] = min(jobs[i], ceil(jobs[index], frame))
    for i in range(index + 1, len(jobs)):
        jobs[i] = min(jobs[i], floor(jobs[index] - 1, frame))
    return sum(jobs)


def roundRobin(jobs, slice, index):
    num_slices = (jobs[index] + slice - 1) // slice
    before = num_slices * slice
    after = (num_slices - 1) * slice
    return sum(min(before, cc) for cc in jobs[0:index]) \
            + sum(min(after, cc) for cc in jobs[index + 1:]) + jobs[index]


roundRobin=lambda a,n,i:sum(min((a[i]+n*(i>=j)-1)//n*n,v)for j,v in enumerate(a))

def roundRobin(jobs, sl, index):
    start_sum = sum(jobs)
    cur_idx = 0
    while jobs[index] > 0:
        jobs[cur_idx] = jobs[cur_idx] - min(jobs[cur_idx], sl)
        cur_idx = (cur_idx + 1) % len(jobs)
    return start_sum - sum(jobs)

def roundRobin(jobs, limit, target):
    queue = list(enumerate(jobs))
    cycles = 0
    while True:
        index, job = queue.pop(0)
        if limit >= job:
            cycles += job
            job = 0
        else:
            job -= limit
            cycles += limit
        if job:
            queue.append((index, job))
        elif index == target:
            break
    return cycles