THE PUZZLET PAGE


How_Does_It_Work


FUNCTION:  AllCharsDiff().  Pass a string to this function and it will inspect each character in the string. If they're all different (such as "912", or "2xY8", "abcdef", etc) the function returns TRUE (-1), otherwise it returns FALSE (0). So "stoop" would return FALSE because the "o" character is repeated.

This version uses IBasic's built-in function instr().  It's about twice as fast as my older versions.  The suggestion is due to Claudio Baiocchi.


Declaring the function must be done like this:

declare AllCharsDiff(a$: string).

Here's the code:


def flag, L, pntr: int
L = len(a$)
flag = -1
if L > 1
    pntr = 1
    do
        if instr(pntr + 1, a$, mid$(a$, pntr, 1)) > pntr
            flag = 0
      endif
        pntr = pntr + 1
    until not flag | pntr > L
endif
return flag

In the description of the code which follows, I have applied line numbers to make it easier to follow. Here they are:

1
2
3
4
5
6
7
8
9
10
11
12
13

def flag, L, pntr: int
L = len(a$)
flag = -1
if L > 1
    pntr = 1
    do
        if instr(pntr + 1, a$, mid$(a$, pntr, 1)) > pntr
            flag = 0
      endif
        pntr = pntr + 1
    until not flag | pntr > L
endif
return flag

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

1

def flag, L, pntr: int.  Establishes local variables.  flag is used to indicate success or failure.  L is used to store the length of the argument.  pntr is used as a pointer to the appropriate character of the argument.

2

L = len(a$).  Uses IBasic's in-built function len() to obtain the length (number of characters) of argument a$, which is then stored in variable L.

3

flag = -1.  Initialise flag to TRUE (-1).  This means the function will assume all characters in the argument are different unless it discovers otherwise during execution. The reason for this is the special case where the argument consists of just one character, or no characters at all, as you'll see in the next line.

4

if L > 1.   The possibility exists that the argument consists of only one character, or even that it's an empty string.  In such a case we can say that all characters are definitely different without going any further.  So line 4 is asking the question "Is variable L greater than one (that is, does the argument contain more than one character)?"

If the answer to this question is "no," the code jumps straight to line 13, which just returns the state of flag to the calling routine.  Since the code already initialised flag to TRUE, that is what is returned.  This is correct, because we just established that the argument contains either zero or one character, meaning all its characters are different.

5

pntr = 1.  If the answer to the question in line 4 is "yes," the code moves on to line 5.  It means that, since the argument is at least two characters long, it must be examined in detail for duplicate characters.  In preparation, variable pntr is set to value 1, so that it starts out pointing to the first character in the argument.

6

do.  Opens the main DO loop, which will be used to examine the characters of the argument one at a time for repeats.

7

if instr(pntr + 1, a$, mid$(a$, pntr, 1)) > pntr.  Line 7 is the heart of the code.  Let's work from the inside out, simplifying as we go.  For an example, let's assume a$ (the argument) is "bcde", and the value in pntr is still 1.

The code begins by isolating a character for testing.  Using IBasic's in-built function mid$(), it says
mid$("bcde", 1, 1), which will return "b".  Now the next part of line 6 can be simplified to read instr(2, "bcde", "b").

Here the in-built function Istring() is deployed.  We can paraphrase this part of the line as saying "Starting at the second character of string "bcde" and working to the end, does the character "b" exist?  If it does, return the position of the character.  If not, return value 0."  Note that the search starts at character 2, otherwise the "b" would be falsely reported as being duplicated at position 1.

Finally, then, we can paraphrase the whole of line 6 thus:
"Is the positional value returned from a search for character "b" in string "bcde", starting at position 2, greater than value 1?"

8

flag = 0.  If the answer to the question in line 7 is "yes," we have found a duplicate, so variable flag is set to FALSE to indicate failure (that is, duplicate characters exist).  This line is only executed when a duplicate is found.

9

endif.  Housekeeping: closed IF-ENDIF clause opened in line 7.

10

pntr = pntr + 1.  Variable pntr is incremented to point at the next character.  In the above example, the question would be modified to "Is the positional value returned from a search for character "c" in string "bcde", starting at position 3, greater than value 2?"

11

until not flag | pntr > L.  The code has reached the end of the DO loop and must make a decision: execute it again, or move on to the next line of code.  There are two items on which to base a decision.  Firstly, if flag is set to FALSE a duplicated character has been found and there's no point in continuing the search.  Secondly, if the newly-incremented value in variable pntr is now greater than the value stored in variable L, the whole argument has been searched and there's no more to do.

So line 11 could be paraphrased as:  "If variable flag is set to -1 (FALSE), or the value stored in variable pntr is greater than that stored invariable L, exit the DO loop, otherwise execute it again."

12

endif.  Housekeeping: closes IF-ENDIF clause opened in line 4.  The code can arrive at this line by two routes.  The first occurs when the argument contains either zero or one character, and in this case flag will be at its initialised value of TRUE (-1).  The second occurs when the argument contains more than one character.  In this case, it will have been examined for duplicate characters.  If any were found, the initialised value of flag would have been reset to FALSE (0).

13

return flag.  The code has finished at this point.  All that remains is to return the value in flag to the calling routine, and this line takes care of that.



MAIN MENU
HOW DOES IT WORK?

Site design/maintenance: Dave Ellis E-mail me!
Last Updated: February 3rd, 2010.