Download presentation

Presentation is loading. Please wait.

Published byRiver Wyse Modified about 1 year ago

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

2
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

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

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

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

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

7
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;

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

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

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

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

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

13
Dictionary Input infile INFL dlm=',|' missover end=end; input word do until (word=''); word = compress (word,'~

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

15
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

16
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;

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

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

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

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

21
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;

22
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

23
WORK.UNJUMBLE 1 2 1 1 = 2 combinations

24
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 ;

25
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).

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

27
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 swap reverse ij

28
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;

29
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;

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

31
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;

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

33
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”

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

35
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;

36
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;

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

38
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;

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

40
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;

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

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

43
Answer is: SESUG ATLANTA Paper, Slides, and Code available at

44
About the Author Richard A. DeVenezia Independent Consultant 9949 East Steuben Road Remsen, NY (315)

Similar presentations

© 2017 SlidePlayer.com Inc.

All rights reserved.

Ads by Google