permuting a string (was Re: Speed)

Peter M. Brigham pmbrig at gmail.com
Tue Aug 26 14:14:41 EDT 2014


A tune-up on the earlier solution to listing permutations of a string. Obviously, no need to load an array with the values of the characters, just use "char c of tString". Also, if tString contains duplicate letters then there will be duplicate entries in the output, so those should be stripped before returning the result of the function. Here's the streamlined script:

function permute tString
   put (the length of tString) into N
   if N > 9 then
      answer "Can only permute up to 9 characters."
      exit permute
   end if
   subtract 1 from N
   put P2(N,49) into permList
   repeat with c = 1 to N+1
        replace c with char c of tString in permList
   end repeat
   noDupes permList
   return permList
end permute

function P2 N,B
   -- N is the depth to permute
   -- B is the ASCII value to start from
   -- so P2(1,49) returns 21 cr 12
   -- P2(2,53) returns 675 cr 765 cr 756 cr 576 cr 657 cr 567
   if N = 0 then return numToChar(B) & cr
   put P2(N - 1,B) into T
   add B to N
   repeat with i = B to N - 1
      put T into T2
      replace numToChar(i) with numToChar(N) in T2
      replace cr with numToChar(i) & cr in T2
      put T2 after R
   end repeat
   replace cr with numToChar(N) & cr in T
   return R & T
end P2

on noDupes @tList,tDelim
   -- thanks to Peter Hayworth of the use-LC mailing list
   -- NOTE: tList is referenced, so the original list will be changed.
   
   -- strips duplicate (and empty) lines/items from a list
   -- if tDelim = empty then looks first for the presence of cr in tList,
   --       if found, defaults to cr as the delimiter
   --    if no cr found, looks for the presence of comma in tList,
   --       if found, defaults to comma as the delimiter
   --    if neither found, exits without changing tList
   --       (user should have specified another delim)
   
   -- use it as follows, eg:
   --  assuming theList starts as a comma-delimited list, call:
   --    noDupes theList,comma      or just      noDupes theList
   --  following which theList will contain the original list
   --    stripped of empty and duplicate items
   
   -- note: the order of the list will likely be changed, may require re-sorting
   -- note: the split command is inherently case-sensitive
   --    (irrespective of the value of the caseSensitive property),
   --    so "Chuck" and "chuck" will not be considered duplicates
   --    if you need case insensitive, use the noDupes() function instead
   
   if tDelim = empty then
      if cr is in tList then
         put cr into tDelim
      else if comma is in tList then
         put comma into tDelim
      else
         answer "noDupes: no delimiter specified" as sheet
         exit noDupes
      end if
   end if
   replace tDelim with cr in tList
   filter tList without empty
   split tList by cr and cr
   put the keys of tList into tList
   replace cr with tDelim in tList
end noDupes

-- Peter

Peter M. Brigham
pmbrig at gmail.com
http://home.comcast.net/~pmbrig





More information about the use-livecode mailing list