Maximum Currency Conversion Along a Simple Path
Reported by candidates from Rippling's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Rippling reported this one in September 2026, and the detail that matters is buried in the statement: a path can visit each currency at most once, even when a profitable cycle exists. That one rule turns a Bellman-Ford-looking problem into a small-graph search. With currencyCount capped at 8 and at most 20 queries, you're looking at a graph pattern where brute force is the intended answer. If you blank during the live OA, StealthCoder runs invisibly on your desktop as a safety net. But you can know this one cold before you even open the invite.
The problem
There are currencyCount currencies numbered from 0 through currencyCount - 1. Each directed edge edges[i] = [u, v] permits converting one unit of currency u into rates[i] units of currency v. For each query queries[j] = [source, target], start with amounts[j] units of the source currency and find the greatest amount of the target currency obtainable along one allowed path. A path may visit each currency at most once, including its source and target. Multiply the current amount by the rate of every traversed edge. Do not round intermediate amounts. Only listed directed conversions exist. Do not automatically add reciprocal edges. Stop when the target is reached. When source equals target, the only allowed path is the zero-edge path, returning the starting amount. If no allowed path reaches the target, return -1, even if the starting amount is zero. Return one floating-point amount per query, in query order. Queries are independent and do not consume or change rates. Profitable cycles may exist, but revisiting a currency is forbidden. Each returned value is accepted when its absolute error is at most 10^-6 * max(1, abs(expected)). Function maximumConversions(currencyCount: int, edges: int[][], rates: double[], queries: int[][], amounts: double[]) → double[] Examples Example 1 currencyCount = 3 edges = [[0,1],[1,2],[0,2]] rates = [2,3,4] queries = [[0,2],[2,0],[1,1]] amounts = [10,10,7] return = [60,-1,7] For 0 to 2, the indirect path 0 → 1 → 2 returns 10 * 2 * 3 = 60, beating the direct result 40. No path goes from 2 to 0. The self-query returns its starting amount 7. Example 2 currencyCount = 3 edges = [[0,1],[1,0],[1,2],[0,2]] rates = [2,2,3,1] queries = [[0,2],[0,0],[1,2]] amounts = [5,5,5] return = [30,5,15] The best path from 0 to 2 is 0 → 1 → 2, yielding 30. Repeating the profitable cycle 0 → 1 → 0 is forbidden. The self-query returns 5, and starting at 1 gives a best target amount of 15. Constraints 1 <= currencyCount <= 8. 0 <= edges.length <= currencyCount * (currencyCount - 1), and rates.length = edges.length. Every edge has distinct valid endpoints; each directed pair appears at most once. 0.1 <= rates[i] <= 10, with at most three decimal places. 0 <= queries.length <= 20, and amounts.length = queries.length. Every query contains two valid currency indices. 0 <= amounts[j] <= 1000, with at most three decimal places.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is the constraint, not the math. Eight nodes means you can run a DFS from the source that tracks a visited set, multiplies the running amount by each edge rate, and records the best value whenever it hits the target. Stop at the target, since the statement says to stop when reached. Handle source equals target by returning the starting amount immediately. Return -1 if no path reaches the target, even when the amount is zero, so track reachability separately from the value. The classic pitfall is reaching for Bellman-Ford or Floyd-Warshall. Those break on profitable cycles because revisits are forbidden. Another pitfall is treating the amount 0 as a sentinel for no path. Worst case is about 7! paths per query times 20 queries, which is trivial. If your DFS logic slips live, StealthCoder is the hedge that reads the problem and hands you a working version.
Drill it cold or hedge it with StealthCoder. Either way, don't walk into the OA hoping you remember the trick.
You can drill Maximum Currency Conversion Along a Simple Path 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 for the candidate who got the OA invite this morning and has 72 hours, not six months.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Rippling's OA.
Rippling reuses patterns across OAs. Made for the candidate who got the OA invite this morning and has 72 hours, not six months. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Maximum Currency Conversion Along a Simple Path FAQ
What's the trick in the Rippling currency conversion problem?+
Ignore shortest-path algorithms. Since currencyCount is at most 8 and revisiting is forbidden, run a DFS with a visited set from each query's source, multiply rates along the way, and keep the max amount found at the target.
Why not use Bellman-Ford or Floyd-Warshall?+
Profitable cycles make those approaches wrong here. They'd happily loop to inflate the amount, but the statement bans revisiting any currency. Simple-path constraints make the problem exhaustive search territory, which is fine at 8 nodes.
How do I handle the edge cases correctly?+
If source equals target, return the starting amount with the zero-edge path. If no path reaches the target, return -1, even when the starting amount is 0. Use a separate found flag instead of checking whether the best value is 0.
How hard is this really?+
Easy to medium. The code is a short backtracking DFS. The difficulty is noticing the constraints permit brute force and not overthinking it with graph algorithms. Floating-point tolerance is generous, so don't round intermediates.
How do I prepare in 48 hours?+
Write a backtracking DFS on a small directed graph with a visited array, then practice carrying a running product and a best value. Test on Example 2, where the 0 to 1 to 0 cycle must be rejected. Rewrite it from memory once.