Bit of an improvement on the previous version. This takes about 10 seconds to run on my PC, again for 10 steps. Changes were: reduce the format length stored down from 100, to whatever is required to store the current words add complev's limiter at 2 (i.e. stops counting the difference once it hits 2). That got me about 50% saving. I then realised I could calculate all permutations of X-letter words prior to the looping, which pretty much trivialised the running time. data _null_; datetime = put(datetime(),datetime20.); putlog datetime=; run; %let start=black; %let end=white; %let max_links = 10; %put &start.; %put &end.; %put &max_links.; data words; infile 'c:\unix-words'; format word $22.; input word $; if length(word) = length("&start.") then output; run; data words; format word $%length(&start.).; set words; run; proc sql; create table wordlinks as select monotonic() as n format 8., words.word as old_word, words2.word as new_word from words, words as words2 where complev(words.word,words2.word,2,"il") = 1; quit; %macro wordchain(); proc sql; create table wordchain_1 as select 0 as found, words.word as word_1 from words where words.word = "&start."; quit; %do i = 2 %to &max_links; %put &i.; %let j = %eval(&i - 1); %put &j.; proc sql; create table wordchain_&i. as select (wordchain_&j..found or wordlinks.new_word = "&end.") as found, wordchain_&j..*, wordlinks.new_word as word_&i. from wordchain_&j. left join wordlinks on ( wordchain_&j..word_&j = wordlinks.old_word ) and ( %do n = 1 %to &j.; %if &n > 1 %then and; wordlinks.new_word ~= wordchain_&j..word_&n. %end; ) and wordchain_&j..word_&j. ~= "&end." /* and length(words.word) = length("&end.")*/ where calculated found or (not (calculated found) and wordlinks.old_word is not missing) ; quit; %end; %leave:; %mend; %wordchain(); data solutions; set wordchain_&max_links.; where found = 1; array words{*} word_1-word_&max_links.; count = 0; do i = 1 to dim(words); if missing(words{i}) then leave; count = count + 1; end; drop i; run; proc sort data=solutions; by count; run; data _null_; datetime = put(datetime(),datetime20.); putlog datetime=; run;
... View more