Maximize coins with tokens moving by +3
Company: Google
Role: Software Engineer
Category: Coding & Algorithms
Difficulty: easy
Interview Round: Take-home Project
You are given a 1D board represented by a string `s` of length `n`. Each character is one of:
- `'.'` — an empty cell
- `'C'` — a cell containing exactly one coin
- `'T'` — a cell containing one of the player's tokens (there may be several tokens)
The player controls all tokens. Movement and scoring work as follows:
- A token may be moved any number of times, in any order.
- A single move sends a token **exactly 3 cells to the right**: from index `i` to index `i + 3`. No other distance is allowed, and tokens may never move left.
- A move is **invalid** if the destination cell is currently occupied by another token. A move that would land past the end of the board is also invalid (tokens never leave the board).
- When a token **lands** on a cell containing an as-yet-uncollected coin, that coin is collected and then disappears. Each coin is collected at most once.
- Only the **landing** cell counts. Coins on cells a token passes "over" mid-flight are **not** collected — but note a single move advances 3 cells at once, so a token does not actually visit the two cells in between.
**Task:** Return the **maximum number of coins** the player can collect over any optimal sequence of moves.
```hint Where to start
A token at index $i$ can only ever sit on indices $i, i+3, i+6, \dots$ — every reachable cell has the **same index modulo 3**. What does that imply about which tokens and coins can possibly interact?
```
```hint Decompose
Partition the board by index $\bmod\ 3$ into three independent sub-boards. Solve each one in isolation and sum the results, because a token can never change its residue class or reach a cell in another class.
```
```hint Within one residue class
Collapse a residue class into a chain (its cells in left-to-right order). In the chain, "advance by one step" right-only. Because tokens move right-only and can't share a cell, they can never cross — their left-to-right order is fixed. What is the largest set of coins they can collectively land on?
```
### Constraints & Assumptions
- $1 \le n \le 100$.
- Each cell is exactly one of `'.'`, `'C'`, `'T'`; a coin and a token never start on the same cell, so no coin is "pre-collected."
- Tokens are interchangeable except for the rule that two tokens cannot occupy the same cell at the same time.
- The board is static apart from token moves; no new coins or tokens appear.
### Clarifying Questions to Ask
- Can two tokens occupy the same cell, even momentarily? (No — that makes the move invalid.)
- Is the order of moves across tokens free, or must each token finish before the next starts? (Moves may be freely interleaved.)
- Are coins consumed permanently once landed on, or can they regenerate? (Collected once, then gone.)
- Does a coin sitting under the cell a token *jumps over* get collected? (No — only the landing cell.)
- Can a token start on a coin? (No — input format guarantees one symbol per cell.)
### What a Strong Answer Covers
- **The mod-3 insight:** recognizing that a token's reachable cells share a residue class, so the board splits into three fully independent sub-problems whose answers sum.
- **Reduction within a class:** mapping each residue class to a left-to-right chain and arguing that right-only, non-crossing motion lets tokens collect every coin at or to the right of the **leftmost** token in that chain.
- **A correctness argument** that the collision constraint never blocks a reachable coin (e.g. a right-to-left serialization, or "the leftmost token alone could sweep the whole chain"), and that coins strictly left of every token are unreachable.
- **An $O(n)$ time, $O(1)$ space** implementation, plus edge cases: no tokens, no coins, multiple tokens per class, coins on both sides of a token, and small $n$.
- Awareness that naive framings (one global sweep ignoring mod 3, or a heavyweight matching/DP) are either wrong or unnecessary.
### Follow-up Questions
- How does the answer change if a move advanced by $k$ cells instead of 3? (The board splits into $k$ classes; everything else generalizes.)
- Suppose coins had **values** and you wanted to maximize total value rather than count — does the same greedy still hold?
- What if tokens could also move **left** by 3? How does reachability and the non-crossing argument change?
- If you additionally had to report *one* concrete optimal move sequence (not just the count), how would you construct it, and what is its length bound?
Quick Answer: This question evaluates proficiency in discrete optimization and state-space reasoning, emphasizing movement constraints, collision avoidance, modular-position effects from fixed-step moves (+3), and maximizing reward collection.
Part 1: Maximize Coins with +3 Token Moves
You are given a 1D board string s. Each character is '.', 'C', or 'T'. A token may move any number of times, but every move must advance it exactly 3 cells to the right. A move is invalid if it lands outside the board or on another token. When a token lands on an uncollected coin, that coin is collected. Return the maximum number of coins that can be collected.
Constraints
- 1 <= len(s) <= 100
- s[i] is one of '.', 'C', or 'T'
- A cell never contains both a token and a coin
Examples
Input: (".",)
Expected Output: 0
Explanation: There are no tokens and no coins.
Input: ("CCC",)
Expected Output: 0
Explanation: There are coins but no tokens, so nothing can be collected.
Input: ("T..C",)
Expected Output: 1
Explanation: The token at index 0 can move to index 3 and collect the coin.
Input: ("T.C",)
Expected Output: 0
Explanation: The coin is not in the same modulo-3 class as the token.
Input: ("C..T..C..T..C",)
Expected Output: 2
Explanation: In residue class 0, the coin at index 0 is left of all tokens, while coins at indices 6 and 12 are collectable.
Hints
- A token moving by +3 always stays in the same index modulo 3 class.
- Within one modulo class, only coins to the right of the leftmost token in that class can be collected.
Part 2: Maximize Coins with +k Token Moves
You are given a 1D board string s and an integer k. Each token may move any number of times, but every move must advance it exactly k cells to the right. A move is invalid if it lands outside the board or on another token. When a token lands on an uncollected coin, that coin is collected. Return the maximum number of coins that can be collected.
Constraints
- 1 <= len(s) <= 100000
- 1 <= k <= 1000000000
- s[i] is one of '.', 'C', or 'T'
- A cell never contains both a token and a coin
Examples
Input: ("T.C.C", 2)
Expected Output: 2
Explanation: The token at index 0 can land on indices 2 and 4.
Input: ("C.T.C", 2)
Expected Output: 1
Explanation: The coin at index 0 is left of the token, but the coin at index 4 is reachable.
Input: ("T.C", 5)
Expected Output: 0
Explanation: k is larger than the board, so no token can land on any new cell.
Input: ("CCC", 2)
Expected Output: 0
Explanation: There are no tokens.
Input: ("CCTC", 1)
Expected Output: 1
Explanation: With k = 1, all cells are in one class. Only the coin to the right of the token is reachable.
Hints
- A token moving by +k always stays in the same index modulo k class.
- For each residue class, only the first token matters for determining which coins are reachable.
Part 3: Maximize Total Coin Value with +3 Token Moves
You are given a 1D board string s and an array values of the same length. Each 'C' cell contains a coin with non-negative value values[i]. Values at non-coin cells are ignored. A token may move any number of times, and every move advances it exactly 3 cells to the right. A move is invalid if it lands outside the board or on another token. When a token lands on an uncollected coin, that coin's value is added to the score. Return the maximum total value that can be collected.
Constraints
- 1 <= len(s) <= 100000
- len(values) == len(s)
- s[i] is one of '.', 'C', or 'T'
- 0 <= values[i] <= 1000000000
- Coin values are non-negative
- A cell never contains both a token and a coin
Examples
Input: ("T..C..C", [0, 0, 0, 5, 0, 0, 7])
Expected Output: 12
Explanation: Both coins are in the token's modulo-3 class and to its right.
Input: ("C..T..C", [4, 0, 0, 0, 0, 0, 9])
Expected Output: 9
Explanation: The value-4 coin is left of the token and unreachable; the value-9 coin is reachable.
Input: ("CCC", [3, 1, 4])
Expected Output: 0
Explanation: There are no tokens.
Input: ("T.C", [0, 0, 100])
Expected Output: 0
Explanation: The coin is in a different modulo-3 class from the token.
Input: ("T..C", [0, 0, 0, 1000000000])
Expected Output: 1000000000
Explanation: The single reachable coin has a large value.
Hints
- Because all coin values are non-negative, every reachable coin should be collected.
- As in the count version, split the board into three independent modulo-3 classes.
Part 4: Maximize Coins When Tokens Can Move Left or Right by 3
You are given a 1D board string s. Each token may move any number of times. In one move, a token may move exactly 3 cells either left or right. A move is invalid if it lands outside the board or on another token. When a token lands on an uncollected coin, that coin is collected. Return the maximum number of coins that can be collected.
Constraints
- 1 <= len(s) <= 100000
- s[i] is one of '.', 'C', or 'T'
- A cell never contains both a token and a coin
Examples
Input: (".",)
Expected Output: 0
Explanation: Empty of both tokens and coins.
Input: ("C..T..C",)
Expected Output: 2
Explanation: The token can collect the coin to its left and the coin to its right.
Input: ("T.C",)
Expected Output: 0
Explanation: The coin is not in the same modulo-3 class as the token.
Input: ("C..T..C..C",)
Expected Output: 3
Explanation: All three coins are in residue class 0, which contains a token.
Input: ("CCC",)
Expected Output: 0
Explanation: There are no tokens, so no coin can be reached.
Hints
- Even with left moves, a token still cannot change its index modulo 3.
- In a modulo-3 class, if there is at least one token, every coin in that class can be collected.
Part 5: Construct a Canonical Optimal Move Sequence
You are given the original +3-only board string s. Return one concrete sequence of moves that collects the maximum possible number of coins. A move is represented as [from_index, to_index], and must always satisfy to_index = from_index + 3. To make the required output deterministic, return the canonical sequence defined as follows: process residue classes 0, then 1, then 2. Within one residue class, process the starting tokens from right to left. Move each processed token right until it is immediately left of the final position of the previously processed token in that residue class, or until it reaches the last cell of that residue class if it is the rightmost token. Optimal means maximum coins collected, not minimum number of moves. This construction always returns at most n^2 moves.
Constraints
- 1 <= len(s) <= 100
- s[i] is one of '.', 'C', or 'T'
- A cell never contains both a token and a coin
- The returned sequence length is guaranteed to be O(n^2)
Examples
Input: (".",)
Expected Output: []
Explanation: There are no tokens, so the canonical move sequence is empty.
Input: ("T..C",)
Expected Output: [[0, 3]]
Explanation: The token moves from index 0 to index 3 and collects the coin.
Input: ("C..T..C",)
Expected Output: [[3, 6]]
Explanation: The token cannot collect the left coin, but it moves right to collect the coin at index 6.
Input: ("T..C..T..C",)
Expected Output: [[6, 9], [0, 3], [3, 6]]
Explanation: The right token moves first, then the left token sweeps right.
Input: (".T..C..C",)
Expected Output: [[1, 4], [4, 7]]
Explanation: Only residue class 1 has a token; it moves through both coin cells.
Hints
- Handle each modulo-3 class independently.
- Moving tokens from right to left creates space for tokens on the left without collisions.