THE PUZZLET PAGE


How_Does_It_Work



FUNCTION:  AllDigitsEven(). When an integer is passed to function AllDigitsEven(), the function checks out  all of its argument's digits. If they are exclusively even, 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 data-typing into account. See the table below for the parameter limits.

Type

Exponent of 2
Value

int 230 1073741824
uint 231 2147483648
int64 261 2305843009213693952
uint64 262 4611686018427387904

Declaring the function must be done like this:

declare AllDigitsEven(a: int) (or whatever integer type you want).

Here's the code:

sub AllDigitsEven(a)
' if every digit contained in
' argument a is even returns
' TRUE (-1), otherwise returns
' FALSE (0)
def flag: int
flag = -1: 'set to TRUE
do
    if a % 2 = 0: 'is "a" even?
        a = a/10: 'yes - chop off LSD
    else
        flag = 0: 'no - set to FALSE
    endif
until not flag | a = 0
return flag: 'return TRUE or FALSE

Overview:  Argument a holds the number to be checked for all-digit even-ness.  The code checks that the LSD (Least Significant, or rightmost, Digit) is even (that is, it can be divided by 2)

If it can, that digit is chopped off by the simple expedient of dividing a by 10 and discarding any remainder. The process is then repeated.

If the LSD wasn't even, there's no point in making
further checks on the rest of the digits.  The function quits, returning FALSE (0) to the calling routine.
 

Eventually, if no failures in digit even-ness are detected, a will be reduced to zero length.  When this happens, TRUE (-1) is returned to the calling routine.


Variable flag is used to indicate a's all-digit even-ness. It's set to TRUE (-1) to begin with, and will stay that way unless a is found not to be even, 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.

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

flag = -1: 'set to TRUE
do
    if a % 2 = 0: 'is "a" even?
        a = a/10: 'yes - chop off LSD
    else
        flag = 0: 'no - set to FALSE
    endif
until not flag | a = 0
return flag: 'return TRUE or FALSE

Now for a line-by-line exegesis of the code.

1

flag = -1.  Variable flag is preloaded with the value -1.  Thus, the assumption is made that, until evidence to the contrary is found, a's digits are all even.

2

do.  Opens the main DO loop.

3

if a % 2 = 0.  In plain English, this line asks "Is the result of dividing variable a by 2 equal to zero?"  Since this is the characteristic of all even numbers, an even simpler paraphrase is "Is variable a an even number?"

4

a = a/10.  This line will only be executed if line 3 returns TRUE, that is, a's LSD turns out to be even. To paraphrase the expression a = a/10, we can say "Divide variable a by 10 and save the result in a  itself, over-writing the original contents." 

This line performs a neat operation.  To explain it, let's assume that a has value 12345.  Normally, dividing it by 10 would give 1234.5, but something else happens here.

Remember that a 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 a's new value as 1234 - the 0.5 has been discarded.

Thus, the operation in effect says "Chop off the rightmost digit of a."

5

else.  Provides an alternative action in the event a's LSD is an odd number.

6

flag = 0.  If the code reaches this line, it found a digit that weren't even. It immediately sets flag to zero so that the code will be able to quit without wasting time on further unnecessary digit checks.

7

endif.  Housekeeping - closes IF-ENDIF clause.

8

until not flag | a = 0The 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 | a < 10 is the decision-maker.  It can be paraphrased as "execute the DO loop again unless either flag is FALSE (0) or the value of a is zero."

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), an odd digit has been found, so there's no need to look at any more of a's digits. The function can return the FALSE (0) immediately.

And the alternative for exiting the DO loop is if a has been reduced to zero. Remember, a's length is decremented by 1 each time the DO loop executes without finding an odd digit. So, eventually, if all the digits are even, a will be reduced to zero. Since there are no other digits left, the necessary digit checks are complete and the program can quit.

9


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 all-digit even-ness of the digits of argument a.


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 E-mail me!
Last Updated: February 3rd, 2010.