in reply to Rolling DND Dice.
Admittedly I didn't make it shorter. But then again, as pointed out in The path to mastery, I don't think that shorter should always be the immediate aim of someone who is trying to learn...#! /usr/bin/perl -w use strict; my @dist = dice_distribution( sides => 6, number => 4, slice => [1, 2, 3], ); my $average = sum( map $_*$dist[$_], 0..$#dist ) / sum(@dist); print "The average is $average\n"; sub dice_distribution { my %args = @_; my $sides = $args{sides} || 6; my $number = $args{number} || 3; my $slice = $args{slice} || [0..($number - 1)]; my @distribution; nested_for( sub { my @dice = (sort {$a <=> $b} @_)[@$slice]; $distribution[ sum(@dice) ]++; }, map [1..$sides], 1..$number, ); # Quiet warnings $_ ||= 0 for @distribution; return @distribution; } sub sum { my $sum = 0; $sum += $_ for @_; return $sum; } sub nested_for { bind_loops(@_)->(); } sub bind_loops { my $fn = shift; my $range = shift; my $sub = sub {$fn->($_, @_) for @$range}; return @_ ? bind_loops($sub, @_) : $sub; }
(Yes, a key part of this bears a suspicious resemblance to Re (tilly) 1 (perl): What Happened...(perils of porting from c). If you are puzzled over how this works, figuring out that first may be a good idea.)
|
|---|