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

Of late I have been toying with writing game code. Traditionally, game programming is more difficult than roilling 'real world' solutions & I've been using it as a vehicle to drive my curiosity into new areas of exploration.

Most recently I've been toying with Two Dimensional arrays, for use with generating & storing maps. Below you will find a small piece of code meant to first populate a grid and then retrieve the results. This is more of an open ended question about technique rather than Golf, but I apprieciate anything you might share. My code is most obviously novice-esque. How do I go about making my code "Mo' Better"?

use strict; my @alpha = qw(a b c d e f g h i j k l m n o p q r s t u v w x y z); my $x=0; my $y=0; my @outtie; my ($xx, $yy, $S, $al, $ap); #INPUT foreach $_ (@alpha) { foreach $al (@alpha) { print "X = $x Y = $y "; $outtie[$x][$y] = $al; print "SET to $al\n"; $x++; } $y++; $x=0; } #OUTPUT $yy = 0; $xx = 0; while ($yy < 26) { $xx = 0; while ($xx < 26) { print " $outtie[$xx][$yy] "; $xx++; } print "\n"; $yy++; }


Wait! This isn't a Parachute, this is a Backpack!

Replies are listed 'Best First'.
Re: 2D arrays & mo' better blues
by japhy (Canon) on Jun 06, 2001 at 18:24 UTC
    You're treating Perl's arrays like C's arrays. Why not just assign to the array all at once?
    push @grid, [ @input ] for @input;
    If @input is qw( a b c d ), then this makes a 4x4 table:
    @grid = ( [ qw( a b c d ) ], [ qw( a b c d ) ], [ qw( a b c d ) ], [ qw( a b c d ) ], );
    Except it does it with far less effort. And printing is just as easy.
    print "@$_\n" for @grid;


    japhy -- Perl and Regex Hacker
(boo)Re: 2D arrays & mo' better blues
by boo_radley (Parson) on Jun 06, 2001 at 18:21 UTC
    OK, here's my suggestions : replace
    my @alpha = qw(a b c d e f g h i j k l m n o p q r s t u v w x y z);
    with
    my @alpha = ("a".."z");

    since it's smaller and more legible.

    using

    my $x=0; my $y=0;

    is redundant; my'd variables are set to 0/""/undef unless explicitly set otherwise.

    I'd also replace

    while ($yy < 26) { $xx = 0; while ($xx < 26) { print " $outtie[$xx][$yy] "; $xx++; } print "\n"; $yy++; }

    with

    foreach $yy (1..26) { foreach $xx (1..26) { print " $outtie[$xx][$yy] "; } print \n }
(ar0n) Re: 2D arrays & mo' better blues
by ar0n (Priest) on Jun 06, 2001 at 18:22 UTC
    It doesn't print what each x,y coordinate is set to, but it does the same as your code:
    use strict; my @alpha = ("a".."z"); my @outtie; # INPUT push @outtie, [ @alpha ] for @alpha; #OUTPUT print join(" ", @{$_}), "\n" for @outtie;

    <golf>
    @_=(['a'..'z'])x26; print"@$_\n"for@_;
    </golf>
    note to chipmunk Yes, that's true, but note the <golf> tags... :)

    ar0n ]

      @_=(['a'..'z'])x26;
      Careful! That creates @_ as a list of 26 references to the same array. If you change an element in any one of the rows, you'll have changed that element in every row.
      push @outtie, [ @alpha ] for @alpha;
      This snippet from your expanded solution is the preferred way to avoid this problem.
Re: 2D arrays & mo' better blues
by davorg (Chancellor) on Jun 06, 2001 at 18:27 UTC

    Something like this perhaps:

    use strict; my @alpha = 'a' .. 'z'; my @outtie; # INPUT $outtie[$_] = [@alpha] foreach 0 .. 25; #OUTPUT foreach my $x (@outtie) { foreach my $y (@$x) { print " $y "; } print "\n"; }
    --
    <http://www.dave.org.uk>

    "Perl makes the fun jobs fun
    and the boring jobs bearable" - me

Re: 2D arrays & mo' better blues
by bwana147 (Pilgrim) on Jun 06, 2001 at 18:32 UTC
    @alpha = 'a' .. 'z'; @outtie = ( [ @alpha ] ) x @alpha; foreach (@outtie) { print " $_ " foreach @$_; print "\n"; }

    Or even more cryptic

    @alpha = 'a' .. 'z'; @outtie = ( [ @alpha ] ) x @alpha; print join(' ', @$_) . "\n" foreach (@outtie)

    --bwana147

      One slight caveat with the way you set up the array. You'll end up with 26 references to the same array. Depending on what you're doing with the data, this may or may not be a problem. All of the other solutions I've seen create a copy of the array each time.

      --
      <http://www.dave.org.uk>

      "Perl makes the fun jobs fun
      and the boring jobs bearable" - me

        updated update: update removed

        from perldoc perldsc

          The square brackets make a reference to a new array with a *copy* of what's in @array at the time of the assignment. This is what you want.

        @outtie = ( [ @alpha ] ) x @alpha; looks ok to me.

        "Argument is futile - you will be ignorralated!"