I'm trying to find the common factor(s) of three integers which have each been rounded up to the next multiple of 8:
- i = round(n * a)
- j = round(n * b)
- k = round(n * c)
I'm given i, j, and k and I'm trying to find n. The rounding for all three is always to the next multiple of 8.
I could probably handle the simultaneous equation or finding the factor(s) on my own, but I'm a programmer and not a mathematician and don't know how to handle the complication added with the rounding mathematically. (Stackoverflow said I should ask the question here though.)
Real-world example:
i = 33475329 * 8, a = 42 j = 21519854 * 8, b = 27 k = 18331728 * 8, c = 23
n = 6376253
First, I think we basically have to assume $a,b,c$ are coprime in order to find $n$. Otherwise, you run into the problem Ross Millikan pointed out where $n$ is ambiguous and depends on knowing the common factor between $a,b,c$. Thus, the rest of this solution is going to assume $a,b,c$ are coprime. For example, if the choice is between $(a,b,c)=(46, 18, 54)$ and $(a,b,c)=(23, 9, 27)$, we will choose the latter.
Honestly, I still think the brute force solution is the easiest way to do this. However, I have found a slightly faster solution, although it requires more precomputation. First, I will assume $n$ is very big, so the change from $na$ to $i$, which is just $na$ rounded up to the nearest multiple of $8$, is a very small percent change. For instance, in your example, $i$ is $267802632$ while $na$ is $267802626$, which is a percent change in about $.000002\%$, which is quite small indeed.
Therefore, because of these small percent changes, the ratios between $i,j,k$ are very similar to the ratios between $na,nb,nc$. For instance, in your example $\frac i j$ is $1.5555555813715094$ while $\frac{na}{nb}$ is $1.5555555555555556$, which are very close to each other. However, $\frac{na}{nb}$ simplifies to $\frac a b$, so we get: $$\frac i j\approx \frac a b$$ Now, we know the ratio between $a$ and $b$. However, how do we solve for $a$ and $b$ based off this ratio? Since $a,b\leq 53$, the easiest way to do this is to make an array of all possible ratios $\frac l m$ for $l,m\leq 53$ and do a binary search for $\frac i j$ to find what $a$ and $b$ should be.
Now, from here, finding $n$ is easy: $i\approx na$, so $n\approx \frac i a$. Since we know $n$ is an integer, we can just say $n=\lceil \frac i a \rceil$ and call it a day. Once we know $n$, finding $c$ is also easy: $k\approx nc$, so $c\approx \frac k n\rightarrow c=\lceil \frac k n\rceil$. Thus, we have found $n$, $a$, $b$, and $c$, so we are done.
There is one ambiguity to this, however: If the ratio between $a$ and $b$ has small numerator and denominator, like $\frac 3 4$, how do we know if the solution is $(a,b)=(3,4)$ or $(a,b)=(6,8)$? Now, because we want $a,b,c$ to be coprime, but this does not necessarily mean $a,b$ are coprime. For instance, in your example, $a,b,c$ are coprime, but $a,b$ has common factor of $3$. Therefore, when we find $n$ and $c$, we need to test that $i,j,k$ are indeed $na,nb,nc$ rounded up to the nearest integer and if they are not, we need to multiply $a,b$ by some common factor in order to test if that new common factor leads to a new value of $n$ and $c$ which works. Again, using your example, this means we will first test $(a,b)=(14,9)$, then $(a,b)=(28,18)$, then $(a,b)=(42,27)$ before finally getting the correct solution.
Using all of this analysis, we can construct the following solution:
Now, the pre-computation is about $53^2=2809$ operations, which is slower than brute force of $512$ operations. However, the actual
compute_nabcfunction only takes $\lceil \log_2(2809)\rceil=12$ comparisons for binary search and about $26\cdot 4=$ operations, at most, for testing the different possible values of $n,c$, so the actualcompute_nabcfunction is about $5$ times less operations than brute force. Thus, although it might not make an actual difference since brute force is still pretty fast, if you are OK with doing a lot of pre-computation and have to executecompute_nabcdozens or hundreds of times, it might be easier to use this approach than brute force.