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

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

Embed Size (px)

Citation preview

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

Solving Jumble® PuzzlesDictionaries, Hashes and Permutations

Richard A. DeVenezia

Page 2: 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

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

Sample Puzzle

LASRNO O O    

SHACEO   O O

HOTGUF   O O O

CLATHE     O O   O

Hint: You are here.A:                        

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

Puzzle Representation

• Scrambled words– letter pool

• Unscrambled key– Circled positions to answer pool

• Answer key– Dashes

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

Problem Solving

• Input

• Unjumble– Permutation, Lookup

• Letter Pool

• Find Answer– Permutation, Lookup

• Output Results

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

Puzzle Data

• One puzzle per date

datalines;

2006-10-09 ----- -------

fasrn OOO--

shace O--OO

hotguf --OO-O

clathe --OO-O

run;

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

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;

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

ALLPERM

• Permutations– interchange

• “Because each permutation is generated from the previous permutation by a single interchange, the algorithm is very efficient.”

SAS Help

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

ALLPERM

data allperms;

array p[5] (1:5);

do i = 1 to FACT(5);

call ALLPERM(i, of p[*]);

output;

end;

run;

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

Lookup

• DATA Step– SET KEY=index– Custom format– Hash object

• Hash– Key– Data

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

Hash object

declare HASH dict (); dict.defineKey('word'); dict.defineDone();

word='SESUG'; dict.add();

word='SUGI'; found = (dict.check()=0); put found=;---found=0

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

Dictionary Data

• http://wordlist.sourceforge.net/– Word lists

• http://prdownloads.sourceforge.net/wordlist/agid-4.zip– infl.txt (inflected)

conferee N: confereesconference N: conferencesconference V: conferenced | conferencing | conferencesconferencing N?: conferencings

Part ofSpeech

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

Dictionary Input

infile INFL dlm=' ,|' missover end=end;input word pos @;

do until (word=''); word = compress (word,'~<!?'); if not indexc (word,'123456790.{}') then words.replace();

input word @;end;input;

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

Dictionary Output

• Hash methodOUTPUT(dataset:dataset)

rc = words.output (dataset:’sasuser.agid_dictionary’);

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

Unjumble

• Data– Four jumbled words

• Permutations– of letter array

• 5! + 5! + 6! + 6!– 1,680 lookups by word– ALLPERM

• N = n1 n2 n3 n4 combinations

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

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;

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

Data

do until (end_jumble);

set jumbles end=end_jumble;

where date = “09OCT2006”D;

_i + 1;

jumble = lowcase(jumble);

link allperm;

end;

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

ALLPERM section

• Jumbled Word to Letter Array

• For each permutation of Array– Array to Word– If Word in Dictionary

• Determine circled letters

• OUTPUT

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

Word to Letter Array

• length jumble $6

• array letters $1 letter1-letter6• call pokelong (jumble, addrlong (letters[1]))

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

Letter Array to Word

• length jumble $6

• array letters $1 letter1-letter6• jumble = peekclong (addrlong (letters[1])), 6)

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

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;

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

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

c l a t h e* * O O * Oc h a l e tcircled=altwurd=chALeT

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

WORK.UNJUMBLE

word circled circle _i wurdsnarf sna OOO-- 1 SNArfaches aes O--OO 2 AchESchase cse O--OO 2 ChaSEfought ugt --OO-O 3 foUGhTchalet alt --OO-O 4 chALeT

1211 = 2 combinations

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

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 ;

A B C D _A _B _C _Dsna aes ugt alt SNArf AchES foUGhT chALeTsna cse ugt alt SNArf ChaSE foUGhT chALeT

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

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

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

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

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

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

i j

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

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;

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

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;

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

Letter Pool

• POOL_0 – Original letters

• POOL– Letters ordered according to current

permutation

• Mapping– Pool_0 to Pool

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

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

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

Mapping

* map items that were permuted;

if i > 1 thendo ix = i-1 to dim(pool); pool [ ix ] = pool0 [ indx [ ix ] ] ;end;

return;

a b c

3 1 2

c a b

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

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”

1 2 3 4 5 6 7 8 9 10 11 12

1 2 3 4 12 11 10 9 8 7 6 5

1 2 3 5 4 6 7 8 9 10 11 12

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

Short Cut

• Word not in dictionary

• Find shortest prefix that also isn’t

• Sort after prefix

• Compute next permutation

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

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;

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

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;

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

Last Perm of Tail

• Sort the mapping indices– Descending order

• Method– Index Testing– Not Quicksort

3 5 1 4 2

1 1 . 1 .11

22

32

43

5

3 5 43

22

11

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

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;

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

Word Found

• Two cases– Last word of answer

• Output

• Proceed using next perm

– Not last word• Continue using same perm

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

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;

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

Fallback

• Word construction– starts at position p

• Permutation– altered indices prior to p

• search space exhausted

• Response– reduce p to prior start points

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

Backing Up

do while ((i <= p) and (i > 1)) ;

q = q - 1;

words[q]='';

length = wordlens[q];

p = p - length;

end;

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

Answer is:

SESUG ATLANTA

Paper, Slides, and Code available at

http://www.devenezia.com/papers

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

About the Author

Richard A. DeVeneziaIndependent Consultant

9949 East Steuben RoadRemsen, NY 13438

(315) 831-8802

http://www.devenezia.com/contact.php