6. Functions Operating on Arrays or Lists


1. A (push-down pop-up) stack is a data storage unit that has new 
	information added at the end.  When information is removed, it is taken 
	from that same end. This is also known as a last in, first out stack (LIFO).  
	The push()  function is used in Perl to add data to the end of an 
	array and the pop() function is used to remove data from the end 
	of the array.

   A (push through) queue is a data storage unit that has new items 
   at the end, and taking items out from the beginning. This is also known as 
   first in, first out queue (FIFO).  
   
   Whenever any perl program runs, an array called @ARGV is automatically
   defined for your use.  It holds the value of any command line arguments.
   
   (a). Write a perl program that will output its arguments (make sure to give 
   		  it some) in left to right order, as if it is a queue.
   		  
   (b). Write a perl program that will output its arguments in reverse order 
   		  as if it is a stack.
   		  
2. Run the following program to see what it outputs.

	#! /usr/bin/perl
	@heroes = qw(ruth mantle maris)
	print "size of \@heroes: ", scalar(@heroes), "   "; 	# print array size
	print "highest index: $#heroes     ";  # print highest array subscript (index)
	print ""last element: $heroes[$#heroes]\n\n";
	
	push (@heroes, "sosa");
	print "size of \@heroes: ", scalar(@heroes), "   "; 	# print array size
	print "highest index: $#heroes     ";  # print highest array subscript (index)
	print ""last element: $heroes[$#heroes]\n\n";

	$youngest = pop @heroes;
	print "popped the word [$youngest] from \@heroes\n";
	print "size of \@heroes: ", scalar(@heroes), "   "; 	# print array size
	print "highest index: $#heroes     ";  # print highest array subscript (index)
	print ""last element: $heroes[$#heroes]\n\n";
	
	(a). In the above program, write a simple foreach() loop that would print
		the array elements in a readable fashion (lines 3-5).
		
	(b). In the above program, rewrite the last four lines as one print statement
		and include a loop to emit the entire contents of the @heroes array.
		
3. The following program provides names that are in a given order and outputs
	them in reverse order.
	
	#! /usr/bin/perl
	@players = qw(bob wayne ellen sylvia phil);
	
	$order = 1;
	print "Players finished in this order: \n";
	foreach $p (@players) {
		print $order++, ":  $p\n";
		push (@drill, $p);
	}
	print "\n";
	
	$order = 1;
	print qq(list them in reverse order: \n);
	foreach (@players) {
		$next = pop @drill;
		print $order++, ": $next\n";
	}
	
	(a). Rewrite the program above so that @drill's contents is output in order
	instead.
	
	(b). Rewrite the program above so that it uses unshift() to put information
	into the stack (into @drill).
	
4. Run the program Queue1.pl to see what happens.

	#! /usr/bin/perl
	@heroes = qw(ruth mantle maris)
	print "size: ",  scalar(@heroes), "\n"; 
	foreach (@heroes) { print "$_ " } print "\n";
	
	push (@heroes,  "sosa";)
	print "size: ",  scalar(@heroes), "\n";
	foreach (@heroes) { print "$_ " } print "\n";
	
	$oldest = shift @heroes;
	print "shifted the word [$oldest] from \@heroes\n";
	print "size: ",  scalar(@heroes), "\n";
	foreach (@heroes) { print "$_ " } print "\n";
	# END OF Queue1.pl
	
5. Run the following program to see what happens:

	#! /usr/bin/perl
	@players = qw(bob wayne ellen sylvia phil);
	
	foreach $p (@players) {
		print "$p just arrived, adding to list\n";
		push (@batters, $player);
	}
	
	foreach $batter (0..$#players) {
		$next = shift @batters;
		print Time for $next to bat/n";
	}
	
	(a) There are at least two errors in the above program. What are they?
	
	(b) Rewrite the program to fix the errors.
	
	(c). Would the 2nd foreach line work if written as:
			foreach $batter (1..scalar(@players)) {
			
6. Using the command line arguments array (@ARGV) and a loop, write
	a program to print the arguments in reverse order from their left to
	right appearance on the command line.
	
7. Run the following program and see what it does:

	#! /usr/bin/perl
	@innerdata = qw(
		Mercury 57.9 4880
		Venus	108.2 12100
		Earth 149.6 12756
		Mars 227.9 6794
	);
	
	print "Here comes the whole array ...\n";
	foreach (@innerdata) { print "$_\n"} print "\n";
	
	while ($planet = shift @innerdata) {
		$odistance = shift @innerdata;
		$diameter = shift @innerdata;
		$planetstats = join ":", ($planet, $odistance, $diameter);
		push (@ptable, $planetstats);
	}
	
	print "Here comes the consolidated table...\n";
	foreach (@ptable) { print "$_\n" } print "\n";
	
	(a). On the line where $planetstats is defined, the program pastes
		together 3 scalar values into one string. On the second iteration,
		what should $planetstats look like after it is executed and before
		the push function is executed?
		
	(b). How might the program be rewritten so that the planets
		could be sorted according to orbital distance?
		
8. The splice function takes up to four arguments (The rightmost 2 are
	optional:      splice (ARRAY, OFFSET, LENGTH, LIST)
	If LIST is missing, no elements are substituted and LENGTH elements
	are removed starting from the OFFSET.  If LENGTH is also missing,
	all elements from OFFSET to the end of the array are removed.
	
	Rewrite the program in question 7 to use splice() instead of the 3
	shift() statements.
	
IF IT DOESN'T WORK:

1. (a) one solution is as follows:

	#! /usr/bin/;perl
	$count = 1;
	foreach $arg (@ARGV) {
		print $count++, ". $arg\n";
	}
	
	(b) one solution is as follows:
	
	#! /usr/bin/perl
	while ($arg = pop @argv)	{
		print "$arg \n";
	}

2.  In Question 2 (a) One solution is: 	
      foreach (@heroes) { print "$_ "}
      print "Array size: ", scalar(@heroes), "\n";
									    
    In Question 2 (b) One solution is:		
      print " 
      popped the word [$youngest] from \@heroes
      size of \@heroes: ",scalar(@heroes),"
      highest index: $#heroes
      last element: $heroes[$#heroes]\n\n";

3.  One solution to Question 3 is:

	#! /usr/bin/perl
	@players = qw(bob wayne ellen sylvia phil);
	
	$order = 1;
	print "Players finished in this order: \n";
	foreach $p (@players) {
		print $order++, ":  $p\n";
		unshift (@drill, $p);
	}
	print "\n";
	
	$order = 1;
	print qq(list them in reverse order: \n);
	foreach  $p (@drill) {
		print $order++, ": $p\n";
	}
		
4. In Question 5 (a), The bugs in this program are on line 6, 
instead of pushing $p onto the queue, the program pushes 
an uninitialized variable $player. The print statement on 
line 11 has a forward slash in front of n rather than a \.  The
scalar variable $batter is never used.
	The program as repaired looks like:
	
	#! /usr/bin/perl
	@players = qw(bob wayne ellen sylvia phil);
	
	foreach $p (@players) {
		print "$p just arrived, adding to list\n";
		push (@batters, $p);
	}
	
	foreach (0..$#players) {
		$next = shift @batters;
		print Time for $next to bat\n";
	}

5. In Question 6, one solution is:
	#! /usr/bin/perl
	while ($a = pop @ARGV) 	{
		print "last argument is $a\n";
	}
	
6. In Question 7, one solution is:

	#! /usr/bin/perl
	@innerdata = qw(
		Mercury 57.9 4880
		Venus	108.2 12100
		Earth 149.6 12756
		Mars 227.9 6794
	);
	
	print "Here comes the whole array ...\n";
	foreach (@innerdata) { print "$_\n"} print "\n";
	
	while ($planet = shift @innerdata) {
		$odistance = shift @innerdata;
		$diameter = shift @innerdata;
		$planetstats = join ":", ($odistance, $planet, $diameter);	#Reorder these
		push (@ptable, $planetstats);
	}
	
	print "Here comes the consolidated table...\n";
	foreach (@ptable) { print "$_\n" } print "\n";
	
	$, = "\n";	# each element of the array on a new line
	print "Here comes the sorted table...\n";
	print sort { (split ":", $a)[0] <=> (split ":", $b)[0] } @ptable;
	print "\n";
	
	print "Sorted by diameter...\n";
	print sort { (split ":", $a)[2] <=> (split ":", $b)[2] } @ptable;
	print "\n";
	
7. In Question 8, one solution is:

	#! /usr/bin/perl
	@innerdata = qw(
		Mercury 57.9 4880
		Venus	108.2 12100
		Earth 149.6 12756
		Mars 227.9 6794
	);
	
	print "Here comes the whole array ...\n";
	foreach (@innerdata) { print "$_\n"} print "\n";
	
	while ( scalar(@innerdata) > 0 ) {
		@pdata = splice (@innerdata, 0, 3);
		$planetstats = join (":", @pdata);
		push (@ptable, $planetstats);
	}
	
	print "Here comes the consolidated table...\n";
	foreach (@ptable) { print "$_\n" } print "\n";

Questions about the questions? Send mail to Robert Katz: rkatz@ned.highline.ctc.edu
Last Update January 26, 2002