Keep track of the size of each of the subgroups and when there's one that is ambiguous place it in the subgroup with the lowest current count.
If you want to go for even closer accuracy, place all singletons in their respective sub-groups (all non-ambiguous values). And then do a second pass for all that fit in 2 sub-groups, and a third for all that fit in 3 sub-groups, at most this would be an O(n^2) operation anyway, with the previous one running in O(n*log(n)) roughly. Just based off of what I'm seeing in my head.
If you split the main array into 3 sub-arrays with 1, 2, and 3 group values being in their own respective arrays (if space isn't an issue) you could perform the second in nearly O(n*log(n)).
Disclaimer: This answer does not answer the question that completely. But it's too long for a comment.
NP-hard? I believe, this problem could be NP-hard.
Consider a special case of the Knapsack problem:
Given a set of positive integers and a positive integer b, does there exist a subset of the set such that the sum of all integers in that subset equals b?
This sounds somewhat similar to our Countdown problem, and it seems to be much simpler. However, Knapsack (and this special case of Knapsack) is NP-hard (and NP-complete, of course).
I did not manage to use this for a proof that Countdown is NP-hard. I could not get rid of the division. Consider we have a thousand 2, and b = 7. This will never be solvable with Knapsack, but always (?) with Countdown, at least in all the ways I tried to transfer the problem.
Now, if Countdown really was NP-hard, we could deduce that there with very high probability is no algorithm that is significantly more efficient than brute-force trying all possibilities. (And if we should find such an algorithm, we will become very famous.)
No, I don't think there must be an efficient algorithm.
Heuristics. The Youtube video linked in the question has a nice example: The contestant found an exact answer 952 = ((100 + 6) * 3 * 75 - 50) / 25. That is completely against my intuition, I would never have tried it that way in the first time: Produce a very large number, then divide it and yield the result.
On the other, we humans feel that we do not need to try (arbitrary example) 50 * 75 * 100 / 2 / 3 / 7 to reach a three-digit-number. But computers do not feel anything, they simple calculate.
After all, if we implemented some heuristics, and this heuristics does not find an exact solution, we still will have to try all other solutions to make sure there really is none.
What the contestant in the Youtube video does is, I think, to very quickly check a large number of possibilities and to quickly discard those that will not (or likely will not) give a solution.
Conclusion. When implementing an algorithm, one could take care to strip equal calculations such as a / b / c = a / (b * c), but I think this is quite hard to do and I do not know whether this improves the runtime significantly.
Computers of course are faster than humans in checking a large number of possibilities. And nowadays, even smartphones are so fast they can solve this problem, I think, within a second by simply trying all possibilities. (I did not test this.) There are only six numbers, it would be different if there were e.g. 60 of them.
Best Answer
Factorize logic, return early
As suggested in comments, it would be sufficient to simply wrap your logic in a function and exit early with
return
's in order to simplify things a lot. Also, you could factorize a bit of functionnality by delegating tests to another function. More concretely:This is shorter than my previous attempt:
The above is a little more verbose, but is easy to read IMHO and does not recompute comparisons multiple times.
Visual confirmation
In your answer you say:
... also, in your question, you say:
I may not understand what you are trying to achieve: do you want to copy-paste the pattern everywhere you need it? With a function like the one above, you capture the pattern once, and you check once for all that all comparisons use
a
,b
andc
as required. Then, you don't need to worry anymore when you call the function. Of course, maybe in practice your problem is a little more complex than the one you described: if so, please add some details if possible.