99 lines
3.6 KiB
Plaintext
99 lines
3.6 KiB
Plaintext
-- This is the blocks array
|
|
global GlobalBlocks = #("BO","XK","DQ","CP","NA", \
|
|
"GT","RE","TG","QD","FS", \
|
|
"JW","HU","VI","AN","OB", \
|
|
"ER","FS","LY","PC","ZM")
|
|
|
|
-- This function returns true if "_str" is part of "_word", false otherwise
|
|
fn occurs _str _word =
|
|
(
|
|
if _str != undefined and _word != undefined then
|
|
(
|
|
matchpattern _word pattern:("*"+_str+"*")
|
|
) else return false
|
|
)
|
|
|
|
-- This is the main function
|
|
fn isWordPossible word blocks: = -- blocks is a keyword argument
|
|
(
|
|
word = toupper word -- convert the string to upper case, to make it case insensitive
|
|
if blocks == unsupplied do blocks = GlobalBlocks
|
|
-- if blocks (keyword argument) is unsupplied, use the global blocks array (this is for recursion)
|
|
|
|
blocks = deepcopy blocks
|
|
|
|
local pos = 1 -- start at the beginning of the word
|
|
local solvedLetters = #() -- this array stores the indices of solved letters
|
|
|
|
while pos <= word.count do -- loop through every character in the word
|
|
(
|
|
local possibleBlocks = #() -- this array stores the blocks which can be used to make that letter
|
|
for b = 1 to Blocks.count do -- this loop finds all the possible blocks that can be used to make that letter
|
|
(
|
|
if occurs word[pos] blocks[b] do
|
|
(
|
|
appendifunique possibleBlocks b
|
|
)
|
|
)
|
|
if possibleBlocks.count > 0 then -- if it found any blocks
|
|
(
|
|
if possibleBlocks.count == 1 then -- if it found one block, then continue
|
|
(
|
|
appendifunique solvedLetters pos
|
|
deleteitem blocks possibleblocks[1]
|
|
pos += 1
|
|
)
|
|
else -- if it found more than one
|
|
(
|
|
for b = 1 to possibleBlocks.count do -- loop through every possible block
|
|
(
|
|
local possibleBlock = blocks[possibleBlocks[b]]
|
|
local blockFirstLetter = possibleBlock[1]
|
|
local blockSecondLetter = possibleBlock[2]
|
|
local matchingLetter = if blockFirstLetter == word[pos] then 1 else 2
|
|
-- ^ this is the index of the matching letter on the block
|
|
|
|
local notMatchingIndex = if matchingLetter == 1 then 2 else 1
|
|
local notMatchingLetter = possibleBlock[notMatchingIndex]
|
|
-- ^ this is the other letter on the block
|
|
|
|
if occurs notMatchingLetter (substring word (pos+1) -1) then
|
|
( -- if the other letter occurs in the rest of the word
|
|
local removedBlocks = deepcopy blocks -- copy the current blocks array
|
|
deleteitem removedBlocks possibleBlocks[b] -- remove the item from the copied array
|
|
|
|
-- recursively check if the word is possible if that block is taken away from the array:
|
|
if (isWordPossible (substring word (pos+1) -1) blocks:removedBlocks) then
|
|
( -- if it is, then remove the block and move to next character
|
|
appendifunique solvedLetters pos
|
|
deleteitem blocks possibleblocks[1]
|
|
pos += 1
|
|
exit
|
|
)
|
|
else
|
|
( -- if it isn't and it looped through every possible block, then the word is not possible
|
|
if b == possibleBlocks.count do return false
|
|
)
|
|
)
|
|
else
|
|
( -- if the other letter on this block doesn't occur in the rest of the word, then the letter is solved, continue
|
|
appendifunique solvedLetters pos
|
|
deleteitem blocks possibleblocks[b]
|
|
pos += 1
|
|
exit
|
|
)
|
|
)
|
|
)
|
|
) else return false -- if it didn't find any blocks, then return false
|
|
)
|
|
|
|
makeuniquearray solvedLetters -- make sure there are no duplicates in the solved array
|
|
if solvedLetters.count != word.count then return false -- if number of solved letters is not equal to word length
|
|
else
|
|
( -- this checks if all the solved letters are the same as the word
|
|
check = ""
|
|
for bit in solvedLetters do append check word[bit]
|
|
if check == word then return true else return false
|
|
)
|
|
)
|