Update: cleaned up check_part() - removed debugging, filtered dups.#!/usr/bin/perl # usage: anagram 'my phrase' dictionary_file use warnings; use strict; use Algorithm::Loops qw/ NestedLoops /; my $phrase = shift; my $dict = shift; # collapse all letters into a sorted sequence (my $sorted = $phrase) =~ s/[\W]//g; $sorted = join '', sort split //, $sorted; my $rx = qr|^[$sorted]+$|i; my $phrase_length = length $sorted; open DICT, "<$dict" or die "Could not open $dict: $!\n"; my @list; my $num_words; while (my $word = <DICT>) { chomp $word; next if length $word > $phrase_length; next unless $word =~ $rx; next if length $word == 1 && $word ne 'a' && $word ne 'i'; push @{ $list[length $word] }, $word; $num_words++; } close DICT; print "Number of words in pool: $num_words\n"; my @size; $size[$_] = @{ $list[ $_ ] } for 1..$phrase_length; # Enumerate over all integer partitions my @p; part( 2*$phrase_length, $phrase_length, 0); ### Subroutines sub part { my ($n, $k, $t) = @_; $p[$t] = $k; check_part( $t) if $n == $k; for (my $j = $k<$n-$k ? $k : $n-$k; $j >= 1; $j--) { part( $n-$k, $j, $t+1); } } my %ana_seen; sub check_part { my $t = shift; # create iterator for all combos of words my @iter = map { [0..$size[$p[$_]]-1] } 1..$t; my $iter = NestedLoops( \@iter); while( my @i = $iter->() ) { my $formatted = join " ", sort map {$list[ $p[$_] ][ $i[$_-1] ]} + 1..$t; next if $ana_seen{$formatted}; $ana_seen{$formatted} = 1; my $test = join "", split / /, $formatted; $test = join '', sort split //, $test; print "$formatted\n" if $test eq $sorted; } }
-Mark
|
---|
Replies are listed 'Best First'. | |
---|---|
Re: Generate Multi-word Anagrams
by japhy (Canon) on Apr 28, 2004 at 08:27 UTC | |
(Golf) Generate Multi-word Anagrams
by dragonchild (Archbishop) on Apr 28, 2004 at 20:12 UTC | |
Re: Generate Multi-word Anagrams
by dragonchild (Archbishop) on Apr 28, 2004 at 02:18 UTC | |
by kvale (Monsignor) on Apr 28, 2004 at 03:25 UTC | |
Re: Generate Multi-word Anagrams
by QM (Parson) on Jan 25, 2005 at 22:36 UTC |