◀ THE GRIND — GREEDY

Dota2 Senate

MEDIUM✓ CHIP-TIMEDLC #649 — FULL STATEMENT ↗

The drill: Senators sit in a fixed circle and vote in turn order: on a senator's turn, if a rival party still has anyone standing, they ban the nearest rival ahead of them. Play loops around until one party has no senators left — name the winner.

THE BRIEFING — THE FULL DRILL, IN MY OWN WORDS

Senators from two parties — R and D — sit around a circle in a fixed order and take turns going around it, looping back to the start as many times as needed. Each character of the input string is one senator's party.

On a senator's turn, if the opposing party still has at least one senator left standing, that senator bans the nearest still-standing rival that comes after them in turn order — banned senators skip every future turn.

Play keeps looping around the circle until one party has no senators left standing at all. The task is naming which party ends up winning.

EX 01
senate = "RRDDD"
"Radiant"
R STARTS WITH A HEAD COUNT DEFICIT BUT WINS THE QUEUE RACE
EX 02
senate = "DDRRR"
"Dire"
D STARTS BEHIND BUT OUTLASTS R
EX 03
senate = "DR"
"Dire"
MINIMUM SIZE, D ACTS FIRST
THE HINTS — TAKE ONLY WHAT YOU NEED
HINT 1 THE NUDGE

The senator whose turn is 'next' overall is always the one whose last action is farthest in the past. Simulating string-position order across repeated sweeps of the circle is really just asking: who acted least recently?

HINT 2 THE STRUCTURE

Two separate turn-orders — one for R, one for D — capture exactly that. Compare the next R's turn number to the next D's turn number; whichever is EARLIER survives this duel and bans the other.

HINT 3 ONE STEP FROM THE ANSWER

Use two queues of original indices. Pop the front of each; the smaller index acts first and bans the other, then re-enters its own queue at index + n — its next turn, one full lap later. Whichever queue empties first loses.

COACH'S BOARD — THE PATTERN, STEP BY STEP
THE TURN QUEUEPATTERN · GREEDY — TWO QUEUESsenate = "RRDDD"
R
R
D
D
D
QUEUES — R / D (turn tickets)
R queue[0, 1]
D queue[2, 3, 4]
STEP 1

Senate RRDDD. Two turn-order queues: Radiant [0,1], Dire [2,3,4] — whichever front ticket is earlier acts next.

STEP 1 / 7 · ← → WORK TOO
THE SPLITS — TWO PACES, TWO LANGUAGES
grind/dota2-senate.pyRACE PACE
LANG ▸
PACE ▸
class Solution:
    def predictPartyVictory(self, senate: str) -> str:
        n = len(senate)
        radiant = collections.deque(i for i, c in enumerate(senate) if c == "R")
        dire = collections.deque(i for i, c in enumerate(senate) if c == "D")
        while radiant and dire:
            r, d = radiant.popleft(), dire.popleft()
            if r < d:
                radiant.append(r + n)
            else:
                dire.append(d + n)
        return "Radiant" if radiant else "Dire"
TIME O(N)SPACE O(N)PYTHON · RACE PACE · 12 LN

✓ CHIP-TIMED — ALL 4 SOLUTIONS RAN GREEN AGAINST SELF-AUTHORED CASES IN CI · JDK 21 · CPYTHON 3.12 · NOTHING PUBLISHES RED