[프로그래머스] 디스크 컨트롤러
const solution = (jobs) => {
const jobSize = jobs.length
const PQ = new PriorityQueue()
let time = 0
let enterTime = 0
let successTime = 0
let isProcess = false
const endProcess = []
while (endProcess.length < jobSize) {
const pushList = jobs.filter((job) => job[0] === time)
for (const el of pushList) {
PQ.push({ enterTime: el[0], processTime: el[1] })
}
if (time !== 0 && time === successTime) {
endProcess.push(successTime - enterTime)
isProcess = false
}
if (PQ.queue.length !== 1 && isProcess === false) {
const popElement = PQ.pop()
enterTime = popElement.enterTime
successTime = time + popElement.processTime
isProcess = true
}
time++
}
return Math.trunc(endProcess.reduce((acc, cur) => acc + cur, 0) / endProcess.length)
}
class PriorityQueue {
constructor(fn) {
this.queue = [null]
}
push(element) {
const queue = this.queue
queue.push(element)
const queueSize = queue.length
if (queueSize === 2) {
return
}
let currentIdx = queueSize - 1
let parentIdx
while (currentIdx > 1) {
parentIdx = Math.trunc(currentIdx / 2)
if (queue[currentIdx].processTime > queue[parentIdx].processTime) {
break
}
this.swap(queue, currentIdx, parentIdx)
currentIdx = parentIdx
}
}
pop() {
const queue = this.queue
const queueSize = queue.length
if (queueSize === 2) {
return queue.pop()
}
this.swap(queue, 1, queueSize - 1)
const popData = queue.pop()
let currentIdx = 1
while (currentIdx < queueSize) {
const result = this.check(queue, currentIdx)
if (result === null) {
break
}
if (queue[currentIdx].processTime <= queue[result].processTime) {
break
}
this.swap(queue, currentIdx, result)
currentIdx = result
}
return popData
}
check(queue, idx) {
const leftChildIdx = idx * 2
const rightChildIdx = idx * 2 + 1
if (!queue[leftChildIdx]) {
return null
} else if (!queue[rightChildIdx]) {
return leftChildIdx
}
return queue[leftChildIdx].processTime < queue[rightChildIdx].processTime ? leftChildIdx : rightChildIdx
}
swap(queue, i, j) {
;[queue[i], queue[j]] = [queue[j], queue[i]]
}
display() {
console.log(this.queue)
}
}