user
Our sandpiles are based on a 3 by 3 rectangular grid giving nine areas that
contain a number from 0 to 3 inclusive. (The numbers are said to represent
grains of sand in each area of the sandpile).

E.g. `s1` =

```
    
    1 2 0
    2 1 1
    0 1 3

```

and `s2` =

```
    2 1 3
    1 0 1
    0 1 0

```

Addition on sandpiles is done by adding numbers in corresponding grid areas,
so for the above:

```
              1 2 0     2 1 3     3 3 3
    s1 + s2 = 2 1 1  +  1 0 1  =  3 1 2
              0 1 3     0 1 0     0 2 3

```

If the addition would result in more than 3 "grains of sand" in any area then
those areas cause the whole sandpile to become "unstable" and the sandpile
areas are "toppled" in an "avalanche" until the "stable" result is obtained.

Any unstable area (with a number >= 4), is "toppled" by loosing one grain of
sand to each of its four horizontal or vertical neighbours. Grains are lost
at the edge of the grid, but otherwise increase the number in neighbouring
cells by one, whilst decreasing the count in the toppled cell by four in each
toppling.

A toppling may give an adjacent area more than four grains of sand leading to
a chain of topplings called an "avalanche".
E.g.

```
    
    4 3 3     0 4 3     1 0 4     1 1 0     2 1 0
    3 1 2 ==> 4 1 2 ==> 4 2 2 ==> 4 2 3 ==> 0 3 3
    0 2 3     0 2 3     0 2 3     0 2 3     1 2 3

```

The final result is the stable sandpile on the right.

**Note:** The order in which cells are toppled does not affect the final result.

Task

* Create a class or datastructure and functions to represent and operate on sandpiles.
* Confirm the result of the avalanche of topplings shown above
* Confirm that s1 + s2 == s2 + s1 # Show the stable results
* If s3 is the sandpile with number 3 in every grid area, and s3\_id is the following sandpile:

```
    2 1 2  
    1 0 1  
    2 1 2

```

* Show that `s3 + s3_id == s3`
* Show that `s3_id + s3_id == s3_id`

Show confirming output here, with your examples.

References

* https://www.youtube.com/watch?v=1MtEUErz7Gg
* https://en.wikipedia.org/wiki/Abelian\_sandpile\_model
assistant
**Works with**: Rakudo version 2020.05

Most of the logic is lifted straight from the Abelian sandpile model task.

```
class ASP {
    has $.h = 3;
    has $.w = 3;
    has @.pile = 0 xx $!w * $!h;

    method topple {
        my $buf = $!w * $!h;
        my $done;
        repeat {
            $done = True;
            loop (my int $row; $row < $!h; $row = $row + 1) {
                my int $rs = $row * $!w; # row start
                my int $re = $rs  + $!w; # row end
                loop (my int $idx = $rs; $idx < $re; $idx = $idx + 1) {
                    if self.pile[$idx] >= 4 {
                        my $grain = self.pile[$idx] div 4;
                        self.pile[ $idx - $!w ] += $grain if $row > 0;
                        self.pile[ $idx - 1  ]  += $grain if $idx - 1 >= $rs;
                        self.pile[ $idx + $!w ] += $grain if $row < $!h - 1;
                        self.pile[ $idx + 1  ]  += $grain if $idx + 1 < $re;
                        self.pile[ $idx ] %= 4;
                        $done = False;
                    }
                }
            }
        } until $done;
        self.pile;
    }
}

# some handy display layout modules
use Terminal::Boxer:ver<0.2+>;
use Text::Center;

for 3, (4,3,3,3,1,2,0,2,3), (2,1,2,1,0,1,2,1,2), # 3 square task example
    3, (2,1,2,1,0,1,2,1,2), (2,1,2,1,0,1,2,1,2), # 3 square identity
    5, (4,1,0,5,1,9,3,6,1,0,8,1,2,5,3,3,0,1,7,5,4,2,2,4,0), (2,3,2,3,2,3,2,1,2,3,2,1,0,1,2,3,2,1,2,3,2,3,2,3,2) # 5 square test
  -> $size, $pile, $identity {

    my $asp = ASP.new(:h($size), :w($size));

    $asp.pile = |$pile;

    my @display;

    my %p = :col($size), :3cw, :indent("\t");

    @display.push: rs-box |%p, |$identity;

    @display.push: rs-box |%p, $asp.pile;

    @display.push: rs-box |%p, $asp.topple;

    $asp.pile Z+= $identity.list;

    @display.push: rs-box |%p, $asp.pile;

    @display.push: rs-box |%p, $asp.topple;

    put %p<indent> ~ qww<identity 'test pile' toppled 'plus identity' toppled>».&center($size * 4 + 1).join: %p<indent>;

    .put for [Z~] @display».lines;

    put '';
}

```

Output:

```
	   identity  	  test pile  	   toppled   	plus identity	   toppled   
	╭───┬───┬───╮	╭───┬───┬───╮	╭───┬───┬───╮	╭───┬───┬───╮	╭───┬───┬───╮
	│ 2 │ 1 │ 2 │	│ 4 │ 3 │ 3 │	│ 2 │ 1 │ 0 │	│ 4 │ 2 │ 2 │	│ 2 │ 1 │ 0 │
	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤
	│ 1 │ 0 │ 1 │	│ 3 │ 1 │ 2 │	│ 0 │ 3 │ 3 │	│ 1 │ 3 │ 4 │	│ 0 │ 3 │ 3 │
	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤
	│ 2 │ 1 │ 2 │	│ 0 │ 2 │ 3 │	│ 1 │ 2 │ 3 │	│ 3 │ 3 │ 5 │	│ 1 │ 2 │ 3 │
	╰───┴───┴───╯	╰───┴───┴───╯	╰───┴───┴───╯	╰───┴───┴───╯	╰───┴───┴───╯

	   identity  	  test pile  	   toppled   	plus identity	   toppled   
	╭───┬───┬───╮	╭───┬───┬───╮	╭───┬───┬───╮	╭───┬───┬───╮	╭───┬───┬───╮
	│ 2 │ 1 │ 2 │	│ 2 │ 1 │ 2 │	│ 2 │ 1 │ 2 │	│ 4 │ 2 │ 4 │	│ 2 │ 1 │ 2 │
	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤
	│ 1 │ 0 │ 1 │	│ 1 │ 0 │ 1 │	│ 1 │ 0 │ 1 │	│ 2 │ 0 │ 2 │	│ 1 │ 0 │ 1 │
	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤	├───┼───┼───┤
	│ 2 │ 1 │ 2 │	│ 2 │ 1 │ 2 │	│ 2 │ 1 │ 2 │	│ 4 │ 2 │ 4 │	│ 2 │ 1 │ 2 │
	╰───┴───┴───╯	╰───┴───┴───╯	╰───┴───┴───╯	╰───┴───┴───╯	╰───┴───┴───╯

	       identity      	      test pile      	       toppled       	    plus identity    	       toppled       
	╭───┬───┬───┬───┬───╮	╭───┬───┬───┬───┬───╮	╭───┬───┬───┬───┬───╮	╭───┬───┬───┬───┬───╮	╭───┬───┬───┬───┬───╮
	│ 2 │ 3 │ 2 │ 3 │ 2 │	│ 4 │ 1 │ 0 │ 5 │ 1 │	│ 1 │ 3 │ 2 │ 1 │ 0 │	│ 3 │ 6 │ 4 │ 4 │ 2 │	│ 1 │ 3 │ 2 │ 1 │ 0 │
	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤
	│ 3 │ 2 │ 1 │ 2 │ 3 │	│ 9 │ 3 │ 6 │ 1 │ 0 │	│ 2 │ 2 │ 3 │ 3 │ 1 │	│ 5 │ 4 │ 4 │ 5 │ 4 │	│ 2 │ 2 │ 3 │ 3 │ 1 │
	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤
	│ 2 │ 1 │ 0 │ 1 │ 2 │	│ 8 │ 1 │ 2 │ 5 │ 3 │	│ 1 │ 1 │ 2 │ 0 │ 3 │	│ 3 │ 2 │ 2 │ 1 │ 5 │	│ 1 │ 1 │ 2 │ 0 │ 3 │
	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤
	│ 3 │ 2 │ 1 │ 2 │ 3 │	│ 3 │ 0 │ 1 │ 7 │ 5 │	│ 2 │ 0 │ 3 │ 2 │ 0 │	│ 5 │ 2 │ 4 │ 4 │ 3 │	│ 2 │ 0 │ 3 │ 2 │ 0 │
	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤	├───┼───┼───┼───┼───┤
	│ 2 │ 3 │ 2 │ 3 │ 2 │	│ 4 │ 2 │ 2 │ 4 │ 0 │	│ 3 │ 2 │ 3 │ 2 │ 1 │	│ 5 │ 5 │ 5 │ 5 │ 3 │	│ 3 │ 2 │ 3 │ 2 │ 1 │
	╰───┴───┴───┴───┴───╯	╰───┴───┴───┴───┴───╯	╰───┴───┴───┴───┴───╯	╰───┴───┴───┴───┴───╯	╰───┴───┴───┴───┴───╯

```