user
|  |
| --- |
| This page uses content from **Wikipedia**. The original article was at Brownian\_tree. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance) |

Task

Generate and draw a   Brownian Tree.

A Brownian Tree is generated as a result of an initial seed, followed by the interaction of two processes.

1. The initial "seed" is placed somewhere within the field. Where is not particularly important; it could be randomized, or it could be a fixed point.
2. Particles are injected into the field, and are individually given a (typically random) motion pattern.
3. When a particle collides with the seed or tree, its position is fixed, and it's considered to be part of the tree.

Because of the lax rules governing the random nature of the particle's placement and motion, no two resulting trees are really expected to be the same, or even necessarily have the same general shape.
assistant
(formerly Perl 6)

This solution spawns new Particles at a growing square border and displays the Tree every 50 particles and at the end using unicode UPPER/LOWER HALF BLOCK and FULL BLOCK.

**Works with**: Rakudo version 2015.12

```
constant size = 100;
constant particlenum = 1_000;


constant mid = size div 2;

my $spawnradius = 5;
my @map;

sub set($x, $y) {
    @map[$x][$y] = True;
}

sub get($x, $y) {
    return @map[$x][$y] || False;
}

set(mid, mid);
my @blocks = " ","\c[UPPER HALF BLOCK]", "\c[LOWER HALF BLOCK]","\c[FULL BLOCK]";

sub infix:<█>($a, $b) {
    @blocks[$a + 2 * $b]
}

sub display {
    my $start = 0;
    my $end = size;
    say (for $start, $start + 2 ... $end -> $y {
        (for $start..$end -> $x {
            if abs(($x&$y) - mid) < $spawnradius {
                get($x, $y) █ get($x, $y+1);
            } else {
                " "
            }
        }).join
    }).join("\n")
}

for ^particlenum -> $progress {
    my Int $x;
    my Int $y;
    my &reset = {
        repeat {
            ($x, $y) = (mid - $spawnradius..mid + $spawnradius).pick, (mid - $spawnradius, mid + $spawnradius).pick;
            ($x, $y) = ($y, $x) if (True, False).pick();
        } while get($x,$y);
    }
    reset;

    while not get($x-1|$x|$x+1, $y-1|$y|$y+1) {
        $x = ($x-1, $x, $x+1).pick;
        $y = ($y-1, $y, $y+1).pick;
        if (False xx 3, True).pick {
            $x = $x >= mid ?? $x - 1 !! $x + 1;
            $y = $y >= mid ?? $y - 1 !! $y + 1;
        }
        if abs(($x | $y) - mid) > $spawnradius {
            reset;
        }
    }
    set($x,$y);
    if $spawnradius < mid && abs(($x|$y) - mid) > $spawnradius - 5 {
        $spawnradius = $spawnradius + 1;
    }
}

display;

```