Suggestions for how to make this smaller and Perlisher are welcome. I'm sure this can be compressed to a one-liner, somehow...

Heres my go at a generic version. Returns the average of NdS Drop X. N,S should be larger than 0 and X non-negative. eg: avg_die(4,6,1) gives your result (in 162 chars, including sub decl. :-)

#!perl -l use strict; use warnings; $|++; #162 chars, including sub decl. sub A{my($d,$s,$l,$y,$c,$t,$z)=@_;$c||=\$z;if(!$d){ $t+=$_ for(sort{$a<=>$b}@$y)[$l..$#$y];$$c++}else{$t+=A ($d-1,$s,$l,[@{$y||[]},$_],$c)for 1..$s}$y?$t:$t/$z}
sub avg_roll{ my($num_dice, $sides_of_dice, $num_to_lose, # We only expect the below to be provided when called # recursively $rolled_ref, $counter_ref)=@_; my ($total,$counter); # we declare these with the @_ in the golf # version here we seperate them to show they # arent really parameters. $counter_ref||=\$counter; # make a reference to our counter, # unless we were called recursively; unless ($num_dice){ # we are done, no more dice $total+=$_ # increment the total by the value of the dice for ( sort {$a<=>$b} @$rolled_ref # sort the results numerica +lly # to make avg_roll(4,12,1) +work. )[$num_to_lose..$#$rolled_ref]; # take a slice $$counter_ref++ # incrememnt the counter } else { # we havent finished rolling $total+= # so increment the total avg_roll( # by the result $num_dice-1, # of the next die $sides_of_dice, $num_to_lose, [ # pass in a ref, @{$rolled_ref||[]}, # containing the previous rolls $_ # and the new one ], $counter_ref # and a way to access the counter ) for 1..$sides_of_dice # for each possible roll of the d +ie } $rolled_ref ? $total # if we are not the root of the r +ecursion # return the total, whatever it m +ay be : $total/$counter # return the average. }
print A(4,6,1); print avg_roll(4,6,1); __END__ 12.2445987654321 12.2445987654321

Update: 150 chars.

sub B{my($d,$s,$l,$c,@y,$t,$z)=@_;$c||=\$z;if(!$d){$t+=$_ for(sort{$a<=>$b}@y)[$l..$#y];$$c++}else{$t+=B($d-1,$s,$l, $c,@y,$_)for 1..$s}@y?$t:$t/$z}

:-)


---
demerphq

    First they ignore you, then they laugh at you, then they fight you, then you win.
    -- Gandhi



In reply to Re: Rolling DND Dice. by demerphq
in thread Rolling DND Dice. by grendelkhan

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.