Winning Draws for a Mahjong Hand
Reported by candidates from Zip's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Zip reported this one in September 2025, and it looks like a Mahjong puzzle but it's really a tiny brute force with a recursive check. You have 13 tiles, ranks 1 through 9, and you need every rank that completes a winning 14-tile hand. That's nine candidate draws, each tested with a backtracking partition check. If you're taking this OA soon, stop thinking about game rules and think counts array plus recursion. StealthCoder sits invisibly as a safety net on the live OA if your recursion falls apart mid-test, but the logic here is small enough to own beforehand.
The problem
You have 13 Mahjong tiles. Each tile has a rank from 1 through 9. A complete 14-tile hand is winning when all tiles can be divided into exactly four three-tile groups and one two-tile pair. A group is either three equal ranks or three consecutive ranks; the pair is two equal ranks. For every rank from 1 through 9, consider drawing one more tile of that rank. Return all ranks whose draw makes the hand winning, in increasing order. A physical deck contains at most four tiles of each rank, so a rank already appearing four times cannot be drawn. Groups and the pair must use each of the 14 tiles exactly once. Function winningDraws(tiles: int[]) → int[] Examples Example 1 tiles = [1,1,1,2,2,2,3,3,3,4,4,4,5] return = [2,3,4,5,6] Drawing 5 gives the obvious partition 111, 222, 333, 444, and pair 55. Other listed draws permit a different split using consecutive groups. Example 2 tiles = [1,2,2,3,4,4,4,6,7,7,9,9,9] return = [] No available fourteenth rank permits a partition into four groups and a pair. Constraints tiles.length == 13. 1 <= tiles[i] <= 9. Each rank appears at most four times in the given hand.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Build a count array of size 10. For each rank 1 through 9, skip it if the count is already 4. Otherwise add one, then test whether the 14 tiles split into four groups and one pair. Try every rank as the pair: subtract two, then run a recursive check on the rest. The check finds the lowest rank with a nonzero count. It must either form a triplet (count at least 3) or a run of r, r+1, r+2 (all nonzero). Remove it, recurse, restore on failure. Always working from the lowest rank keeps it deterministic and tiny. The common pitfall is forgetting the four-copy cap, or trying triplets only and missing runs like 234 versus 222. Another is mutating the counts and not undoing them. Search space is trivial, so no memoization needed. If you blank under pressure, StealthCoder can hand you the working recursion on the live OA, but the lowest-rank-first rule is the whole trick.
Memorize the pattern. If you can't, run StealthCoder. The proctor sees the IDE. They don't see what's behind it.
You can drill Winning Draws for a Mahjong Hand cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Zip's OA.
Zip reuses patterns across OAs. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Winning Draws for a Mahjong Hand FAQ
What's the actual trick in Winning Draws for a Mahjong Hand?+
Try each rank 1 to 9 as the extra tile, then check if the 14 tiles partition into four groups and a pair. Use a count array and always resolve the lowest remaining rank first, either as a triplet or a run. That forces one clean branching path.
How hard is this problem really?+
Medium at most. There's no clever optimization, just careful backtracking. The input is only 13 tiles with ranks to 9, so brute force is instant. Most failures come from sloppy state restoration or missing the four-copy limit, not from complexity.
Do I need to try every rank as the pair?+
Yes. Loop over every rank with count at least 2, remove two, and check whether the remaining 12 tiles form four groups. Skipping this misses hands where the pair choice decides whether runs or triplets work out.
What edge case trips people up most?+
The cap of four tiles per rank. If your hand already has four of a rank, drawing it is illegal even if it would complete the hand. Example 2 returns an empty list, so also make sure you return [] cleanly.
How do I prepare for this in 48 hours?+
Write the recursive group check from scratch twice using a count array. Then wrap it in the loop over draws and pair choices. Test it against both examples. Practice the undo step after each failed branch, since that's where bugs hide.