[tpm] russian peasant multiplication
Dave Doyle
dave.s.doyle at gmail.com
Wed Jul 22 07:38:30 PDT 2009
and once more recursively:
#!/usr/bin/perl
use strict;
use warnings;
use Test::More qw(no_plan);
# russian peasant multiplication
sub rpm {
my $left = abs(int(shift));
my $right = abs(int(shift));
return 0 if !$left || !$right;
return $right if $left == 1;
return ( ($left % 2) == 0 ? 0 : $right) + rpm(int($left/2),$right*2);
}
my @pairs = ( [11,12], [13,14],[999,1],[4252,5723], [0,1],[1,0],[0,0]);
is(
rpm(@{$_}),
$_->[0] * $_->[1],
"$_->[0] * $_->[1] = " . $_->[0] * $_->[1]
) foreach @pairs;
--
dave.s.doyle at gmail.com
On Wed, Jul 22, 2009 at 10:21 AM, Dave Doyle<dave.s.doyle at gmail.com> wrote:
> I know at least one other monger has seen this:
>
> http://thedailywtf.com/Articles/Programming-Praxis-Russian-Peasant-Multiplication.aspx
>
> Anyone take a crack at it? I did just for fun... and a desperate need
> to do something other than PHP right now. It can, of course, be made
> much shorter. I used a hashref with left and right keys to make it a
> little easier to read instead of just using arrayrefs.
>
> #!/usr/bin/perl
>
> use strict;
> use warnings;
> use Test::More qw(no_plan);
>
> # russian peasant multiplication
> sub rpm {
> my @data = ({
> left => abs(int(shift)),
> right => abs(int(shift)),
> });
>
> return 0 unless $data[0]{left} && $data[0]{right};
>
> # half the left, double the right
> while (1) {
> my $row = $data[$#data];
> last if $row->{left} == 1;
> push(@data, {
> left => int($row->{left} / 2),
> right => $row->{right} * 2,
> } );
> }
>
> # calc total by adding right columns to total where left is odd
> my $total = 0;
> $total += ( ($_->{left} % 2) == 0 ? 0 : $_->{right} ) foreach @data;
> return $total;
> }
>
> my @pairs = ( [11,12], [13,14],[999,1],[4252,5723], [0,1],[1,0],[0,0]);
>
> is(
> rpm(@{$_}),
> $_->[0] * $_->[1],
> "$_->[0] * $_->[1] = " . $_->[0] * $_->[1]
> ) foreach @pairs;
>
> --
> dave.s.doyle at gmail.com
>
More information about the toronto-pm
mailing list