|
Posted by Mike Hunter on June 3, 2008, 11:08 am
Please log in for more thread options
Hey folks,
Recently I was coding and wanted to see which of 4 strings had the
largest result when passed to a function. This is what I ened up
writing:
while (...)
{
my @roundArr;
push @roundArr, [$A, check($goodPrefix.$A)];
push @roundArr, [$C, check($goodPrefix.$C)];
push @roundArr, [$T, check($goodPrefix.$T)];
push @roundArr, [$G, check($goodPrefix.$G)];
@roundArr = sort {$b->[1] <=> $a->[1]} @roundArr;
print $roundArr[0]->[0]." wins!\n";
}
The code works fine, but I can't help but think there's a better idiom
for what I'm trying to do. I get a little bit of a creepy feeling by
using an array, I feel like I should be doing something with a hash. I
guess there's no way of getting around having to associate the given
check() result with the particular input.
Any thoughts on some awesome one-liner that I can't see?
Thanks,
Mike
|
|
Posted by A. Sinan Unur on June 3, 2008, 11:53 am
Please log in for more thread options
> Recently I was coding and wanted to see which of 4 strings had the
> largest result when passed to a function. This is what I ened up
> writing:
>
> while (...)
> {
>
> my @roundArr;
> push @roundArr, [$A, check($goodPrefix.$A)];
> push @roundArr, [$C, check($goodPrefix.$C)];
> push @roundArr, [$T, check($goodPrefix.$T)];
> push @roundArr, [$G, check($goodPrefix.$G)];
>
> @roundArr = sort {$b->[1] <=> $a->[1]} @roundArr;
> print $roundArr[0]->[0]." wins!\n";
>
> }
I don't know about idioms but the question is do you need to store the
results to the check call? If not:
#!/usr/bin/perl
my $goodPrefix = 'prefix';
my ( $A, $C, $T, $G ) = ('a', 'cc', 'ttt', 'gg' );
my $winner = $A;
my $winner_score = check( $goodPrefix.$A );
for my $s ( $C, $T, $G ) {
my $score = check( $goodPrefix.$s );
if ( $score > $winner_score ) {
$winner = $s;
$winner_score = $score;
}
}
print "$winner\t$winner_score\n";
sub check { length shift }
__END__
If you absolutely must use a hash:
#!/usr/bin/perl
use strict;
use warnings;
my $goodPrefix = 'prefix';
my ( $A, $C, $T, $G ) = ('a', 'cc', 'ttt', 'gg' );
my %scores = map { $_ => check( $goodPrefix.$_ ) } ( $A, $C, $T, $G );
my $winner = (sort { $scores <=> $scores } keys %scores)[0];
print "$winner\t$scores\n";
sub check { length shift }
__END__
> Any thoughts on some awesome one-liner that I can't see?
If you have a large number of elements, sort is going to do far more
comparisons than simply walking the elements.
Sinan
--
(remove .invalid and reverse each component for email address)
comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
|
|
Posted by Ben Morrow on June 3, 2008, 12:20 pm
Please log in for more thread options
>
> If you absolutely must use a hash:
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
>
> my $goodPrefix = 'prefix';
>
> my ( $A, $C, $T, $G ) = ('a', 'cc', 'ttt', 'gg' );
>
> my %scores = map { $_ => check( $goodPrefix.$_ ) } ( $A, $C, $T, $G );
>
> my $winner = (sort { $scores <=> $scores } keys %scores)[0];
>
> print "$winner\t$scores\n";
>
> sub check { length shift }
The hash needs to be the other way round:
use List::Util qw/max/;
my %scores = map { check("$goodPrefix$_") => $_ } qw/a cc ttt gg/;
my $winner = max keys %scores;
print "$scores\t$winner\n";
If there is a tie this will pick the last from your original list.
Ben
--
BEGIN;local($#,$;,$/)=@_;for(keys%{ #ben@morrow.me.uk
$#});/(\w):/&&(&(($#.$_,$;.$+,$/),next);$/==$*&&&)($;.$
_)}};*_=sub{for(@_){$|=(!$|||$_||&)(q) )));&((q:\:\::,q,,,$_);$_&&&)("\n")}}}_
$J::u::s::t, $a::n::o::t::h::e::r, $P::e::r::l, $h::a::c::k::e::r, $,
|
|
Posted by Jürgen Exner on June 3, 2008, 11:59 am
Please log in for more thread options >Hey folks,
>
>Recently I was coding and wanted to see which of 4 strings had the
>largest result when passed to a function. This is what I ened up
>writing:
>
>while (...)
>{
>
> my @roundArr;
> push @roundArr, [$A, check($goodPrefix.$A)];
> push @roundArr, [$C, check($goodPrefix.$C)];
> push @roundArr, [$T, check($goodPrefix.$T)];
> push @roundArr, [$G, check($goodPrefix.$G)];
Ouch! Replace the preceeding 4 lines with
for ($A, $C, $T, $G) {
push @roundArr, [$_, check($goodPrefix.$_)];
}
>
> @roundArr = sort {$b->[1] <=> $a->[1]} @roundArr;
> print $roundArr[0]->[0]." wins!\n";
>
>}
>
>The code works fine, but I can't help but think there's a better idiom
>for what I'm trying to do.
Conceptually you just loop through the data set and remember, which
element produced the best result so far:
$best = $a; #just as the default start value
for ($b, $c, $d) {
$best = $_ if check($_) > check($best)
}
However this has some redundancies like computing $best over and over
again. Therefore you want to store that result in an auxiliary variable
$bestV:
$best = $a; #just as the default start value
$bestV = check ($a);
for ($b, $c, $d) {
if (($tmp = check($_)) > $bestV) {
$best = $_;
$bestV = $tmp;
}
}
>I get a little bit of a creepy feeling by
>using an array, I feel like I should be doing something with a hash. I
>guess there's no way of getting around having to associate the given
>check() result with the particular input.
The point is that you don't need to keep all of the temporary results
around, neither in a hash nor in an array. All you need to store is the
currently best candidate and for optimization its value.
jue
|
|
Posted by Tad J McClellan on June 3, 2008, 9:25 pm
Please log in for more thread options
>>Recently I was coding and wanted to see which of 4 strings had the
>>largest result when passed to a function.
> Conceptually you just loop through the data set and remember, which
> element produced the best result so far:
That is known as the "high water mark" algorithm.
--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher0cmdat/"
|
| Similar Threads | Posted | | Good documentation or good source examples for Image::Magick or converter from commandline to perl | April 1, 2008, 5:23 pm |
| Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, | April 21, 2005, 1:25 pm |
| Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, | April 22, 2005, 3:33 pm |
| Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, | April 24, 2005, 6:50 pm |
| Good morning or good evening depending upon your location. I want to ask you the most important question of your life. Your joy or sorrow for all eternity depends upon your answer. The question is: Are you saved? It is not a question of how good you are, | May 1, 2005, 11:27 am |
| Perl/regex Advice | August 5, 2004, 4:42 pm |
| advice for a gui for my perl scripts. | April 29, 2005, 11:37 am |
| Acceptible idiom ? | October 11, 2004, 12:36 pm |
| Concise idiom sought | March 25, 2006, 9:14 am |
| idiom for managing passed arguments? | October 18, 2005, 12:03 pm |
|