Re (tilly) 1: "Junkyard" Puzzle: Average of Numbers
by tilly (Archbishop) on May 13, 2001 at 06:17 UTC
|
First of all, Perl is list-oriented and handles passed in
arguments by reference. Therefore the Perlish way to do
this is to just take a list of numbers and work with that.
But I will play off the rule as given even though it is
not the API I would choose.
Also the stricture to avoid having any variables should
not be looked at as just a bizarre restriction. People who
program in a functional style often do that voluntarily.
With that in mind I offer the following version that
follows the restrictions as a matter of intentional style
and just happens to solve a more complex problem.
The function is avg_nested which extracts the numbers
from a nested set of arrays of arrays and computes the
average of the entire list:
sub avg {
sum(@_) / @_;
}
sub avg_nested {
avg(flatten_arrays(@_));
}
sub flatten_arrays {
map {ref($_) ? flatten_arrays(@$_) : $_} @_;
}
sub sum {
@_ ? shift(@_) + sum(@_) : 0;
}
UPDATE
jynx caught me. I wrote it, then changed a function
name at the last minute and didn't test properly. I
forgot to change one flatten to flatten_arrays... | [reply] [d/l] |
|
First of all, Perl is list-oriented and handles passed in
arguments by reference. Therefore the Perlish way to do
this is to just take a list of numbers and work with that.
But I will play off the rule as given even though it is
not the API I would choose.
I know this is the case, what I was trying to prevent doing was giving the 'player' the opporuntity to use the copy of the list if the list was passed by value; they could modify this with no concern over altering the original array. (So, for example, doing something that stores the sum in some place in the list copy, would be possible). However, with passing by reference, any changes to the sub's array would affect the original array, and thus you are forced to find another means to store the value.
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] |
Re: "Junkyard" Puzzle: Average of Numbers
by no_slogan (Deacon) on May 13, 2001 at 05:49 UTC
|
eval(join "+", @{$_[0]}) / @{$_[0]}
Update: Oh, are we golfing? That's 31 characters
without the spaces. | [reply] [d/l] |
|
Damn! I did this one without reading a single other post and came out with a sloppier version that yours, but along the same lines (I'm new at this :)
sub find_avg {
(eval join"+",@{$_[0]})/(($#{$_[0]})+1);
}
I had a hell of a time getting $#array working with $_[0]. I see I over complicated it :)
I'd like to add that these "Junkyard" puzzles, Golf and such are extremely good practice for those of us lower on the curve. Just in the past week or so, I've added quite a bit of knowledge to my base. These remind me much of doing geometric proofs back in middle school. Entertaining as well as educational.
Thank you.
| [reply] [d/l] [select] |
|
I wouldn't suggest golfing with these. Sure, you could, but that's not the challenge; it's probably more interesting to see how many TIMTOWTDI approaches can be taken.
Dr. Michael K. Neylon - mneylon-pm@masemware.com
||
"You've left the lens cap of your mind on again, Pinky" - The Brain
| [reply] |
Re: "Junkyard" Puzzle: Average of Numbers
by jmcnamara (Monsignor) on May 14, 2001 at 02:04 UTC
|
This is 37 chars. I saw Abigail do something like this on clpmisc:
sub average1 {
local$"="+";eval("@{$_[0]}")/@{$_[0]}
}
This looks prettier when dealing with an ordinary list:
sub average2 {
local$"="+";eval("@_")/@_
}
In which case this would be shorter:
sub average3 {
eval(join"+",@_)/@_
}
The last one is the same as no_slogan's.
John.
--
| [reply] [d/l] [select] |
Re: "Junkyard" Puzzle: Average of Numbers
by repson (Chaplain) on May 13, 2001 at 05:42 UTC
|
Here's the first thing that springs to mind if I read the problem correctly (30 characters):
sub avg {
(map{(1)x$_}@{$_[0]})/@{$_[0]}
}
| [reply] [d/l] |
|
Clever, but the problem statement doesn't guarantee that
we're dealing with non-negative integers.
| [reply] |
Re: "Junkyard" Puzzle: Average of Numbers (Newbie approach)
by bambam (Initiate) on May 13, 2001 at 06:09 UTC
|
sub s{
push @{$_[0]},0;
${$_[0]}[$#{$_[0]}] += ${$_[0]}[$_] for 0..$#{$_[0]}-1;
${$_[0]}[$#{$_[0]}] /= $#{$_[0]};
pop @{$_[0]};
}
| [reply] [d/l] [select] |
Re: "Junkyard" Puzzle: Average of Numbers
by DrZaius (Monk) on May 13, 2001 at 12:22 UTC
|
sub avg {
return eval '(' . join('+', @{$_[0]}) . ')/' . scalar(@{$_[0]});
}
Works pretty good over all :)
| [reply] [d/l] |
|
Hi,
You could make it shorter by taking out the scalar().
@{$_[0]} is already interpretted in scalar context.
$code or die
$ perldoc perldoc
| [reply] |
Re: "Junkyard" Puzzle: Average of Numbers
by $code or die (Deacon) on May 13, 2001 at 22:25 UTC
|
sub average {
map{$_[1]+=$_}@{$_[0]};$_[1]/@{$_[0]}
}
Works under strict and warnings. Although I am probably breaking your second rule (creating $_[1]).
$code or die
$ perldoc perldoc | [reply] [d/l] |
Re: "Junkyard" Puzzle: Average of Numbers
by MeowChow (Vicar) on May 13, 2001 at 22:56 UTC
|
Flibbertigibbit! All the fun ones have been done...
use List::Util qw(sum);
sub avg { (sum @{$_[0]}) / @{$_[0]} }
oops: didn't notice the last rule. never mind, run along now...
MeowChow
s aamecha.s a..a\u$&owag.print | [reply] [d/l] |