LeetCode 3847 - Find the Score Difference in a Game

This problem describes a game played over a sequence of rounds. The array nums represents the points awarded in each game, where nums[i] is the number of points available during game i. There are exactly two players. At the beginning: - The first player is active.

LeetCode Problem 3847

Difficulty: 🟡 Medium
Topics: Array, Simulation

Solution

LeetCode 3847 - Find the Score Difference in a Game

Problem Understanding

This problem describes a game played over a sequence of rounds. The array nums represents the points awarded in each game, where nums[i] is the number of points available during game i.

There are exactly two players. At the beginning:

  • The first player is active.
  • The second player is inactive.

For every game, two possible role swaps may occur before points are awarded:

  1. If nums[i] is odd, the active and inactive players swap roles.
  2. If the current game is every 6th game, meaning indices 5, 11, 17, ..., the active and inactive players swap roles again.

After all required swaps for that game have been performed, the active player receives nums[i] points.

The goal is to compute:

first player's total score - second player's total score

The important detail is that swaps happen before points are awarded. Multiple swaps can occur during the same game. If both swap conditions trigger, the roles are swapped twice, which effectively returns them to their original state.

The constraints are small:

  • 1 <= nums.length <= 1000
  • 1 <= nums[i] <= 1000

Since there are at most 1000 games, we can easily simulate the process directly. There is no need for advanced optimization techniques or complex data structures.

Several edge cases are worth noting:

  • A single-element array.
  • Arrays where every value is odd, causing a swap before every game.
  • Arrays where game indices 5, 11, 17, ... introduce additional swaps.
  • Games where both swap rules apply simultaneously, resulting in two swaps and therefore no net change.
  • Very large point values, although the constraints keep totals well within standard integer limits.

Approaches

Brute Force Approach

A straightforward approach is to literally simulate the game exactly as described.

For each game:

  1. Check whether the score is odd and perform a swap if necessary.
  2. Check whether the game index is a multiple of 6 minus 1 (5, 11, 17, ...) and perform another swap if necessary.
  3. Award the points to the currently active player.

At the end, compute the difference between the two accumulated scores.

This approach is correct because it directly follows the rules of the game in the exact order specified.

Given that there are only up to 1000 games, this simulation is already fast enough.

Optimal Approach

The key observation is that the game state can be represented by a single variable indicating which player is currently active.

Since each game only requires constant-time work:

  • At most two swaps.
  • One score update.

We can process the array in a single pass.

No additional data structures are needed because the entire state of the game is captured by:

  • First player's score.
  • Second player's score.
  • Current active player.

This yields an optimal linear-time simulation.

Approach Comparison

Approach Time Complexity Space Complexity Notes
Brute Force O(n) O(1) Direct simulation of every rule
Optimal O(n) O(1) Single-pass simulation using active-player state

In this problem, the brute-force simulation is already optimal because every game must be examined at least once.

Algorithm Walkthrough

  1. Initialize two score variables, one for each player.
  2. Maintain a boolean variable indicating whether the first player is currently active.
  3. Iterate through the array from left to right.
  4. For the current game, check whether nums[i] is odd.

If it is odd, toggle the active player because the rules require a role swap before the game is played. 5. Check whether the current index is one of 5, 11, 17, ....

This can be tested with:

(i + 1) % 6 == 0

If true, toggle the active player again. 6. After all required swaps have been processed, award nums[i] points to the active player. 7. Continue until every game has been processed. 8. Return:

first_score - second_score

Why it works

The algorithm maintains the invariant that the active-player variable always reflects the correct active player immediately before points are awarded for the current game. Each rule is applied in the required order, and every point value is added to exactly the player who should receive it. Since the simulation exactly mirrors the problem statement, the final scores are correct, and their difference is the required answer.

Python Solution

from typing import List

class Solution:
    def scoreDifference(self, nums: List[int]) -> int:
        first_score = 0
        second_score = 0

        first_active = True

        for i, points in enumerate(nums):
            if points % 2 == 1:
                first_active = not first_active

            if (i + 1) % 6 == 0:
                first_active = not first_active

            if first_active:
                first_score += points
            else:
                second_score += points

        return first_score - second_score

The implementation follows the simulation directly.

The variables first_score and second_score store the accumulated points for each player. The boolean first_active tracks whether the first player is currently active.

For every game, the odd-value rule is processed first. Next, the sixth-game rule is applied. After all swaps are completed, the points are awarded to the active player. Once all games have been processed, the score difference is returned.

Go Solution

func scoreDifference(nums []int) int {
    firstScore := 0
    secondScore := 0

    firstActive := true

    for i, points := range nums {
        if points%2 == 1 {
            firstActive = !firstActive
        }

        if (i+1)%6 == 0 {
            firstActive = !firstActive
        }

        if firstActive {
            firstScore += points
        } else {
            secondScore += points
        }
    }

    return firstScore - secondScore
}

The Go implementation mirrors the Python solution almost exactly.

A boolean variable tracks whether the first player is active. Since the maximum possible total score is only 1000 * 1000 = 1,000,000, standard Go int values are more than sufficient and overflow is not a concern under the given constraints.

Worked Examples

Example 1

Input:

nums = [1, 2, 3]
Game Points Odd Swap 6th Game Swap Active Player After Swaps First Score Second Score
0 1 Yes No Second 0 1
1 2 No No Second 0 3
2 3 Yes No First 3 3

Final answer:

3 - 3 = 0

Example 2

Input:

nums = [2, 4, 2, 1, 2, 1]
Game Points Odd Swap 6th Game Swap Active Player After Swaps First Score Second Score
0 2 No No First 2 0
1 4 No No First 6 0
2 2 No No First 8 0
3 1 Yes No Second 8 1
4 2 No No Second 8 3
5 1 Yes Yes Second 8 4

Final answer:

8 - 4 = 4

Example 3

Input:

nums = [1]
Game Points Odd Swap 6th Game Swap Active Player After Swaps First Score Second Score
0 1 Yes No Second 0 1

Final answer:

0 - 1 = -1

Complexity Analysis

Measure Complexity Explanation
Time O(n) Each game is processed exactly once
Space O(1) Only a few variables are maintained regardless of input size

The algorithm performs a constant amount of work for every element in the array. No auxiliary data structures proportional to the input size are used, so the space complexity remains constant.

Test Cases

from typing import List

class Solution:
    def scoreDifference(self, nums: List[int]) -> int:
        first_score = 0
        second_score = 0
        first_active = True

        for i, points in enumerate(nums):
            if points % 2 == 1:
                first_active = not first_active

            if (i + 1) % 6 == 0:
                first_active = not first_active

            if first_active:
                first_score += points
            else:
                second_score += points

        return first_score - second_score

sol = Solution()

assert sol.scoreDifference([1, 2, 3]) == 0      # Example 1
assert sol.scoreDifference([2, 4, 2, 1, 2, 1]) == 4  # Example 2
assert sol.scoreDifference([1]) == -1           # Example 3

assert sol.scoreDifference([2]) == 2            # Single even value
assert sol.scoreDifference([1, 1]) == 0         # Consecutive odd swaps
assert sol.scoreDifference([2, 2, 2, 2, 2, 2]) == 10  # Sixth-game swap only
assert sol.scoreDifference([1, 1, 1, 1, 1, 1]) == 0   # Frequent swaps
assert sol.scoreDifference([5, 5, 5, 5, 5, 5]) == 0   # Double swap on index 5
assert sol.scoreDifference([1000] * 1000) == 4000     # Large input stress case
assert sol.scoreDifference([1, 2, 1, 2, 1, 2, 1, 2]) == 0  # Alternating behavior

Test Summary

Test Why
[1,2,3] Validates example 1
[2,4,2,1,2,1] Validates example 2
[1] Validates example 3
[2] Single game with no swap
[1,1] Consecutive odd-triggered swaps
[2,2,2,2,2,2] Tests sixth-game swap behavior
[1,1,1,1,1,1] Odd swaps on every game
[5,5,5,5,5,5] Double swap on the sixth game
[1000] * 1000 Maximum-size stress test
[1,2,1,2,1,2,1,2] Mixed swap scenarios

Edge Cases

Single Game

When the array contains only one element, the answer depends entirely on whether that value is odd or even. An odd value causes an immediate swap before scoring, while an even value leaves the first player active. The implementation naturally handles this because the loop processes exactly one game and applies the rules in order.

Both Swap Rules Trigger Simultaneously

At indices 5, 11, 17, ..., an odd value causes two consecutive swaps. A common bug is to treat these conditions as mutually exclusive or forget that both must be applied. The implementation executes both checks independently, so two swaps correctly cancel each other out.

All Values Are Odd

If every score is odd, the active player changes before every game. This produces frequent role changes and can expose errors in active-player tracking. Because the algorithm stores the active state explicitly and toggles it whenever an odd value appears, it correctly handles arbitrarily long sequences of odd numbers.

All Values Are Even

When every value is even, the only role changes occur on every sixth game. This verifies that the periodic swap rule functions correctly even when the odd-value rule never activates. The implementation checks the sixth-game condition independently on every iteration, ensuring correct behavior.

Maximum Input Size

With 1000 games and values up to 1000, the total score can reach one million. The algorithm still runs in linear time and uses constant space. Both Python integers and Go integers comfortably handle these values without overflow concerns under the given constraints.