leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit 738535d11be07f7840c63e3b822995e2062dd565
parent d17da29c5340ec5d1e336b48ebf633dfbf6ad98c
Author: Jack Sangdahl <jack@pngu.org>
Date:   Tue, 31 Mar 2026 20:52:41 -0600

2751. robot collisions

Diffstat:
Mrobot_collisions.c | 130+++++++++++++++++++++++++++++++++++++++++++------------------------------------
Mrobot_collisions.py | 50+++++++++++++++++++++++++++-----------------------
2 files changed, 98 insertions(+), 82 deletions(-)

diff --git a/robot_collisions.c b/robot_collisions.c @@ -13,86 +13,98 @@ * further collisions can occur */ -int cmp(const void *a, const void *b) { - int *aa = *(int **)a, *bb = *(int **)b; - return aa[0] - bb[0]; +struct robot { + int position; + int health; + int index; + char direction; +}; + +int cmp_pos(const void *a, const void *b) { + return ((struct robot *)a)->position - ((struct robot *)b)->position; +} + +int cmp_idx(const void *a, const void *b) { + return ((struct robot *)a)->index - ((struct robot *)b)->index; } int *survivedRobotsHealths(int *positions, int positionsSize, int *healths, int healthsSize, char *directions, int *returnSize) { - int **record = (int **)malloc(sizeof(int *) * positionsSize); - int *stack = (int *)malloc(sizeof(int) * positionsSize), idx = -1; - int *ans = (int *)malloc(sizeof(int) * positionsSize); - *returnSize = 0; - for (int i = 0; i < positionsSize; i++) { - record[i] = (int *)malloc(sizeof(int) * 2); - record[i][0] = positions[i]; - record[i][1] = i; - if (directions[i] == 'L') - healths[i] *= 1; + int n = positionsSize, m = 0; + struct robot *robots = (struct robot *)malloc(n * sizeof(struct robot)); + struct robot *stack = (struct robot *)malloc(n * sizeof(struct robot)); + for (int i = 0; i < n; ++i) { + robots[i].position = positions[i]; + robots[i].health = healths[i]; + robots[i].direction = directions[i]; + robots[i].index = i; } - qsort(record, positionsSize, sizeof(int *), cmp); - for (int i = 0; i < positionsSize; i++) { - if (idx == -1) { - stack[++idx] = record[i][1]; - } else if (healths[record[i][1]] < 0 && healths[stack[idx]] > 0) { - if (healths[stack[idx]] == -1 * healths[record[i][1]]) { - healths[stack[idx]] = 0; - healths[record[i][1]] = 0; - idx--; - } else if (healths[stack[idx]] > -1 * healths[record[i][1]]) { - healths[record[i][1]] = 0; - healths[stack[idx]] -= 1; - } else { - while (idx != -1 && healths[stack[idx]] > 0 && - healths[stack[idx]] < -1 * healths[record[i][1]]) { - healths[stack[idx]] = 0; - idx--; - healths[record[i][1]] += 1; - } - if (idx == -1 || healths[stack[idx]] < 0) { - stack[++idx] = record[i][1]; - } else if (-1 * healths[record[i][1]] == healths[stack[idx]]) { - healths[stack[idx]] = 0; - healths[record[i][1]] = 0; - idx--; + qsort(robots, n, sizeof(struct robot), cmp_pos); + for (int i = 0; i < n; ++i) { + struct robot curr = robots[i]; + if (curr.direction == 'R' || !m || stack[m - 1].direction == 'L') { + stack[m++] = curr; + continue; + } + if (curr.direction == 'L') { + bool add = true; + while (m > 0 && stack[m - 1].direction == 'R' && add) { + int prev_health = stack[m - 1].health; + if (curr.health > prev_health) { + m--; + curr.health--; + } else if (curr.health < prev_health) { + stack[m - 1].health--; + add = false; } else { - healths[record[i][1]] = 0; - healths[stack[idx]] -= 1; + m--; + add = false; } } - } else { - stack[++idx] = record[i][1]; + if (add) + stack[m++] = curr; } } - for (int i = 0; i < positionsSize; i++) - free(record[i]); - free(record), free(stack); - for (int i = 0; i < positionsSize; i++) - if (healths[i]) - ans[(*returnSize)++] = abs(healths[i]); + qsort(stack, m, sizeof(struct robot), cmp_idx); + int *ans = (int *)malloc(m * sizeof(int)); + *returnSize = m; + for (int i = 0; i < m; ++i) + ans[i] = stack[i].health; + free(robots); + free(stack); return ans; } int main() { - int p1[] = {5, 4, 3, 2, 1}, h1[] = {2, 17, 9, 15, 10}, rs1; - int p2[] = {3, 5, 2, 6}, h2[] = {10, 10, 15, 12}, rs2; - int p3[] = {1, 2, 5, 6}, h3[] = {10, 10, 11, 11}, rs3; - char s1[] = "RRRRR", s2[] = "RLRL", s3[] = "RLRL"; + int p1[] = {5, 4, 3, 2, 1}, h1[] = {2, 17, 9, 15, 10}; + int r1[] = {2, 17, 9, 15, 10}, rs1; + int p2[] = {3, 5, 2, 6}, h2[] = {10, 10, 15, 12}; + int r2[] = {14}, rs2; + int p3[] = {1, 2, 5, 6}, h3[] = {10, 10, 11, 11}; + int r3[] = {}, rs3; + char *s1 = "RRRRR", *s2 = "RLRL", *s3 = "RLRL"; int *sbh1 = survivedRobotsHealths(p1, ARRAY_SIZE(p1), h1, ARRAY_SIZE(h1), s1, &rs1); int *sbh2 = survivedRobotsHealths(p2, ARRAY_SIZE(p2), h2, ARRAY_SIZE(h2), s2, &rs2); int *sbh3 = survivedRobotsHealths(p3, ARRAY_SIZE(p3), h3, ARRAY_SIZE(h3), s3, &rs3); - for (int i = 0; i < rs1; i++) - printf("%d ", sbh1[i]); // expect: 2,17,9,15,10 + for (int i = 0; i < rs1; i++) { + printf("%d ", sbh1[i]); + assert(r1[i] == sbh1[i]); + } printf("\n"); - for (int i = 0; i < rs2; i++) - printf("%d ", sbh2[i]); // expect: 14 + for (int i = 0; i < rs2; i++) { + printf("%d ", sbh2[i]); + assert(r2[i] == sbh2[i]); + } printf("\n"); - for (int i = 0; i < rs3; i++) - printf("%d ", sbh3[i]); // expect: null + for (int i = 0; i < rs3; i++) { + printf("%d ", sbh3[i]); + assert(r3[i] == sbh3[i]); + } printf("\n"); - free(sbh1), free(sbh2), free(sbh3); + free(sbh1); + free(sbh2); + free(sbh3); } diff --git a/robot_collisions.py b/robot_collisions.py @@ -1,4 +1,5 @@ # 2751. Robot Collisions +from typing import List """ there are 'n' 1 idxexed robots, each having a position on a line, health, and @@ -13,32 +14,35 @@ further collisions can occur """ -class Solution(object): - def survivedRobotsHealths(self, positions, healths, directions): - """ - :type positions: List[int] - :type healths: List[int] - :type directions: str - :rtype: List[int] - """ +class Solution: + def survivedRobotsHealths( + self, positions: List[int], healths: List[int], directions: str + ) -> List[int]: n = len(positions) - idx = sorted(range(n), key=positions.__getitem__) + robots = [[positions[i], healths[i], directions[i], i] for i in range(n)] + robots.sort() stack = [] - for i in idx: - if directions[i] == "R": - stack.append(i) + for robot in robots: + if robot[2] == "R" or not stack or stack[-1][2] == "L": + stack.append(robot) continue - while stack and healths[i] > 0: - if healths[stack[-1]] < healths[i]: - healths[stack.pop()] = 0 - healths[i] -= 1 - elif healths[stack[-1]] > healths[i]: - healths[stack[-1]] -= 1 - healths[i] = 0 - else: - healths[stack.pop()] = 0 - healths[i] = 0 - return [v for v in healths if v > 0] + if robot[2] == "L": + add = True + while stack and stack[-1][2] == "R" and add: + last_health = stack[-1][1] + if robot[1] > last_health: + stack.pop() + robot[1] -= 1 + elif robot[1] < last_health: + stack[-1][1] -= 1 + add = False + else: + stack.pop() + add = False + if add: + stack.append(robot) + + return [robot[1] for robot in sorted(stack, key=lambda robot: robot[3])] if __name__ == "__main__":