THE PUZZLET PAGE

PUZZLET 058 - THE SOLUTION


' Puzzlet #058
' Find any integer not greater than 9999 such
' that subtracting its reverse from the original
' yields an anagram of the original.
' Example:  2961 - 1692 = 1269.
' Note: leading zeroes can be inferred where
' necessary.
' By Dave Ellis.

declare Reversed(n: int)
declare IsAnagram(str1$: string, str2$: string)
declare PrintResult(n: int, r: int, d: int)
def num, revNum, diffNums: int
def numStr$, diffNumStr$: string
openconsole
print "Searching ...": print
num = 1

do
    revNum = Reversed(num)
    diffNums = num - revNum
    numStr$ = ltrim$(str$(num))
    diffNumStr$ = ltrim$(str$((diffNums)))
    if IsAnagram(numStr$, diffNumStr$)
        PrintResult(num, revNum, diffNums)
    endif
    num = num + 1
until num = 10000

print: print "No More!"
print: print "Press any key ... ",
do: until inkey$ <> ""
closeconsole
end


sub Reversed(n)
' returns the reverse of n
' example: n = 1234 returns 4321
def i, L: int
def n$, rev$: string
n$ = ltrim$(str$(n))
L = len(n$)
rev$ = ""
for i = L to 1 #-1
    rev$ = rev$ + mid$(n$, i, 1)
next i
return val(rev$)

sub IsAnagram(str1$, str2$)
' if str1$ is an anagram of str2$,
' returns -1, else returns 0.
def i$, j$, test$: string
def flag, i, j, L1, L2: int
test$ = str2$
L1 = len(str1$)
L2 = len(test$)
if L1 <> L2
    flag = 0
else
    for i = 1 to L1
         i$ = mid$(str1$, i, 1)
        j = 1
        flag = -1
        do
        j$ = mid$(test$, j, 1)
            if i$ = j$
                replace$(test$, j, 1, "X")
                flag = 0
        endif
            j = j + 1
        until flag = 0 | j > L2
    next i
    flag = (test$ = string$(L1, "X"))
endif
return flag

sub PrintResult(n, r, d)
' pretty printer
def format$: string
format$ = "####"
print using (format$, n), " - ",
print using (format$, r), " = ",
print using (format$, d)
return


PROGRAM NOTES


Integer variable num is used to iterate over the search range from 1 to 9999.  Its reverse is held in another integer variable, revNum.  The reverse is obtained by submitting num as parameter to the function Reversed().  The returned value is stored in revNum.

The difference between num and revNum is stored in a third integer variable, diffNums.  Remember, it's the value in diffNumsnum
that interests us- if it's an anagram of num, we've found a valid solution.

We're now ready to make the test.  I have elected to use string-slicing here so num and diffNum are converted into numStr$ and diffNumStr$ respectively.  The contents of these two variables are passed as parameters to the function IsAnagram().

IsAnagram() looks at its two arguments, given local variable names str1$ and str2$.  If one is the anagram of the other, -1 (TRUE) is returned to the calling routine, otherwise 0 (FALSE) is returned.  IsAnagram() has been used in Puzzlets before, so I don't propose to explain how it works again here.  If you want to know more, please either refer back to the Archives, or e-mail me at the address below.

If TRUE is returned we have a solution, and it's printed out to the screen in a tidy manner by the subroutine PrintResult(). Either way, the program carries on until all values for num up to 9999 have been explored, printing out any solutions
it finds along the way.

When you run the code, it generates the screen shown inset.  

There are a total of seven solutions.

Note that 1980 and 3870 assume the leading zero in their reversals.

Searching ...

  954 -  459  =  495
1980 -   891 = 1089
2961 - 1692 = 1269
3870 -   783 = 3087
5823 - 3285 = 2538
7641 - 1467 = 6174
9108 - 8019 = 1089

No more!

Press any key ...


MAIN MENU
DOWNLOAD CODE
ARCHIVES


Site design/maintenance: Dave Ellis E-mail me!
Last Updated: February 22nd, 2004.