LISTSERV at the University of Georgia
Menubar Imagemap
Home Browse Manage Request Manuals Register
Previous (more recent) messageNext (less recent) messagePrevious (more recent) in topicNext (less recent) in topicPrevious (more recent) by same authorNext (less recent) by same authorPrevious page (June 1998, week 2)Back to main SAS-L pageJoin or leave SAS-L (or change settings)ReplyPost a new messageSearchProportional fontNon-proportional font
Date:         Tue, 9 Jun 1998 13:11:55 -0400
Reply-To:     "H. Mark Keintz" <mkeintz@POP.UPENN.EDU>
Sender:       "SAS(r) Discussion" <SAS-L@UGA.CC.UGA.EDU>
From:         "H. Mark Keintz" <mkeintz@POP.UPENN.EDU>
Subject:      Re: Word Jumble problem
Comments: To: Philip Tejera <FXTBB@CUNYVM.CUNY.EDU>
In-Reply-To:  <SAS-L%98060517561269@UGA.CC.UGA.EDU>
Content-Type: TEXT/PLAIN; charset=US-ASCII

There have been a number of solutions to the word jumble problem, but I don't think I saw any that would not require reprogramming when the word to be jumbled gets longer or shorter. Below are solutions to two more general permutation problems.

Problem 1: Generate all permutations of a character string. My proposal is in program 1 below. It's main features are:

1. It uses the COMPRESS function to update the string being permuted. Because COMPRESS removes **all** instances of a character (or characters) from a string, the program never needs to test whether a character has been drawn more than once from the source sting (which many of the other proposals need to do). NOTE that this also means that the program purges source string of duplicates first, so as not to generate an inappropriate number of permutations.

2. As I mention above, the algorithm used will treat a character string of any length.

3. Simply changing the %LET command in program 1 is all that is required to generate an appropriate collection of permuted strings.

Problem 2: Generate a specified permutation of a character string. My proposal is in program 2 below, along with a DATA step demonstrating its use. It's main features:

1. It uses a macro (GETPERM) to generate the result, although I believe the code could easily by put into ordinary SAS code.

2. It also uses the COMPRESS function. Unlike program 1, this macro does not check for duplicate characters, since that would be the task of the calling program.

3. The GETPERM macro takes either literal or variable arguments. These are demonstrated in the sample DATA step.

In addition to leveraging the power of the COMPRESS function, these programs also generate one possible mapping of permutations onto an index set. I.e., if we know there are 24 permutations of "abcd", this provides a way to assign each to a "permutation number."

/********************************** PROGRAM 1 *******************************/

******* Procedure to generate all permutations of a character string *******; ** Note the following assumption: **; ** 1. The original character string has no duplicate characters. **; ** Usage: **; ** 1. Change the %let command below to the string of your choice. **; ** 2. You may wish to change the put= to an output command. **; ** Notes: **; ** 1. The loop that goes P=0 to NPERM-1 would work as P=1 to NPERM too. **; ** **; ** mkeintz@pop.upenn.edu 6/9/98 **; *****************************************************************************;

%let original=abcef;

data _null_;

orig="&original"; *Put word to be permuted in orig; result=orig; result=" "; *Make a same-length blank character variable;

nlet=length(orig); *Calculate the number of letters to be drawn;

nperm=1; *Calculate the number of permutations to generate; do i=1 to nlet; *this could easily be macro-ized to a command ...; nperm=nperm*i; * ... like nperm=%nperm(n); end;

do p=0 to nperm-1; *For each permutation P... ; string=orig; *Generate a working string; result=" "; *blank out result from previous permutation; do i = nlet to 1 by -1; *For each letter .... ; letr=substr(string,mod(p,i)+1,1); *Draw a letter indicated by P ; result=left(trim(result) || letr); *Stick it in the result ; string=compress(string,letr); *Remove it from the working string; end; put p= result=; * or OUTPUT, etc. ; end; run;

/********************************** PROGRAM 2 *******************************/

********** GETPERM generates the P'th permuation of a character string ******; ** Note the following assumption: **; ** 1. The original character string has no duplicate characters. **; ** Usage: **; ** 1. %getperm("abcd",p) or %getperm(word,p) **; ** where word is a character var **; ** and p is a number or a numeric variable. **; ** Notes: **; ** 1. I had wanted to generate a macro that would work in the following **; ** way. RESULT=%GETPERM("abcd",4), but the lack of an exact macro **; ** analog to the COMPRESS function prevents it. **; ** 2. Note that P can be ANY positive or negative number. The macro **; ** will simply cycle through all possible permutations **; ** **; ** mkeintz@pop.upenn.edu 6/9/98 **; *****************************************************************************;

%macro getperm(orig,p); *Macro to generate the Pth permutation of orig; start=&orig; *Make a working string variable; nlet=length(start); *How many letters to jumble?; result=&orig; result=" "; *Build a same-length blank variable; do i = nlet to 1 by -1; * ... for letr=substr(start,mod(&p,i)+1,1); result=left(trim(result) || letr); start=compress(start,letr); end; %mend getperm;

/*********** Sample use of GETPERM follows */

data _null_; wrd="abcd";

do p=0 to 24; %getperm(wrd,p); put p= result= ; end;

%getperm(wrd,100); put p= result=;

do p=4 to 7; %getperm("efgh",p); put p= result=; end;

%getperm("wxyz,22); put p= result=;

run;

Mark Keintz University of Pennsylvania / 6298 Computer Core Director Population Studies Center mark_keintz@pop.upenn.edu 3718 Locust Walk phone: 215/898-6713 fax: 898-2124 Philadelphia, PA 19104-6298


Back to: Top of message | Previous page | Main SAS-L page