Hi dominick_t,

I looked again at the OP, especially at its original content ("long post") before you added the new introduction, and I think I finally understood what you were trying to do.

In the code below, I first traverse the array of words looking for words without repeated letters and store them in the %signatures hash (storing them in anonymous arrays, because two different words may have the same signature if they are anagrams, such as "ab" and "ba" in my list of words).

Then I read the array a second time, skip words without duplicate letters (already stored in the hash), build a signature from the de-duplicated letters; if this signature is found in the %signatures hash, then we've found a word using the same letters as one of the words with no repeated letters and can add it in the array corresponding to this hash entry.

At the end, the program prints every hash entry for which there is more than one word in the anonymous array.

#!/usr/bin/perl use strict; use warnings; my (%seen, %signatures); my @words = qw / ba ab aabb aaabbb xxyy xxxyyy baaab baba xxy xyz ABBA + dcdccd cd/; for my $word (@words) { chomp $word; # not needed here, but may be useful when reading f +rom a file or a DATA section my $word = lc $word; next if $seen{$word}++; next if $word =~ /(.).*\1/; # skip if the word has repeated lette +rs my $signature = join "", sort split //, $word; push @{$signatures{$signature}}, $word; } for my $word (@words) { chomp $word; my $word = lc $word; next unless $word =~ /(.).*\1/;; # skip words already stored (h +aving no duplicate letters) my %unique_letters = map { $_ => 1 } split //, $word; # could use + the uniqstr function of Lists::Util my $signature = join "", keys %unique_letters; push @{$signatures{$signature}}, $word if exists $signatures{$sign +ature}; } for my $key (keys %signatures) { if (scalar @{$signatures{$key}} > 1) { print "@{$signatures{$key}}\n" } }
With the data in the @words array used in the code above, I obtain the following output:
ba ab aabb aaabbb baaab baba abba cd dcdccd
which seems to be what you're looking for.

Note that is probably not how I would usually write this, my code would probably be quite a bit shorter, but I tried to avoid colloquial (too idiomatic) Perl and to keep it very simple, doing things step by step.


In reply to Re: Anagrams & Letter Banks by Laurent_R
in thread Anagrams & Letter Banks by dominick_t

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.