On 3/8/11 Tue Mar 8, 2011 2:51 PM, "Ben Lavery" <ben.lav...@gmail.com> scribbled:
> Here is my code, I've taken out a few irrelevant bits, but this is the main > guts: > use warnings; > use strict; > use Math::Combinatorics; > > #Set up a hash for searching later > my %word_list; > > #Read list of valid words into hash > my $WORDFILE='Words'; > open(WORDFILE, "$WORDFILE") or die "can't open $WORDFILE: $!"; > while (<WORDFILE>) { > chomp; > $word_list{$_} = 0; If you assign 1 to the hash value, you can dispense with the 'exists' in your test, below. > } > close(WORDFILE); > > #Set up letters > my @letters = split(//, $ARGV[0]); > > #Used to hold all valid combinations of characters > my @all_combinations; > > #Iterate through the letters > #We then calculate all combinations > #of the letters and see if any of them match a real word. If they > #do, we add them to the @all_combinations array. > my $count = 3; > while($count <= @letters){ > my $combinator1 = Math::Combinatorics->new( > count => $count, > data => [@letters], > ); > > while(my @combo = $combinator1->next_combination){ > my $combinator2 = Math::Combinatorics->new( > count => $count, > data => [@combo], > ); > > while(my @perm = $combinator2->next_permutation){ > my $temp_word = join('',@perm); > > #Here, using a hash looks much cleaner than iterating through an array > push(@all_combinations, $temp_word) if (exists $word_list{$temp_word}); Here, if hash values are 1, you don't need 'exists': push(@all_combinations, $temp_word) if $word_list{$temp_word}; > } > } > $count++; > } > > #Remove duplicates > my %hash = map { $_ => 1 } @all_combinations; > @all_combinations = keys %hash; > > #Print out the array, separating each element with a newline. > print join("\n",@all_combinations),"\n"; > > > Currently, I can call the script as below and get the following output: > $ perl combinations.pl abcde > bade > bed > dace > bad > dab > bead > ace > bac > cad > aced > cade > abc > ade > cab > > I want to be able to specify something like: > $ perl combinations.pl ab.de > This would essentially be the same as doing: > cat Words | grep -e "^ab.de$" > Where Words is a file containing all of the valid words. > > I'm wondering if I need to convert my hash of valid words into an array, then > iterate through each entry with something like: > if($word_list[i] =~ m/$temp_word/){ > push(@all_combinations, $temp_word); > } You can use the built-in grep function to compare each of the words in your word list to your specified pattern, used as a regular expression, and return all that match. In that case, the period is fine, as it will match any character: my @matches = grep( /^$temp_word$/i, @word_list ); push( @all_combinations, @matches ); Note that I have anchored the pattern to the beginning and end of the string so that only full words match, and I have used the i modifier for case-insensitivity. If everything is in the same case, you can dispense with the /i modifier for a little more efficiency; just lower-case your input pattern first. -- To unsubscribe, e-mail: beginners-unsubscr...@perl.org For additional commands, e-mail: beginners-h...@perl.org http://learn.perl.org/