07:16:24
icon

:: PriorityQueue {
  @init() {
    return {data: []}
  }
  @len(q) {
    return q.data.len
  }
  @top(q) {
    return q.data[0]
  }
  @push(q,v) {
    var ind = q.data.len
    q.data.push(v)
    loop {
      if ind == 0 break
      let next = if ind % 2 == 0 {(ind-2) / 2} else {(ind-1) / 2}
      if q.data[ind] < q.data[next] {
        let tmp = q.data[ind]
        q.data[ind] = q.data[next]
        q.data[next] = tmp
        ind = next
        continue
      }
      else {break}
    }
    return null
  }
  @pop(q) {
    let v = q.data[0]
    if q.data.len == 1 {
      q.data.pop()
      return v
    }
    q.data[0] = q.data.pop()
    var ind = 0
    loop {
      if (ind*2)+1 >= q.data.len {break}
      if (ind*2)+2 >= q.data.len {
        if q.data[ind*2+1] < q.data[ind] {
          let tmp = q.data[ind]
          q.data[ind] = q.data[ind*2+1]
          q.data[ind*2+1] = tmp
          ind = ind*2+1
          continue
        }
        else {break}
      }
      let next = if q.data[ind*2+1] < q.data[ind*2+2] {ind*2+1} else {ind*2+2}
      if q.data[next] < q.data[ind] {
        let tmp = q.data[ind]
        q.data[ind] = q.data[next]
        q.data[next] = tmp
        ind = next
        continue
      }
      else {break}
    }
    return v
  }
}

var a = PriorityQueue:init()
PriorityQueue:push(a,3)
PriorityQueue:push(a,1)
PriorityQueue:push(a,4)
<:PriorityQueue:pop(a)//1
<:PriorityQueue:pop(a)//3
PriorityQueue:push(a,1)
<:PriorityQueue:len(a)//2
PriorityQueue:push(a,5)
PriorityQueue:push(a,9)
<:PriorityQueue:top(a)//1
PriorityQueue:pop(a)
<:PriorityQueue:top(a)//4