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

Re: Re: Re: Re: Generate unique initials from a list of names

by EdwardG (Vicar)
on Mar 12, 2004 at 20:33 UTC ( [id://336255]=note: print w/replies, xml ) Need Help??


in reply to Re: Re: Re: Generate unique initials from a list of names
in thread Generate unique initials from a list of names

Alan Harper => A H <-- AMBIGUOUS! Adam Harper => Ad Ha

The requirement is that all derived 'initials' should be unambiguous in which name they refer to.

'A H' could refer to Alan or Adam.

My code does this:

Adam Harper => AdHa Alan Harper => AlHa

Replies are listed 'Best First'.
Re: Re: Re: Re: Re: Generate unique initials from a list of names
by Limbic~Region (Chancellor) on Mar 12, 2004 at 21:00 UTC
    EdwardG,
    Ok - I interpreted the requirement differently. Since there are only two possibilities and "Ad Ha" can only refer to 1, "A H" must refer to the other. I believe the following accomplishes what you want - and is actually a bit better than your solution (I think). If I am wrong - I give up.
    #!/usr/bin/perl use strict; use warnings; my %data; my $last = 0; while ( <DATA> ) { chomp; my @names = split; $last = @names if @names > $last; $_ = ucfirst lc $_ for @names; $data{ "@names" } = \@names; } for my $index ( 0 .. $last ) { for my $person ( keys %data ) { next if ! $data{$person}[$index]; my $old_name = $data{$person}[$index]; for my $length ( 1 .. length $old_name ) { $data{$person}[$index] = substr( $old_name, 0, $length ); my $match = 0; for ( keys %data ) { next if $_ eq $person || @{$data{$_}} != @{$data{$pers +on}}; my $test_name = $data{$_}[$index]; $data{$_}[$index] = substr( $test_name, 0, $length ); my ($s_name , $s_test) = ("@{$data{$person}}", "@{$dat +a{$_}}"); $data{$_}[$index] = $test_name; if ( $s_name eq $s_test ) { $match = 1; last; } } last if ! $match; } } } print "@{ $data{$_} } =>\n" for keys %data;
    The reason why I say my code is a bit better is because:
    __DATA__ Victor Mcduffie Viola Mcnamee # Yours Vic Mcd Vio Mcn # Mine V Mcn V Mcd

    Cheers - L~R

      Bingo, yours is now better than mine. :)

      ++

        EdwardG,
        Here is the longer, but more elegant code I mentioned.
        #!/usr/bin/perl use strict; use warnings; my %data = map { chomp; $_ => [ split ] } <DATA>; my $last = 0; for ( keys %data ) { $last = @{$data{$_}} if @{$data{$_}} > $last; $_ = ucfirst lc $_ for @{$data{$_}}; } for my $index ( 0 .. $last ) { for my $name ( map { $data{$_} } keys %data ) { next if ! $name->[$index]; for my $length ( 1 .. length $name->[$index] ) { if ( ! Match( $name, $index, $length ) ) { $name->[$index] = substr( $name->[$index], 0, $length +) ; last; } } } } sub Short { my ( $name, $index, $length ) = @_; return join " ", @{$name}[ grep $_ < $index, 0 .. $#$name ], substr( $name->[$index], 0, $length ), @{$name}[ grep $_ > $index, 0 .. $#$name]; } sub Match { my ( $name, $index, $length ) = @_; my $s_name = Short( $name, $index, $length ); for my $t_name ( map { $data{$_} } keys %data ) { next if @$name != @$t_name || $name eq $t_name; my $s_test = Short( $t_name, $index, $length ); return 1 if $s_name eq $s_test; } return 0; } print "@{ $data{$_} } => $_\n" for sort keys %data;
        If you want it to be even faster, add the following test as the second || condition on line 36.
        index($t_name->[$index], substr($name->[$index], 0, 1))
        Cheers - L~R

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://336255]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (3)
As of 2024-04-25 16:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found