I got pretty good time processing the list forward using binary recursion (or I guess ternary for part 2) at 0.15s for part2. At each step you can check if the sum or the product would be greater than the target and stop checking down that branch. However, it seems processing backwards allows for pruning the branches better. Glad I checked your video out. (code example is below in read more) let isEquationSatisfiableWithConcat (lhs, calibrations) = let rec loop runningTotal calibrations = match calibrations with | [] -> runningTotal = lhs | c :: remainingCalibrations -> let runningTotalProduct = runningTotal * c let runningTotalSum = runningTotal + c let runningTotalConcat = concat runningTotal c let productSatisfies = if runningTotalProduct > lhs then false else loop runningTotalProduct remainingCalibrations let sumSatisfies = if runningTotalSum > lhs || productSatisfies then false else loop runningTotalSum remainingCalibrations let concatSatisfies = if runningTotalConcat > lhs || productSatisfies || sumSatisfies then false else loop runningTotalConcat remainingCalibrations productSatisfies || sumSatisfies || concatSatisfies match calibrations with | c :: cs -> loop c cs | _ -> failwith "Expected at least one calibration component"