class maxHeap {
  constructor() {
    this.heap = [];
    this.heap.push(Number.MAX_SAFE_INTEGER);
  }
  insert(val) {
    this.heap.push(val);
    this.upheap(this.heap.length - 1);
  }
  // pos = push한 값의 인덱스 번호
  upheap(pos) {
    let tmp = this.heap[pos];
    while (tmp > this.heap[parseInt(pos / 2)]) {
      this.heap[pos] = this.heap[parseInt(pos / 2)];
      pos = parseInt(pos / 2);
    }
    this.heap[pos] = tmp;
  }
  get() {
    if (this.heap.length === 2) {
      return this.heap.pop();
    }
    let res = this.heap[1];
    this.heap[1] = this.heap.pop();
    this.downheap(1, this.heap.length - 1);
    return res;
  }
  downheap(pos, len) {
    let tmp = this.heap[pos];
    let child;
    while (pos < parseInt(len / 2)) {
      child = pos * 2;
      // 우측 자식이 더 크면 child값 재할당
      if (child < len && this.heap[child] < this.heap[child + 1]) child++;
      if (tmp >= this.heap[child]) break;
      this.heap[pos] = this.heap[child];
      pos = child;
    }
    this.heap[pos] = tmp;
  }
  size() {
    return this.heap.length - 1;
  }
  show() {
    for (let i = 1; i <= this.size(); i++) {
      console.log(this.heap[i]);
    }
    return true;
  }
}
function solution(nums, m) {
  let cnt = 0;
  let answer = Number.MAX_SAFE_INTEGER;
  for (let n of nums) {
    if (m % n === 0) answer = Math.min(answer, m / n);
  }
  while (m > 0) {
    if (m - nums[nums.length - 1] >= 0) {
      m = m - nums[nums.length - 1];
      cnt++;
    } else {
      nums.pop();
    }
  }
  return Math.min(answer, cnt);
}
function solution2(nums, m) {
  let answer = 0;
  let lt = 0,
    rt = nums.length - 1;
  nums.sort((a, b) => a - b);
  while (lt <= rt) {
    if (nums[lt] + nums[rt] <= m) {
      answer++;
      lt++;
      rt--;
    } else {
      answer++;
      rt--;
    }
  }
  return answer;
}
function solution(meeting) {
  let answer = 0;
  meeting.sort((a, b) => {
    if (a[1] === b[1]) return a[0] - b[0];
    else return a[1] - b[1];
  });
  let et = 0;
  for (let x of meeting) {
    if (x[0] >= et) {
      answer++;
      et = x[1];
    }
  }
  return answer;
}
function solution(nums) {
  let maxH = new maxHeap();
  for (let x of nums) {
    maxH.insert(x);
  }
  maxH.get();
  maxH.show();
  while (maxH.size() > 1) {
    let a = maxH.get();
    let b = maxH.get();
    if (a !== b) {
      maxH.insert(a - b);
    }
  }
  maxH.show();
  if (maxH.size() === 0) return 0;
  return maxH.get();
}
우선순위큐를 쓰는 대표적 그리디
function solution2(nums) {
  let answer = 0;
  let maxH = new maxHeap();
  nums.sort((a, b) => b[1] - a[1]);
  let maxday = nums[0][1];
  let i = 0;
  for (let day = maxday; day >= 1; day--) {
    for (; i < nums.length; i++) {
      if (nums[i][1] < day) break;
      maxH.insert(nums[i][0]);
    }
    if (maxH.size() > 0) {
      answer += maxH.get();
    }
  }
  return answer;
}
function solution(s) {
  let sH = new Map();
  let sorted1 = s.split("").sort((a, b) => a.charCodeAt() - b.charCodeAt());
  for (let i = 0; i < sorted1.length; i++) {
    sH.set(sorted1[i], sH.get(sorted1[i]) + 1 || 1);
  }
  let sorted2 = [...sH.entries()].sort((a, b) => b[1] - a[1]);
  let answer = sorted2.map((e) => e[0].repeat(e[1]));
  return answer.join("");
}
function solution(nums, m) {
  let answer = 0;
  let mul = 1,
    lt = 0;
  for (let rt = 0; rt < nums.length; rt++) {
    mul *= nums[rt];
    while (mul > m) {
      mul /= nums[lt++];
    }
    answer += rt - lt + 1;
  }
  return answer;
}
function solution(s) {
  let stack = [],
    tmp = [];
  for (let i = 0; i < s.length; i++) {
    if (s[i] === ")") {
      while (stack[stack.length - 1] !== "(") {
        tmp.unshift(stack.pop());
      }
      stack.pop();
      if (!isNaN(stack[stack.length - 1])) {
        let loop = stack.pop();
        if (!isNaN(stack[stack.length - 1])) {
          loop = stack.pop() + loop;
        }
        for (let j = 0; j < parseInt(loop); j++) {
          stack.push(tmp.join(""));
        }
        tmp = [];
      }
    } else {
      stack.push(s[i]);
    }
  }
  return stack.join("");
}