develooper Front page | perl.perl6.language | Postings from April 2003

Re: Fun with multi-dimension arrays

Thread Previous | Thread Next
From:
Dave Whipp
Date:
April 26, 2003 19:59
Subject:
Re: Fun with multi-dimension arrays
Message ID:
20030427025913.15466.qmail@onion.perl.org
Luke Palmer relied:

> And second, that would be calling the key() method on whatever element
> $v was referring to.  You can do the .kv way above, or:
> 
>     for zip(@x, 0...) -> $k,$v {...}

I'll admit I hadn't thought of using zip of that: but I don't think it 
solves the general case: an N dimensional space with irregular boundary...

>>   for @x -> $v is keyed { print "$v.key = $v\n" }
>>
>>Presumably a keyed value could also have .prev and .next methods. 
>>Perhaps C<keyed> is spelt C<iterator>.
> 
> I'd rather not.  It's clear enough one of the other two ways.
> 
> I don't like delegation on the language level.  It can cause some
> really counterintuitive results (consider an array of pairs).

Yeah, you're right. Even with an explicit trait, its somewhat ungainly.

>>If we've got this far, what about 3-d arrays. Is It possible to iterate 
>>a 3-d grid without using nested loops?
> 
> Don't think so.
> 
> Not as if it would be hard to write a multidim() function that could
> behave like so:
> 
>     for multidim(@a1, @a2, @a3) -> $x,$y,$x { ... }
> 
> Especially with coroutines.

Yes, though perhaps not quite like that. Perhaps

   for @array_11d.fully_flat_iterator -> iter
   {
      my (@coord, $value) = iter.key, iter.value
   }

Where @cood would be an array of the 11 ordinates. This would also solve 
the irregular boundary case.

>>I think Ive got this right: both sides of the hyper-plus will 
>>dereference their arrays, and elements will be summed. Because the lhs 
>>is a junction, the result of the hyper operator will be a junction of 
>>corrdinates. I then .states that junction to get the neighborhood: an 
>>array of points
> 
> Wow.  Well done.

Thank you.

>>Having to write
>>
>>   @cell[$point[0]][$point[1]][$point[2]];
>>
>>could get stale somewhat quick.
> 
> True.  I think C<print @cell[$point]> would actually give you the 4th
> element of @cell, though.
> 
> Maybe we need a Key data type that will let you do that:
> 
>     my Key $point = [10, 3, 9];
> 
> Or some such thing.

Thinking about it, a simple @array.value_at(@coord) would solve the 
problem: no magic needed.

>>So lets assume it works. 
> Spoken like a true computer scientist :)

Damn, my reputation as an engineer is shot ;).

>>      my @new_grid is like @.grid;
>  
> Huh?  That's a syntax error.  Are you trying to copy it, or specify
> that the type is the same as @.grid's type?  I don't think we have a
> way of doing the latter, but I would assume:
> 
>         my @new_grid is typeof(@.grid);

What's a few parentheses amonst friends?

>>      for *@new_grid -> $cell is rw is keyed
>>      {
>>        $cell = .next_state($cell.key)
> 
> This calls .next_state on the current cell.   You need to say
> 
>           $cell = $self.next_state($cell.key)
> 
> It's a shame, too.

I can see that being a really common error. And not just for newbies :(.

>>      }
>>      @.grid = @new_grid;
> Hmm, something tells me this could be done a little more elegantly
> with hypotheticals. 

I'd like to see that. Can I temporise something just within the current 
routine, without the methods that I call seeing it? if so, then my GOL 
becomes

   method update
   {
      locally_hypothesise @.grid; # what keyword?

      for @.grid.fully_flat_iterator -> $iter
      {
         .value = $self.next_state(.key)
      }
   }

and next state will use the old values for @.grid:

   method next_state(@point)
   {
     [ -1|0|1 xx 2 ] & ! [0 xx 2]
         ==> states
         ==> map { @.grid.at($^coord >>+<< @point) }
         ==> sum
         ==> infix:== @.grid.at(@point) ?? 2|3 :: 3;
   }

And this code would be almost identical in a N-dimensional game-of-life: 
just a few constants would change. Very elegant. The only problem is 
that my life world would never grow: its boundary is fixed. I guess I 
just need the .sloppy_fully_flat_iterator(boundary_width=>1) operator. 
Yes, these continuation things should be very handy.

Dave.


>>It would be really cool if all this could really work. But I'm pretty 
>>sure it falls flat on its face somewhere along the road.
> 
> 
> Likely, but it's pretty close in any case.
> 
> Cool!
> 
> Luke


Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About