I have to write a program to find a rational number that has a property. I wrote the code to check the property, but now I don’t know how to check all rational numbers. I tried with
float rat;
for (int i=1 ; i ; ++i) {
for (int j=1 ; j ; ++j) {
rat = (float)i/(float)j;
if goodRat(rat) then return rat;
}
}
but it never ends! And it misses too many. So then I tried this
float rat;
while {
int i = random(1000) + 1;
int j = random(1000) + 1;
rat = (float)i/(float)j;
if goodRat(rat)
return rat;
}
but this works only sometimes. How can I solve this?
The rational numbers are countable, which means that they can be put in one-to-one correspondence with the integers. If you do that, then you’ll have your solution.
Instead of giving a one-to-one correspondence, an easier way to walk through the rationals is the following.
Construct an (countably) infinite by (countably) infinite matrix
Qso thatQ_(i,j) = i/jwhereiandjrange from1toinfinity. The matrix looks like this:Of course, there are many repeats (the entire diagonal is 1!), but I’m going for simplicity over speed.
What you’re trying to do is walk down the columns, which are infinite, so you’ll miss lots of numbers. Instead, you should walk along the anti-diagonals, which are finite. That is, take the elements in the following order
So you’ll get
1, 2/1, 1/2, 3/1, 2/2, 1/3, 4/1, 3/2, 2/3, 1/4, .... Moreover, you know that you will encounterr/sat step(r+s)(r+s-1)/2 + s, so any given rational number will be encountered in finite time.One way to code this is to let
ibe the row index (outerforloop) and letjbe the column index (innerforloop). Theniwill range from1toinfinity, butjwill only range from1toi.If your
goodRatfunction takes a fair amount of time, then you can speed this up by first testing thatiandjare coprime, and if not skip them.