There're few other things you can do to possibly speed up the second code snippet, by reducing dimensionality:<p>1) recognize q1 * q2 = 2^p1 * 2^p2 = 2^(p1 + p2), so instead of iterating over q1 then q2, iterate over p = p1 + p2<p>2) memorize some of the combinations; e.g. if you iterate over p, r1 & r2, then you know that all you're trying to find is two integers f1 & f2 that are equal to output * r1 * r2 * 2^p / input; so before you start solving the problem, calculate table T:<p><pre><code> for (int f1 = 1; f1 <= 256; ++f1)
for (int f2 = 1; f2 <= 256; ++f2)
T[f1 * f2] = f1
</code></pre>
now you can check whether integer pair (f1,f2) exists, you can just check whether T[output * r1 * f2 * 2^p / input] is non-zero.
Also, output * r1 * r2 * 2^p has to be divisible by input, so after you iterate over p & r1, you can iterate only over r2's being multiples of input / gcd(input, output * r1 * 2^p)<p>There could be possibly some more tricks found.