Since each letter position within the word has to be changed, but not necessarily in order, we try all permutations of the letter position, which we obtain by permuting the first n digits each time through.
The vary procedure then tries each letter of the alphabet at each of these positions, checking via a binary search that the result is a word, and checking that it is a different word from the one before. The fact that it is following a permutation of the unique first n digits assures that at each new step, the new word is different from words prior to the one previous word.
The parameter l (lower case L) keeps track of the level at which we are, pointing to a digit in the string base$ that tells us which position is to be changed at that level.
DECLARE SUB permute (a$)
DECLARE FUNCTION isWord! (w$)
DECLARE SUB vary (w$, l!)
DIM SHARED hist$(20), base$
INPUT "word:", w$
OPEN w$ + ".mld" FOR OUTPUT AS #1
w$ = LCASE$(LTRIM$(RTRIM$(w$)))
hist$(1) = w$
n = LEN(w$)
w2$ = SPACE$(n)
base$ = LEFT$("123456789", n)
nfact = 1
FOR i = 1 TO n
nfact = nfact * i
NEXT
FOR p = 1 TO nfact
vary w$, 1
permute base$
NEXT
CLOSE
FUNCTION isWord (w$)
n = LEN(w$)
w1$ = SPACE$(n)
OPEN "words" + LTRIM$(STR$(n)) + ".txt" FOR BINARY AS #2
l = LOF(2) / n
low = 1: high = l
DO
mid = INT((low + high) / 2)
GET #2, (mid - 1) * n + 1, w1$
IF w1$ = w$ THEN isWord = 1: CLOSE 2: EXIT FUNCTION
IF w1$ < w$ THEN low = mid + 1: ELSE high = mid - 1 high
isWord = 0
CLOSE 2
END FUNCTION
DEFINT A-Z
SUB permute (a$)
x$ = ""
FOR i = LEN(a$) TO 1 STEP -1
l$ = x$
x$ = MID$(a$, i, 1)
IF x$ < l$ THEN EXIT FOR
IF i = 0 THEN
FOR j = 1 TO LEN(a$) \ 2
x$ = MID$(a$, j, 1)
MID$(a$, j, 1) = MID$(a$, LEN(a$) - j + 1, 1)
MID$(a$, LEN(a$) - j + 1, 1) = x$
NEXT
ELSE
FOR j = LEN(a$) TO i + 1 STEP -1
IF MID$(a$, j, 1) > x$ THEN EXIT FOR
NEXT
MID$(a$, i, 1) = MID$(a$, j, 1)
MID$(a$, j, 1) = x$
FOR j = 1 TO (LEN(a$) - i) \ 2
x$ = MID$(a$, i + j, 1)
MID$(a$, i + j, 1) = MID$(a$, LEN(a$) - j + 1, 1)
MID$(a$, LEN(a$) - j + 1, 1) = x$
NEXT
END IF
END SUB
DEFSNG A-Z
SUB vary (w$, l)
i = VAL(MID$(base$, l, 1))
FOR a = 97 TO 122
wTest$ = w$
MID$(wTest$, i, 1) = CHR$(a)
IF w$ <> wTest$ THEN
IF isWord(wTest$) THEN
good = 1
IF wTest$ = hist$(l) THEN good = 0
IF good THEN
hist$(l + 1) = wTest$
IF l = LEN(w$) THEN
FOR k = 1 TO l + 1
PRINT hist$(k); " ";
PRINT #1, hist$(k); " ";
NEXT
PRINT
PRINT #1,
ELSE
vary wTest$, l + 1
END IF
END IF
END IF
END IF
NEXT
END SUB
|