Advertisement
Guest User

Untitled

a guest
Dec 7th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 4.84 KB | None | 0 0
  1. import "container/heap"
  2.  
  3. type Interval struct {
  4.     start, end int
  5.     index int
  6. }
  7.  
  8. func (i *Interval) String() string {
  9.     return fmt.Sprintf("[%d; %d] (%d)", i.start, i.end, i.maxDist())
  10. }
  11.  
  12. func (i *Interval) maxDist() int {
  13.     d := i.end - i.start - 1
  14.     if d % 2 == 0 {
  15.         d--
  16.     }
  17.     return d / 2
  18. }
  19.  
  20. type IntervalsPQ []*Interval
  21.  
  22. func (pq IntervalsPQ) Len() int { return len(pq) }
  23.  
  24. func (pq IntervalsPQ) Less(i, j int) bool {
  25.     iDist, jDist := pq[i].maxDist(), pq[j].maxDist()
  26.     if iDist == jDist {
  27.         ni, nj := pq[i].end - pq[i].start > 1, pq[j].end - pq[j].start > 1
  28.         if ni == nj {
  29.             return pq[i].start < pq[j].start
  30.         }
  31.         return ni
  32.     }
  33.     return iDist > jDist
  34. }
  35.  
  36. func (pq IntervalsPQ) Swap(i, j int) {
  37.     pq[i], pq[j] = pq[j], pq[i]
  38.     pq[i].index = i
  39.     pq[j].index = j
  40. }
  41.  
  42. func (pq *IntervalsPQ) Push(x interface{}) {
  43.     interval := x.(*Interval)
  44.     interval.index = len(*pq)
  45.     *pq = append(*pq, interval)
  46. }
  47.  
  48. func (pq *IntervalsPQ) Pop() interface{} {
  49.     old := *pq
  50.     n := len(old)
  51.     item := old[n-1]
  52.     old[n-1] = nil  // avoid memory leak
  53.     item.index = -1 // for safety
  54.     *pq = old[:n-1]
  55.     return item
  56. }
  57.  
  58.  
  59. type ExamRoom struct {
  60.     intervals IntervalsPQ
  61.     initialInterval *Interval
  62.     n int
  63.     mapping map[int][2]*Interval
  64. }
  65.  
  66.  
  67. func Constructor(N int) ExamRoom {
  68.     return ExamRoom{intervals: make(IntervalsPQ, 0), n: N, mapping: make(map[int][2]*Interval)}
  69. }
  70.  
  71.  
  72. func (e *ExamRoom) Seat() int {
  73.     // If there is not enough students to create an interval.
  74.     if len(e.intervals) == 0 {
  75.         if e.initialInterval == nil {
  76.             e.initialInterval = &Interval{start: -1, end: e.n}
  77.         }
  78.         if e.initialInterval.start < 0 {
  79.             // Put the student at position 0.
  80.             e.initialInterval.start = 0
  81.             m := e.mapping[0]
  82.             m[1] = e.initialInterval
  83.             e.mapping[0] = m
  84.             return 0
  85.         } else {
  86.             e.initialInterval.end = e.n - 1
  87.             // Add the interval to the heap.
  88.             heap.Push(&e.intervals, e.initialInterval)
  89.             // Update the mapping.
  90.             m := e.mapping[e.n - 1]
  91.             m[0] = e.initialInterval
  92.             e.mapping[e.n - 1] = m
  93.             return e.n - 1
  94.         }
  95.     }
  96.     // Find the largest interval and split it into 2 intervals.
  97.     interval := heap.Pop(&e.intervals).(*Interval)
  98.     // Handle edge case intervals (left-most and right-most).
  99.     if interval.start < 0 {
  100.         interval.start = 0
  101.         heap.Push(&e.intervals, interval)
  102.         e.mapping[0] = [2]*Interval{nil, interval}
  103.         return 0
  104.     } else if interval.end >= e.n {
  105.         interval.end = e.n - 1
  106.         heap.Push(&e.intervals, interval)
  107.         e.mapping[e.n - 1] = [2]*Interval{interval, nil}
  108.         return e.n - 1
  109.     }
  110.     // Position for the new student.
  111.     position := (interval.start + interval.end) / 2
  112.     // Handle general case.
  113.     left := &Interval{
  114.         start: interval.start,
  115.         end: position,
  116.     }
  117.     right := &Interval {
  118.         start: position,
  119.         end: interval.end,
  120.     }
  121.     // Put them both to the heap.
  122.     heap.Push(&e.intervals, left)
  123.     heap.Push(&e.intervals, right)
  124.     // Update the mapping.
  125.     m := e.mapping[interval.start]
  126.     m[1] = left
  127.     e.mapping[interval.start] = m
  128.    
  129.     m = e.mapping[interval.end]
  130.     m[0] = right
  131.     e.mapping[interval.end] = m
  132.    
  133.     e.mapping[position] = [2]*Interval{left, right}
  134.     return position
  135. }
  136.  
  137. func (e *ExamRoom) Leave(p int)  {
  138.     m, ok := e.mapping[p]
  139.     if !ok {
  140.         panic(fmt.Sprintf("student %d not found in mapping", p))
  141.     }
  142.     left, right := m[0], m[1]
  143.     // Merge intervals.
  144.     if left != nil && right != nil {
  145.         // Extend the left interval, get rid of the right one.
  146.         left.end = right.end
  147.         // Update the mapping.
  148.         var m [2]*Interval
  149.         if left.start >= 0 {
  150.             m = e.mapping[left.start]
  151.             m[1] = left
  152.             e.mapping[left.start] = m
  153.         }
  154.         if left.end < e.n {
  155.             m = e.mapping[left.end]
  156.             m[0] = left
  157.             e.mapping[left.end] = m
  158.         }
  159.         // Update the heap invariant for the left interval.
  160.         heap.Fix(&e.intervals, left.index)
  161.         // Remove the right interval from the heap.
  162.         heap.Remove(&e.intervals, right.index)
  163.     } else if left == nil {
  164.         right.start = -right.end
  165.         heap.Fix(&e.intervals, right.index)
  166.     } else if right == nil {
  167.         left.end = e.n - 1 + (e.n - 1 - left.start)
  168.         heap.Fix(&e.intervals, left.index)
  169.     } else {
  170.         panic("removing non-existing student")
  171.     }
  172.    
  173.     delete(e.mapping, p)
  174. }
  175.  
  176.  
  177. /**
  178.  * Your ExamRoom object will be instantiated and called as such:
  179.  * obj := Constructor(N);
  180.  * param_1 := obj.Seat();
  181.  * obj.Leave(p);
  182.  */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement