Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Dice roll chances

by Anonymous Monk
on Nov 11, 2017 at 19:14 UTC ( [id://1203189]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

As the title states I must write a PERL program that randomly generates a number between 1 and 50 in groups of 5. Sum each group and display the results so that each number is on its own line. This question was given to be in the first week of a introduction to Perl class that I am taking and I have to admit I am a little lost. I figured out how to do the first part "randomly generates a number between 1 and 50 in groups of 5" but for the live of me I can not figure out the rest. Any help would be much appreciated. Where is what I have so far.

#!/usr/bin/env perl use strict; use warnings; use List::Util 'shuffle'; use List::MoreUtils qw(natatime); use feature qw(say); my $iterator = natatime 5, shuffle( 1 .. 50 ); my $count = 1; while ( my @five = $iterator->() ) { say join " ", @five; $count++; last if $count > 5; }

2017-11-14 Athanasius retitled and added code and paragragh tags

Replies are listed 'Best First'.
Re: Sum group of numbers and display each number is on its own line
by toolic (Bishop) on Nov 11, 2017 at 19:25 UTC
    One way is to use "sum" from List::Util:
    use strict; use warnings; use List::Util qw(sum shuffle); use List::MoreUtils qw(natatime); use feature qw(say); my $iterator = natatime 5, shuffle( 1 .. 50 ); my $count = 1; while ( my @five = $iterator->() ) { say sum(@five); $count++; last if $count > 5; }

    See also:

Re: Sum group of numbers and display each number is on its own line -- plain way
by Discipulus (Canon) on Nov 11, 2017 at 20:04 UTC
    Hello,

    apart from the long title (I used the better one used by toolic) and the poorly formatted text I suggest you to sign in order, in the future, to be able to edit your own post. For you personal colture PERL does not exists: Perl is the language name and perl is the program that executes your programs.

    The, first, basic rule in programming is to translate a spoken problem or algorithm to a program.

    > I must write a PERL program that randomly generates a number between 1 and 50 in groups of 5. Sum each group and display the results so that each number is on its own line.

    The missing spec is: how many times you want to do this? let's say 3 time..

    Let's see:

    # a PERL program that.. use strict; use warnings; # the missing spec: 3 times for (1..3){ my $sum; # in groups of 5 for (1..5){ # randomly generates a number between 1 and 50 # Sum each group $sum += int (rand(50)+1); } # display the results so that each number is on its own line print "$sum\n"; }

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      Hi Discipulus,

      I like your solution because it's doing the work using Perl code. I do not think that is is a great idea to use several different modules to solve such a simple problem, especially for a beginner probably learning the art of programming. I think it is better for a beginner to actually learn coding such simple algorithms before using ready-made solutions from modules. (I suspect that some monks will probably disagree with me and say that you shouldn't reinvent the wheel, but I insist that the most essential quality of a programmer is to be able to understand a problem and to implement things with no ready-made crutches.)

      I have seen too many self-styled Web developers just using intensively Laravel or Symphony, but more or less unable to write five lines of consistent PHP code. IMHO, it is important to learn doing the things by yourself before you use some extra libraries doing the hard work for you.

        I agree with "the most essential quality of a programmer is to be able to understand a problem" ...

        I'm not sure I agree with "with no ready-made crutches" ...

        First, they are tools, not crutches. Second, why would you not use the tools if they exist? What is important, as with electric power saws, is learning the use of the tool, and that includes understanding what it does. I do agree with you that often that can not be grasped without working though an implementation manually. But part of learning the craft is learning the tools.

        OTOH: This week I had several interviews for a $job, many with observed coding tests. The one I had most trouble with was some numeric array index-related problem, and I found I couldn't refocus my mind from hours of talk about system architecture to slice and splice and (0..$#x), with the two guys chattering amongst themselves, and it being the end of a long day. Just froze and became irritated. "Would you like me to write an object class, or maybe a log adapter, or something *meaningful*?" I asked, darkly.

        They changed the subject and we talked about concurrency and parallelization, and of course 5 minutes after the call ended I emailed them a simple solution to their task, which was not dissimilar to many questions here. I don't think they will hold it against me too much, but I guess I must concur that keeping in the habit of using the basics is a good policy!


        The way forward always starts with a minimal test.
Re: Write a Perl program that poetically generates ...
by 1nickt (Canon) on Nov 11, 2017 at 22:40 UTC

    Hi, don't forget to be a bit poetic. You're writing Perl.

    Update: edited to output the sum of random numbers on one line, misunderstood the spec. Still somewhat poetic, I hope.

    use strict; use warnings; use feature 'say'; sub num { my $num = int( rand( 50 ) + 1 ); $num } sub sum { my $sum = 0; $sum += $_ for @_; $sum } say sum map { num } 1 .. 5 until not 'fun'; __END__

    Hope this helps ;-)


    The way forward always starts with a minimal test.
Re: Dice roll chances (was: Write ... line)
by kcott (Archbishop) on Nov 12, 2017 at 00:34 UTC
    "This question was given to be in the first week of a introduction to Perl class ..."

    Given this information, it seems unlikely that you were expected to use a variety of functions from core and CPAN modules; however, I could be entirely wrong about that. When stuck on a homework problem such as this, it helps if we know exactly what you were learning. Context is also useful: for instance, "I'm learning programming for the first time at school", "I'm studying bioinformatics at university", and so on. Also take a look at "How do I post a question effectively?" for more guidelines on what information to provide with your question.

    Putting the implementation aside, the actual problem to be solved is unclear. As I write this, I see there's already two interpretations; and I have a third. Showing a clear example of the type of results you're expecting would really help.

    Anyway, this sounded like a fairly basic problem, that's used in programming tutorials, which usualy goes something like: "Rolling two six-sided dice produces results between 2 and 12. What are the chances of rolling each possible result?"

    I coded that as a one-liner:

    $ perl -e 'my ($n, $s, $r) = @ARGV; my %x; for (1 .. $r) { my $y = 0; +for (1 .. $n) { $y += 1 + int rand $s } ++$x{$y} } printf "Chance of +rolling %3d is %3d%%\n", $_, int $x{$_} / $r * 100 for sort { $a <=> +$b } keys %x' 2 6 1000000

    I've broken that up into multiple lines for ease of viewing (and added the results of a sample run):

    $ perl -e ' my ($n, $s, $r) = @ARGV; my %x; for (1 .. $r) { my $y = 0; for (1 .. $n) { $y += 1 + int rand $s } ++$x{$y} } printf "Chance of rolling %3d is %3d%%\n", $_, int $x{$_} / $r * 100 for sort { $a <=> $b } keys %x ' 2 6 1000000 Chance of rolling 2 is 2% Chance of rolling 3 is 5% Chance of rolling 4 is 8% Chance of rolling 5 is 11% Chance of rolling 6 is 13% Chance of rolling 7 is 16% Chance of rolling 8 is 13% Chance of rolling 9 is 11% Chance of rolling 10 is 8% Chance of rolling 11 is 5% Chance of rolling 12 is 2%

    So, if you think of your question in terms of rolling five 50-sided dice, this might be the sort of thing you're after; there again, it might be nothing like what you want.

    The code I provided would not, I imagine, be acceptable for a class project: variable names should be meaningful; statements should be formally terminated with semicolons; and the final statement would be better as an actual block. There's no validation of input or error checking (for example, because all percentages are rounded down to the nearest integer, their sum is only 94%, not 100%). You may also have coding standards which you need to follow.

    I'd recommend you fully understand the code before enhancing it. Although the single-letter variable names made sense to me when I was writing the one-liner, they may be as clear as mud to you or others: $n is the number of dice; $s is the number of sides; $r is the number of rolls; %x is a hash which collects the results; and, $y is a temporary value which is reinitialised on each iteration of the outer loop. See also sprintf.

    — Ken

Re: Dice roll chances
by BrowserUk (Patriarch) on Nov 11, 2017 at 22:23 UTC
    C:\docs>perl -mList::Util=sum -e"map print( qq[@$_ : = ], sum @$_ ), [ + map int( 1+rand( 50 ) ), 1 .. 5 ] while <STDIN>" 41 19 15 43 36 : = 154 26 19 12 4 40 : = 101 44 18 1 25 36 : = 124 25 50 48 7 42 : = 172 24 22 3 40 48 : = 137 19 32 7 48 19 : = 125 12 31 9 7 44 : = 103 19 12 41 17 2 : = 91 39 34 5 33 31 : = 142 42 18 15 5 2 : = 82 2 30 32 37 13 : = 114 1 45 2 3 11 : = 62 5 19 48 3 45 : = 120 37 5 37 50 5 : = 134 24 46 16 42 4 : = 132 38 33 15 18 1 : = 105 31 24 6 13 1 : = 75 33 46 9 15 36 : = 139 7 1 5 45 48 : = 106 8 45 38 19 45 : = 155 21 13 18 27 50 : = 129 29 12 29 33 28 : = 131 43 18 28 23 2 : = 114 47 24 45 4 16 : = 136 6 40 4 7 19 : = 76 46 23 31 16 48 : = 164 35 10 36 43 26 : = 150 21 23 16 29 22 : = 111 46 49 5 1 13 : = 114 15 3 11 30 43 : = 102 42 24 31 39 32 : = 168 29 5 8 34 2 : = 78 31 13 28 19 47 : = 138 6 29 1 29 31 : = 96 31 2 26 27 14 : = 100 27 14 26 47 1 : = 115 40 29 14 28 16 : = 127Terminating on signal SIGINT(2)

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". The enemy of (IT) success is complexity.
    In the absence of evidence, opinion is indistinguishable from prejudice. Suck that fhit
Re: Dice roll chances
by choroba (Cardinal) on Nov 11, 2017 at 23:41 UTC
    Another way is golf:
    # 1 2 3 4 5 #2345678901234567890123456789012345678901234567890 @%=1..50;$%+=splice@%,rand@%,1for$]..9;print$%,$/
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      Another way is golf

      Because what intro to programming grader doesn't love golfed and/or obfuscated code! The more devious and clever the better, they say.

      :)

Re: Dice roll chances
by karlgoethebier (Abbot) on Nov 12, 2017 at 09:59 UTC

    My 2˘: perl -E 'say scalar map {1..$_} map {int (rand(50)+1)} (1..5);'

    Update:

    I guess i'll never learn it to read specs right.

    Did you mean this?

    1. Pick up 5 random numbers from 1 to 50
    2. Add them
    3. Print the sum on one line
    4. Repeat this 5 times

    If so, this should work: perl -E 'say scalar map {1..$_} map {int (rand(50)+1)} (1..5)  for 1..5'

    Update 2:

    If you want to use the numbers only once, this should work:

    #!/usr/bin/env perl use strict; use warnings; use feature qw (say); my @n = ( 1 .. 50 ); # ad libitum: # open( my $urandom, "</dev/urandom" ) || die $!; # read( $urandom, $_, 4 ); # close $urandom; # srand( unpack( "L", $_ ) ); # for ( my $i = @n ; --$i ; ) { # my $j = int( rand( $i + 1 ) ); # next if $i == $j; # @n[ $i, $j ] = @n[ $j, $i ]; # } say scalar map { 1 .. $_ } map { splice( @n, int( rand(@n) ), 1 ) } ( 1 .. 5 ) for 1 .. 5; __END__

    To be honest: i didn't test it very thoroughly ;-(

    Best regards, Karl

    «The Crux of the Biscuit is the Apostrophe»

    perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: Dice roll chances
by BillKSmith (Monsignor) on Nov 11, 2017 at 22:08 UTC
    It may not matter for this assignment, but toolic and Discipulus do not exactly agree on what you mean by "randomly generate a number between 1 and 50". Toolic puts 50 balls in a hat and chooses five of them. Discipulus keeps putting each ball back in the hat before he draws again. One difference is that the first method has no possibility of drawing the same number twice.
    Bill
Re: Dice roll chances
by Anonymous Monk on Nov 11, 2017 at 21:17 UTC
    Homework!
      Yes, obviously, but the OP clearly states so, provides some code showing h(is|er) attempt to solve it and asks for directions on parts of the problem that s?he doesn't know how to solve. Nothing wrong here IMHO (except obviously for the poor formatting and lack of <code> and </code> tags).

      Homework! Into the lake with weights tied to his feed!

      «The Crux of the Biscuit is the Apostrophe»

      perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

        Yeah humans shouldnt eat feed it hurst your insides

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1203189]
Approved by toolic
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2024-04-24 06:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found