XP is just a number PerlMonks

Generate a # between 1 and 50 in groups of 5

by Hayest (Acolyte)
 on Jan 30, 2015 at 18:45 UTC Need Help??

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

Hello, as the title states, I'm trying to get a Perl program to generate a number between 1 and 50 in groups of 5. This is for a school assignment, and I'm wondering where I need to go next (I am a beginner with Perl and programming in general). Here is what I have so far:

```#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'shuffle';

my @numbers = (1 .. 50);

print shuffle(@numbers);

I was able to find the 'shuffle' utility which works to print my whole array (with numbers between 1 and 50). Now I know how to create a for loop which would go through each number in the array and print on a new line:

```for (\$i = 0; \$i < @numbers; ++\$i) { ... }

What I want to know is how would I get it to pick five of the numbers inside of it, and print them each on a new line (5 new lines with a number between 50 on each line), line break, print 5 more, line break, etc. I want the program to terminate after it does this for 5 cycles. Any thoughts? Any help would be much appreciated!!!

Replies are listed 'Best First'.
Re: Generate a # between 1 and 50 in groups of 5
by GrandFather (Saint) on Jan 30, 2015 at 22:18 UTC

Turn the problem inside out: you want to print five groups of five numbers. That's the way you need to structure your nested loops.

You already have a random list of numbers so you can pull numbers off the front of the list 5 at a time using splice. So putting those together (with another small wrinkle) we get:

```#!/usr/bin/perl
use strict;
use warnings;
use List::Util 'shuffle';

my @numbers = shuffle(1 .. 50);

for (1 .. 5) {
my @group = splice @numbers, 0, 5;

print "\$_\n" for @group;
print "\n";
}

The small wrinkle is the for @group "statement modifier" which is the nested loop that prints out the individual numbers in each group.

Note that to loop five time in Perl we can use for (1 .. 5) instead of the unwieldy and error prone C loop. The intent of the Perl loop is much clearer and much easier te get right.

Perl is the programming world's equivalent of English
Re: Generate a # between 1 and 50 in groups of 5
by Not_a_Number (Prior) on Jan 30, 2015 at 22:15 UTC

Here's yet another way. The difference is that it will avoid duplicates of a given number in your "groups of 5."

```use List::Util 'shuffle';

my @shuffled = shuffle ( 1 .. 50 );

print join ' ', splice( @shuffled, 0, 5 ), "\n" for 1 .. 5;
Re: Generate a # between 1 and 50 in groups of 5
by choroba (Archbishop) on Jan 30, 2015 at 20:24 UTC
You are almost there. You can use the % operator (modulus) to find each fifth number. If modulus 5 returns 4, output a newline, otherwise, output a space:
```#! /usr/bin/perl
use strict;
use warnings;

use List::Util qw{ shuffle };

my @numbers = shuffle(1 .. 50);
for my \$index (0 .. \$#numbers) {                          # replace wi
+th 0 .. 25 to stop after 5 lines.
print \$numbers[\$index], \$index % 5 == 4 ? "\n" : ' ';
}
لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Generate a # between 1 and 50 in groups of 5
by karlgoethebier (Abbot) on Jan 30, 2015 at 19:07 UTC

Do you mean this?

```#!/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;
}

__END__

karls-mac-mini:monks karl\$ ./1115111.pl
30 26 3 46 23
10 45 47 1 39
8 11 19 49 36
15 22 29 37 18
13 50 44 25 42

Update: A variation:

```my \$iterator = natatime 5, shuffle( 1 .. 50 );
my @takatakina = map { [ \$iterator->() ] } 1 .. 5;

say join " ", @{\$_} for @takatakina;

"Takatakina" is the Konnakol way to count to five. German musicians count "Ein Glas Bier für mich" - because of Take 5 mentioned below ;-)

Best regards, Karl

«The Crux of the Biscuit is the Apostrophe»

The  \$count counter is not needed because the  natatime() iterator is exhausted after completely iterating over its list. (Such a counter would be needed if you wanted to stop short of iterator exhaustion.)

```c:\@Work\Perl>perl -wMstrict -le
"use List::Util 'shuffle';
use List::MoreUtils qw(natatime);
;;
my \$iterator = natatime 5, shuffle 1 .. 50;
;;
while (my @five = \$iterator->()) {
print qq{@five};
}
;;
print '---------';
while (my @five =  \$iterator->()) { print qq{@five}; }
"
47 16 22 40 27
14 8 35 36 21
46 43 9 42 17
31 2 18 33 24
11 1 44 7 3
38 49 41 25 39
15 37 29 12 5
23 45 10 6 26
20 19 28 50 34
32 13 4 30 48
---------

Give a man a fish:  <%-(-(-(-<

The OP wrote:

"I want the program to terminate after it does this for 5 cycles"

You wrote:

"..if you wanted to stop short..."

That's what i wanted. My output:

```karls-mac-mini:monks karl\$ ./1115111.pl
30 26 3 46 23
10 45 47 1 39
8 11 19 49 36
15 22 29 37 18
13 50 44 25 42

This are five cycles with five numbers.

Please correct me if i miss something.

Update: But i I surrender:

Alternate version:

```
for ( 1 .. 5 ) {
my @five = \$iterator->();
say join " ", @five;
}

Best regards, Karl

«The Crux of the Biscuit is the Apostrophe»

Re: Generate a # between 1 and 50 in groups of 5
by BrowserUk (Patriarch) on Jan 31, 2015 at 05:33 UTC

Another "take 5" everybody! (P6 in-joke :):

```@a = shuffle 1 .. 50;
print splice @a, 0, 5 for 1 .. 5;;
7 15 32 24 41
50 22 25 21 28
11 3 45 48 44
42 30 10 36 38
17 26 2 18 33

@a = shuffle 1 .. 50;
print splice @a, 0, 5 for 1 .. 5;;
11 31 48 5 44
25 39 3 40 34
33 16 14 47 49
17 41 37 4 42
50 20 13 24 45

@a = shuffle 1 .. 50;
print splice @a, 0, 5 for 1 .. 5;;
9 6 31 35 7
29 37 36 26 22
32 3 8 1 2
4 21 45 40 43
23 18 30 50 42

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". I'm with torvalds on this
In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked
Re: Generate a # between 1 and 50 in groups of 5
by BillKSmith (Monsignor) on Jan 31, 2015 at 16:01 UTC

There is a subtle difference between generating five random numbers and selecting the first five of a randomly ordered set. (The former allows the possibility of duplicates.) Your text implies the former while your code implies the latter. Here is code for the former.

```use strict;
use warnings;
printf "%2d\n", 1 + int(rand 50) for (1..5);

UPDATE: Changed 'code' to 'text' as pointed out by GrandFather.

Bill
Re: Generate a # between 1 and 50 in groups of 5
by pme (Monsignor) on Jan 30, 2015 at 19:02 UTC
Hi Hayest, welcome to the monastery.

Random numbers can be generated using rand() function (see rand). This short script below prints 5 random numbers between 1 and 50. The group of numbers is sorted.

```#!/usr/bin/perl -w

use strict;

my %num;

while ((keys %num) < 5) {
\$num{int(rand(50)+1)} = 1;
}

print join(' ' , sort {\$a <=> \$b} keys %num) . "\n";
pme,

This is exactly what I was looking to do. Now we are tasked with something additional: "Sum each group and display the results so that each number is on its own line." How would I go about doing something like this? Would I need to implement some sort of do/while or for/next loop?

Thank you in advance!
> How would I go about doing something like this?

perlintro is a good entry point to learn programing!

Cheers Rolf

PS: Je suis Charlie!

Re: Generate a # between 1 and 50 in groups of 5
by Anonymous Monk on Feb 02, 2015 at 11:59 UTC
```printf \$_ == 5 ? "%2d\n" : "%2d ", int rand(50)+1 for (1..5) x 5;

Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1115111]
Approved by GrandFather
Front-paged by blindluke
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (6)
As of 2022-01-28 16:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
Voting Booth?
In 2022, my preferred method to securely store passwords is:

Results (73 votes). Check out past polls.

Notices?