Robot Collisions

hard stack simulation sorting

Problem

Robots stand on a line, each with a position, a health value, and a direction ('L' for left or 'R' for right). All robots move at the same speed and start moving at once. When a right-moving robot reaches a left-moving robot they collide: the one with smaller health is removed and the survivor loses 1 health; if their healths are equal, both are removed. Two robots heading the same way never collide. Return the healths of the surviving robots in the order their indices appear in the original input.

Inputpositions = [3, 5, 2, 6], healths = [10, 10, 15, 12], directions = "RLRL"
Output[14]
Robot 1 (at 5, going L) meets robot 0 (at 3, going R): equal health 10 vs 10, both die. Robot 3 (at 6, going L) meets robot 2 (at 2, going R): 12 < 15, so robot 3 dies and robot 2 drops to 14. Only robot 2 survives.

def survived_robots_healths(positions, healths, directions):
    order = sorted(range(len(positions)), key=lambda i: positions[i])
    stack = []
    for i in order:
        if directions[i] == 'R':
            stack.append(i)
            continue
        while stack and healths[i] > 0:
            top = stack[-1]
            if healths[top] < healths[i]:
                healths[top] = 0
                healths[i] -= 1
                stack.pop()
            elif healths[top] > healths[i]:
                healths[i] = 0
                healths[top] -= 1
            else:
                healths[i] = 0
                healths[top] = 0
                stack.pop()
    return [h for h in healths if h > 0]
function survivedRobotsHealths(positions, healths, directions) {
  const order = [...positions.keys()].sort((a, b) => positions[a] - positions[b]);
  const stack = [];
  for (const i of order) {
    if (directions[i] === 'R') {
      stack.push(i);
      continue;
    }
    while (stack.length && healths[i] > 0) {
      const top = stack[stack.length - 1];
      if (healths[top] < healths[i]) {
        healths[top] = 0;
        healths[i] -= 1;
        stack.pop();
      } else if (healths[top] > healths[i]) {
        healths[i] = 0;
        healths[top] -= 1;
      } else {
        healths[i] = 0;
        healths[top] = 0;
        stack.pop();
      }
    }
  }
  return healths.filter(h => h > 0);
}
class Solution {
    public List<Integer> survivedRobotsHealths(int[] positions, int[] healths, String directions) {
        Integer[] order = new Integer[positions.length];
        for (int i = 0; i < order.length; i++) order[i] = i;
        Arrays.sort(order, (a, b) -> positions[a] - positions[b]);
        Deque<Integer> stack = new ArrayDeque<>();
        for (int i : order) {
            if (directions.charAt(i) == 'R') {
                stack.push(i);
                continue;
            }
            while (!stack.isEmpty() && healths[i] > 0) {
                int top = stack.peek();
                if (healths[top] < healths[i]) {
                    healths[top] = 0;
                    healths[i] -= 1;
                    stack.pop();
                } else if (healths[top] > healths[i]) {
                    healths[i] = 0;
                    healths[top] -= 1;
                } else {
                    healths[i] = 0;
                    healths[top] = 0;
                    stack.pop();
                }
            }
        }
        List<Integer> res = new ArrayList<>();
        for (int h : healths) if (h > 0) res.add(h);
        return res;
    }
}
vector<int> survivedRobotsHealths(vector<int>& positions, vector<int>& healths, string directions) {
    int n = positions.size();
    vector<int> order(n);
    for (int i = 0; i < n; i++) order[i] = i;
    sort(order.begin(), order.end(), [&](int a, int b) { return positions[a] < positions[b]; });
    vector<int> stack;
    for (int i : order) {
        if (directions[i] == 'R') {
            stack.push_back(i);
            continue;
        }
        while (!stack.empty() && healths[i] > 0) {
            int top = stack.back();
            if (healths[top] < healths[i]) {
                healths[top] = 0;
                healths[i] -= 1;
                stack.pop_back();
            } else if (healths[top] > healths[i]) {
                healths[i] = 0;
                healths[top] -= 1;
            } else {
                healths[i] = 0;
                healths[top] = 0;
                stack.pop_back();
            }
        }
    }
    vector<int> res;
    for (int h : healths) if (h > 0) res.push_back(h);
    return res;
}
Time: O(n log n) Space: O(n)