Here's a start, not heavily tested...
Here's how I build my dictionary:
sub word_to_struct { my ( $word ) = @_; my %out; $out{$_}++ for split //, $word; return \%out; } sub read_dict { my ( $dict_file ) = @_; my %out; $dict_file ||= '/usr/share/dict/words'; open my $dict_fh, '<', $dict_file or die "Can't read '$dict_file': $!\n"; while ( my $word = <$dict_fh> ) { chomp $word; if ( $word =~ m{ \A [a-z]+ \z }xmsi ) { $out{$word} = word_to_struct($word); } } close $dict_fh or die "close failed: $!\n"; return \%out; }
That produces a data structure like this:
... 'expletive' => { 'l' => 1, 'e' => 3, 'p' => 1, 'v' => 1, 'x' => 1, 'i' => 1, 't' => 1 }, 'measles' => { 'l' => 1, 'e' => 2, 'a' => 1, 'm' => 1, 's' => 2 }, ...
So then I can build a list of possible words this way:
sub possible { my ( $tiles_ref, $dict_ref ) = @_; my @out; my %tile_count; $tile_count{$_}++ for @{$tiles_ref}; my $longest_word = scalar @{$tiles_ref}; WORD: foreach my $word ( keys %{$dict_ref} ) { next WORD if length $word > $longest_word; foreach my $letter ( keys %{$dict_ref->{$word}} ) { next WORD if ! defined $tile_count{$letter}; next WORD if $dict_ref->{$word}{$letter} > $tile_count{$le +tter}; } push @out, $word; } return @out; } # example: use Data::Dumper; print Dumper( possible( [ qw( a b c d e ) ], read_dict() ) );
It seems to me that the big foreach could be some kind of unholy nested grep, but I haven't done that. Note also that I've rejected the idea of building a regex to match words, and I've made no attempt to make the dictionary compact.
Now that I've written this much, I'm wondering if this is a homework problem.
In reply to Re: Scrabble Word Regex Challenge
by kyle
in thread Scrabble Word Regex Challenge
by QM
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |