# Solving Jumble® Puzzles Dictionaries, Hashes and Permutations Richard A. DeVenezia.

## Presentation on theme: "Solving Jumble® Puzzles Dictionaries, Hashes and Permutations Richard A. DeVenezia."— Presentation transcript:

Solving Jumble® Puzzles Dictionaries, Hashes and Permutations Richard A. DeVenezia

Jumble® Puzzles Four scrambled words –Two five letter words –Two six letter words Marked letters of unscrambled words –Scramble of an answer to a cartoon hint

Sample Puzzle LASRNO O O SHACEO O O HOTGUF O O O CLATHE O O O Hint: You are here. A:

Puzzle Representation Scrambled words –letter pool Unscrambled key –Circled positions to answer pool Answer key –Dashes

Problem Solving Input Unjumble –Permutation, Lookup Letter Pool Find Answer –Permutation, Lookup Output Results

Puzzle Data One puzzle per date datalines; 2006-10-09 ----- ------- fasrn OOO-- shace O--OO hotguf --OO-O clathe --OO-O run;

Input data jumbles (keep=date jumble circle) answers (keep=date answer) ; input date yymmdd10. answer \$char50.; output answers; do i = 1 to 4; input jumble:\$6. circle:\$6. ; output jumbles; end;

ALLPERM Permutations –interchange “Because each permutation is generated from the previous permutation by a single interchange, the algorithm is very efficient.” SAS Help

ALLPERM data allperms; array p[5] (1:5); do i = 1 to FACT(5); call ALLPERM(i, of p[*]); output; end; run;

Lookup DATA Step –SET KEY=index –Custom format –Hash object Hash –Key –Data

Hash object declare HASH dict (); dict.defineKey('word'); dict.defineDone(); word='SESUG'; dict.add(); word='SUGI'; found = (dict.check()=0); put found=; --- found=0

Dictionary Data http://wordlist.sourceforge.net/ –Word lists http://prdownloads.sourceforge.net /wordlist/agid-4.zip –infl.txt (inflected) conferee N: conferees conference N: conferences conference V: conferenced | conferencing | conferences conferencing N?: conferencings Part of Speech

Dictionary Input infile INFL dlm=',|' missover end=end; input word pos @; do until (word=''); word = compress (word,'~ { "@context": "http://schema.org", "@type": "ImageObject", "contentUrl": "http://images.slideplayer.com/13/4029063/slides/slide_13.jpg", "name": "Dictionary Input infile INFL dlm= ,| missover end=end; input word pos @; do until (word= ); word = compress (word, ~

Dictionary Output Hash method OUTPUT(dataset:dataset) rc = words.output (dataset:’sasuser.agid_dictionary’);

Unjumble Data –Four jumbled words Permutations –of letter array 5! + 5! + 6! + 6! –1,680 lookups by word –ALLPERM N = n 1  n 2  n 3  n 4 combinations

Load Dictionary declare hash dict (); dict.defineKey ('word'); dict.defineDone (); length word \$6; do until (end_dict); set &dictionary (where=(length(word) in (5,6))) end=end_dict ; word = lowcase(word); dict.replace(); end;

Data do until (end_jumble); set jumbles end=end_jumble; where date = “09OCT2006”D; _i + 1; jumble = lowcase(jumble); link allperm; end;

ALLPERM section Jumbled Word to Letter Array For each permutation of Array –Array to Word –If Word in Dictionary Determine circled letters OUTPUT

Word to Letter Array length jumble \$6 array letters \$1 letter1-letter6 call pokelong (jumble, addrlong (letters[1]))

Letter Array to Word length jumble \$6 array letters \$1 letter1-letter6 jumble = peekclong (addrlong (letters[1])), 6)

Check Each Permutation L = length (jumble); call pokelong(jumble,addrlong(letters[1])); do i = 1 to fact (L); if L = 5 then call allperm (i, of letters1-letters5); else call allperm (i, of letters1-letters6); word = peekclong (addrlong (letters(1)), L); if (word ne jumble) and dict.check () = 0 then... end;

Circled Letters k = 1; circled = ' '; do j = 1 to length (circle); if substr(circle,j,1) = 'O' then do; substr(circled,k,1) = substr(word,j,1); substr(wurd,j,1) = upcase(substr(wurd,j,1)); k + 1; end; OUTPUT; c l a t h e * * O O * O c h a l e t circled=alt wurd=chALeT

WORK.UNJUMBLE 1  2  1  1 = 2 combinations

WORK.POOL create table pool as select a.circled as A, b.circled as B, c.circled as C, d.circled as D, a.wurd as _A, b.wurd as _B, c.wurd as _C, d.wurd as _D from unjumble as a, unjumble as b, unjumble as c, unjumble as d where a._i = 1 and b._i = 2 and c._i = 3 and d._i = 4 ;

Finding the Answer Permute pool –ALLPERM ? –12 letter pool = 479,001,600 perms Lexicographic ordering –Permutation f precedes a permutation g in the lexicographic (alphabetic) order iff for the minimum value of k such that f(k)  g(k), we have f(k) < g(k).

Lexico-what? Ordered progression –Avoid unnecessary checks Example –iterator arrives at 1-3-2-4-5 –dictionary says no 1-3’s –advance to nextperm 1-4-x-x-x

Next Perm From right –find i where f ( i-1 ) < f ( i ) From i+1 –find j where f ( j ) < f ( i-1 ) Swap –f ( i-1 ) and f ( j - 1 ) Reverse –from i to end 1 - 5 - 4 - 3 - 2 swap 2 - 5 - 4 - 3 - 1 reverse 2 - 1 - 4 - 3 - 5 2 - 1 - 3 - 4 - 5 ij

NEXTPERM next_perm: i = 12; do while (i > 1); if (indx[i-1] <= indx[i]) then leave; i + (-1); end; if i = 1 then return; j = i + 1; do while (j <= 12); if (indx[i-1] >= indx[j]) then leave; j + 1; end;

NEXTPERM * swap ; ix1 = i-1; ix2 = j-1; h = indx[ix1]; indx[ix1] = indx[ix2]; indx[ix2] = h; * reverse v[i..n] by swapping; ix1 = i; ix2 = 12; do while (ix1 < ix2); h = indx[ix1]; indx[ix1] = indx[ix2]; indx[ix2] = h; ix1 + 1; ix2 + (-1); end;

Letter Pool POOL_0 –Original letters POOL –Letters ordered according to current permutation Mapping –Pool_0 to Pool

Filling the Pool array circles [4] \$6 a b c d; ix = 1; do i = 1 to dim(circles); do j = 1 to length (circles[i]); pool0[ix] = substr (circles[i],j,1); pool [ix] = pool0[ix]; indx [ix] = ix; ix + 1; end;

Mapping * map items that were permuted; if i > 1 then do ix = i-1 to dim(pool); pool [ ix ] = pool0 [ indx [ ix ] ] ; end; return;

Dead Ends 12 letters s n a a e s u g t a l t –No words start with “snaa” –Can skip remaining sequence of 8! permutations that start with “snaa”

Short Cut Word not in dictionary Find shortest prefix that also isn’t Sort after prefix Compute next permutation

Prefix Dictionary * hash for dictionary of word prefixes; declare hash part (); part.defineKey ("length", "count", "prefix"); part.defineDone (); *... For each word added to dictionary...; * add word prefixes to word prefix dictionary; length = length(word); do count = 2 to length-1; prefix = substr(word,1,count); if part.check() eq 0 then continue; part.add(); end;

Word Tests word=peekclong(addrlong(pool(p)),length); if (dict.check() ne 0) then do; * word not found, find smallest prefix * not in prefix dictionary; do count = 2 to length-1; prefix = substr(word,1,count); if part.check() ne 0 then leave; end;

Last Perm of Tail Sort the mapping indices –Descending order Method –Index Testing –Not Quicksort

Tail Sort array map[12]; call missing (of map[*]); LEFT = p + count; RIGHT = 12; do ix = LEFT to RIGHT; map [ indx [ ix ] ] = 1; end; j = 12; do ix = 1 to 12 while (j >= LEFT); if not map[ ix ] > 0 then continue; indx [ j ] = ix; j = j - 1; end;

Word Found Two cases –Last word of answer Output Proceed using next perm –Not last word Continue using same perm

Successes if (q = 2) then do; if (soln.check() ne 0) then do; soln.add(); put 'NOTE: ' words[*]; end; words[q] = ' '; end; else do; * advance p to next word place; q + 1; p + length; length = wordlens[q]; CONTINUE; * return to top of loop; end;

Fallback Word construction –starts at position p Permutation –altered indices prior to p search space exhausted Response –reduce p to prior start points

Backing Up do while ((i 1)) ; q = q - 1; words[q]=''; length = wordlens[q]; p = p - length; end;

Answer is: SESUG ATLANTA Paper, Slides, and Code available at http://www.devenezia.com/papers

About the Author Richard A. DeVenezia Independent Consultant 9949 East Steuben Road Remsen, NY 13438 (315) 831-8802 http://www.devenezia.com/contact.php

Download ppt "Solving Jumble® Puzzles Dictionaries, Hashes and Permutations Richard A. DeVenezia."

Similar presentations