FUNCTION:
IsReverseRun(). A "Reverse Run" number is an
integer
whose digits are all in consecutive, descending order, left to right,
such as 321, 98765, 54, etc. When an integer is passed to IsReverseRun(), the function checks out all of its argument's digits. If they are arranged as described above, TRUE (1) is returned, otherwise FALSE (0). It's up to you what kind of integer you pass to the function, as long as the function declaration has already taken this datatyping into account. See the table below for the parameter limits. 
Type

Exponent
of 2^{} 
Value

int  2^{30}  1073741824 
uint  2^{31}  2147483648 
int64  2^{61}  2305843009213693952 
uint64  2^{62}  4611686018427387904 
Declaring the function must be done like
this: declare IsReverseRun(r: int) (or whatever integer type you want). Here's the code: sub IsReverseRun(r) ' if r forms a reverse run, such as ' 765 or 654321 etc, returns TRUE (1) ' otherwise returns FALSE (0) if r < 10: 'not enough digits for a run return 1 endif def flag, LSD1, LSD2: int flag = 1 do LSD1 = r % 10: 'save current LSD r = r/10: 'chop off current LSD LSD2 = r % 10: 'get new LSD if LSD2  LSD1 <> 1: 'not descending flag = 0 endif until not flag  r < 10 return flag 
Overview:
Variable r
holds the number to be checked for consecutive, descending
orderliness. The
code
copies the LSD (Least Significant, or rightmost, Digit) into variable LSD1, then chops the LSD off r, so
that a new LSD exists on the
end of r (what used to be the
second last digit, in fact). The new LSD is saved in variable
LSD2. If the two digits are in consecutive, descending order, their difference will be exactly 1. A check is made that LSD2  LSD1 equals 1 is made. If the difference isn't exactly one, r wasn't in consecutive, descending order, so no further checks are made. The function quits, returning FALSE (0) to the calling routine. If the difference is exactly one, descending orderliness hasn't been disproved yet, so another round of checks as above is carried out, this time on the next available LSD. Each time these checks are carried out, r gets a bit shorter since its LSD is being chopped off every time. Eventually, if no failures in orderliness are detected, r will be reduced to zero length. When this happens, TRUE (1) is returned to the calling routine. Let's look at the variables before we begin on the code detail. r is the function's argument which has been submitted by the calling routine. It's asking the question "Are f's digits in consecutive, descending order?" and expects one of two replies: TRUE (1) or FALSE (0). IsReverseRun()'s job therefore is to determine f's consecutive, descending orderliness and respond accordingly. Variable flag is used to indicate r's orderliness. It's set to TRUE (1) to begin with, and will stay that way unless r is found not to be ordered, at which point it will be reset to FALSE (0). The code picks the change up and aborts further investigation, making the function work more efficiently. Variable LSD1 is used to hold r's current LSD (that is, the least significant, or rightmost, digit). In this function, r is repeatedly shortened by chopping off the rightmost digit. Everytime this happens, a new rightmost digit appears, and this is loaded into LSD2. So the contents of these variables change all the time. To make it simpler to follow a detailed code description, I've numbered the lines as shown below. 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 
if
r < 10: 'not
enough digits for a run return 1 endif def flag, LSD1, LSD2: int flag = 1 do LSD1 = r % 10: 'save current LSD r = r/10: 'chop off current LSD LSD2 = r % 10: 'get new LSD if LSD2  LSD1 <> 1: 'not descending flag = 0 endif until not flag  r < 10 return flag 
Now
for a linebyline exegesis of the code. 
1 
if r < 10. This is a preliminary check. If r is less than 10, it can't fail a run check because there are no other digits which could cause it to fail. So no further checks on r will be necessary. 
2 
return
1. If the code reaches
this line, it means that r
only has one digit. The convention here is that this is
considered to be a run, and TRUE (1) is returned to the calling
routine. 
3 
endif. Housekeeping  closes IFENDIF clause. 
4 
def flag, LSD1, LSD2: int. If the code gets this far, r has more than one digit, so a digitbydigit check on it will be made. This line defines the variables that will be used to make the checks. LSD1 will hold r's last LSD. After saving the last LSD, r's LSD is chopped off, so a new LSD appears, and this is stored in LSD2. Variable flag is used to indicate TRUE or FALSE status of consecutive, descending orderliness of r. 
5 
flag = 1. Variable flag is preloaded with the value 1. Thus, the assumption is made that, until evidence to the contrary is found, r's digits are in consecutive descending order. 
6 
do. Opens the main DO loop. 
7 
LSD1 = r % 10. We can paraphrase this
expression as "Divide r by 10
and save the remainder in variable LSD."
Such a division is called integer arithmetic. Example: Assume r is 12345. Dividing by 10 gives 1234 remainder 5. The 5 is saved in LSD1. So you can see that the effect is simply to find r's own LSD and save it in variable LSD1. Note two important things here. Firstly, only the remainder of the division is saved. Secondly, r itself isn't changed when this line is executed, because we didn't save anything into r itself, so whatever was there remains there. You could therefore more accurately paraphrase the line as "Find out what the remainder would be if r were to be divided by 10, and, without actually changing r, save that remainder in variable LSD1." 
8 
f = d/10. To paraphrase the expression,
"Divide variable r by 10 and
save the result in r itself, overwriting
the original contents." This line performs a neat operation. To explain it, let's assume that r has value 54321. Normally, dividing it by 10 would give 5432.1, but something else happens here. Remember that r was declared as an integer in the declaration? That means that it must remain an integer, no matter what we do to it. And an integer contains no decimal part. So the operation on this occasion gives r's new value as 4321  the 0.1 has been discarded. Thus, the operation in effect says "Chop off the rightmost digit of r." 
9 
LSD2 = r % 10. This is almost identical to the action in line 7 above, except for two things. Firstly r's LSD has been chopped off, so r % 10 will yield the new LSD, different to that stored in variable LSD1. Secondly, this new LSD is stored in a different variable, LSD2. 
10 
if
LSD2  LSD1 <> 1. Once again, a paraphrase can
help us understand this expression more clearly: "Is the value of LSD2 exactly 1 greater than that of
LSD1?". Why are we making this comparison? Assume r started with value 65421. After one execution of lines 7 to 9, LSD1 contains 1, LSD2 contains 2 and r now contains 6542. So the expression LSD2  LSD1 will yield 1. Thus, at the moment, consecutive descending orderliness is assumed. The next time around the DO loop things have changed, because lines 7 and 8 have been executed again. LSD1 now contains 2, LSD2 contains 4, and r now contains 654. So LSD2  LSD1 will yield 2. This proves that, although everything was ok the first time around the loop, it wan't the second time, and consecutive descending orderliness isn't maintained throughout the whole of r. 
11 
flag = 0. If the code reaches this line, it found two successive digits that weren't in consecutive descending order. It immediately sets flag to zero so that the code will be able to quit without wasting time on further unnecessary digit checks. 
12 
endif. Housekeeping  closes IFENDIF clause. 
13 
until
not flag  r < 10.
The code now reaches the end of the DO
loop. It needs to decide whether
to execute the loop again, or just move on to the next instruction. The line until not flag  r < 10 is the decisionmaker. It can be paraphrased as "execute the DO loop again unless either flag is FALSE (0) or the value of r is less than 10." The "until not flag" may appear confusing, but it's actually simple. The normal phrase is "until flag" and means "execute the DO loop until flag is set to TRUE (1)." So "until not flag" means the opposite: "execute the DO loop until flag is set to FALSE (0)." Clearly, if flag is FALSE (0), a nonordered digit has been found, so there's no need to look at any more of r's digits. The function can return the FALSE (0) immediately. And the alternative for exiting the DO loop is if r is less than 10. Remember, r's length is decremented by 1 each time the DO loop executes without finding a nonordered digit. So, eventually, if all the digits are ordered, r will be shortened to just 1 digit  obviously having value less than 10. Since there is no other digit to its left to compare to, the necessary digit checks are complete and the program can quit. 
14 
return flag. One of those two alternatives will cause the last line of code to be executed: return flag. The calling routine will thus receive either a FALSE (0) or TRUE (1), corresponding to the consecutive, descending orderliness of the digits of argument r. 
This code was originally written with a
different algorithm, using strings. This version runs
faster. 
MAIN MENU
HOW DOES IT WORK?
Site design/maintenance: Dave Ellis Email me!
Last Updated: February 4, 2010.