Problem Analysis
This problem has two layers. The outer layer is a small combinatorial search: I must consider every set of four distinct digits chosen from 1 to 9, of which there are C(9, 4) = 126. For each set I determine which positive integers are expressible, then measure the length of the unbroken run 1, 2, 3, ..., n. The set that maximises that run wins, and the answer is its digits written as a string.
The interesting layer is the inner enumeration. Given four numbers, I must explore every parenthesisation and every assignment of the four arithmetic operators to the gaps between them. The naive route is to enumerate all binary expression trees over four leaves and try each operator at each internal node - a fiddly counting exercise. The unlocking observation is that any arithmetic expression over a pool of k numbers can be built by repeatedly picking two numbers, combining them with one operation, and replacing both with the result. Each step shrinks the pool by one, so after k - 1 steps a single value remains. By iterating over every unordered pair and every applicable operation at each step, I visit every distinct expression tree exactly once - I never have to reason about tree shapes at all. Because subtraction and division are non-commutative, I consider both orderings: for a pair (a, b) I try the absolute difference |a - b| and both quotients a / b and b / a. The recursion is shallow (6 pairs, then 3, then 1), the input size is fixed at four, and the outer loop is just 126 iterations, so the whole program runs in effectively constant time. The only arithmetic subtlety is that division produces non-integers, so I carry all values as floating-point numbers and test for integrality only at the boundary.
Solution Approach
Recursive pool reduction (Python and C)
Both files implement the same algorithm. The core is a recursive routine that receives the current pool of values. If the pool holds a single element, that element is a reachable result and is returned. Otherwise the routine iterates over every unordered pair (i, j), removes those two elements to form a "rest" pool, and for each of the up to five operation results appends that result to the rest pool and recurses. The union of everything the recursive calls return is the full set of reachable values.
In Python (eval_all_operations) the pool is a tuple and the result is a set. The reduced pool is built with a comprehension that skips the two chosen indices, then I append each operation result and recurse. The guards if b > 0 and if a > 0 before the divisions avoid division by zero (a zero can arise from a subtraction) and also serve as light pruning. The caller solve loops over the 126 digit sets with four nested ranges enforcing a < b < c < d, filters the returned values for integers via x.is_integer(), then counts the consecutive run from 1 with a simple while length + 1 in results loop. I decorate the recursive function with functools.lru_cache: because the pool is an unordered multiset, the same intermediate state recurs across different call paths and different digit sets, and caching on the tuple of values lets me reuse that work.
The C version (eval_all) mirrors the algorithm without memoisation - the problem is small enough that plain recursion is fast. It uses a hand-rolled DoubleSet: a dynamically grown array of doubles with a linear-scan duplicate check before each insertion, plus an isfinite guard that discards any NaN or infinity. After collecting the reachable doubles for a digit set, the code marks each positive near-integer into a fixed boolean array found[2048] (rounding with floor(v + 0.5) and confirming with a 1e-9 tolerance), then scans forward from index 1 to measure the run. The outer loop structure matches the Python version exactly.