Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris

"Jumble" solver

by ackohno (Scribe)
on Jan 24, 2003 at 03:49 UTC ( #229529=CUFP: print w/replies, xml ) Need Help??

I don't know if anyone else will like this, but I think its kindof neat. Its a nasty little way to unscramble the word puzzle in the comics of the news paper. The way it unscrambles a word is this: first it makes a hash of every word in a word list (as value) and the key is the letters of the word in order (ex: iiiimppssss=> mississippi). then the scrambled word the user specifies is sorted the same way and used as the key in the hash.

to use first make the database with scriptname -m -w wordlist (-d database path). if you use your own database path you will also have to do -d path when you run: unscramble -u scrambledword (-d path)
#!/usr/bin/perl use Getopt::Std; getopts("u:mw:d:"); #defualt file locations over ride with option -d <path> $wordlist = "/usr/share/lib/dict/words"; $database = "$ENV{HOME}/.word_db"; #option -u(nscramble) ... if($opt_u){ #open default if not specified open(IN, $opt_d ? "<$opt_d" : "<$database"); #build the lookup table while(<IN>){ ($value, $key) = split /:/; chomp $key; $hash{$key} = $value; } #arange the letters to match format of database $sorted = join "",sort split//,$opt_u; #display unscrambled word print $hash{$sorted}."\n"; } #build the database file, -m(ake) elsif($opt_m){ open(IN, $opt_w ? "<$opt_w" : "<$wordlist"); open(OUT, $opt_d ? ">$opt_d" : ">$database"); #write lookup table, word:sorted letters while(<IN>) { chomp; $sorted = join "",sort split//; print OUT "$_:$sorted\n"; } } else { print "Usage: ./$0 [-m] [-w[wordlist]] [-d [database]][-u scramble +dword]\n"; }

Replies are listed 'Best First'.
Re: "Jumble" solver
by LAI (Hermit) on Jan 24, 2003 at 15:01 UTC

    This is pretty nifty. I would suggest, though, that you allow for anagrams. Simple example, because I haven't had my coffee yet this morning and I don't have the brain power to thing of a longer anagram: evil, vile and live have the same letters. Yes, I guess the people who write the jumble probably make sure there's only one solution, but just in case you might want your lookup table to be a hash of arrays:

    #option -u(nscramble) ... if($opt_u){ #open default if not specified open(IN, $opt_d ? "<$opt_d" : "<$database"); #build the lookup table while(<IN>){ ($value, $key) = split /:/; chomp $key; push @{$hash{$key}}, $value; # each hash value is an arrayref } #arange the letters to match format of database $sorted = join "",sort split//,$opt_u; #display unscrambled word print join ', ', @{$hash{$sorted}} , "\n"; }

Re: "Jumble" solver
by Hofmator (Curate) on Jan 24, 2003 at 16:08 UTC
    just a quick sidenote ... you might want to check the return value of your calls to open. The standard idiom goes like this: open IN, $filename or die "Couldn't open file '$filename' for reading: $!";

    -- Hofmator

Re: "Jumble" solver
by Coruscate (Sexton) on Jan 25, 2003 at 02:59 UTC

    Here's one of my scripts from my perl drawer. It reads in a dictionary (standard: one word per line of a file), asks the user for a list of letters to unscramble, and does so, giving a list of *all* words 3 letters or longer found within the letters given. What I've wanted to do with this is create a boggle script: the user would input the game board and the script would output all the words found in the puzzle, giving the location of the first letter of each word to boot (for easy finding!). Have yet to get around to that, though it's not one of my priorities, so we'll see if I ever do it.

    If you wanted to change this script to only unscramble the letters (ie: find only words that contain the same number of letters as the letters given), just take out the outer for() loop and change the next unless length $word == $len; line to next unless length $word == length $letters;. Of course, mine ends up being much longer in the end :(

    #!/usr/bin/perl -w use strict; sub cls { system $^O =~ /win32/i ? 'cls' : 'clear' } sub load_dict { my $path = shift; cls(); print "Loading the dictionary..."; open my $dict, $path or die "Dictionary not found at '$path'\n"; chomp( my @words = <$dict> ); close $dict; print " Done.\n", scalar(@words), " words in the dictionary.\n";; sleep 3; return \@words; } my $path = $ARGV[0] or die qq{Usage: "perl }, $0=~m#.*[/\\](.*)$#, qq{ path_to_dictionary"\n}; my $words = load_dict( $path ); for (;;) { my @found; cls(); print 'Letters to unscramble: '; chomp( my $letters = <STDIN> ); last unless $letters; for my $len (reverse( 3 .. length $letters )) { my $s = join '?', (sort( split //, $letters ), ''); for my $word (@$words) { next unless length $word == $len; my $t = join '', sort (split //, $word); push @found, $word if $t =~ /^$s$/; } } print "\n", scalar(@found), " words found in '$letters':\n"; print " - $_\n" for @found; print "\nPress enter to start new scramble...\n"; <STDIN>; }

    "User error. Replace user and press any key to continue."


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: CUFP [id://229529]
Approved by krujos
Front-paged by /dev/trash
[1nickt]: Discipulus Sorry had no time before. ++Test::Warn, but also simply Capture::Tiny to capture everything and examine it. Or just Test::Exception:: dies_ok().

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (4)
As of 2018-01-22 13:05 GMT
Find Nodes?
    Voting Booth?
    How did you see in the new year?

    Results (233 votes). Check out past polls.