user
A Penrose tiling can cover an entire plane without creating a pattern that periodically repeats.

There are many tile sets that can create non-periodic tilings, but those can typically also be used to create a periodic
tiling. What makes Penrose tiles special is that they *can only be used to produce non-periodic tilings*.

The two best-known Penrose tile sets are `Kite and Dart (P2)` and `Thin Rhombus and Fat Rhombus (P3)`

These so-called prototiles are usually depicted with smooth edges, but in reality Penrose tiles have interlocking tabs
and cut-outs like the pieces of a jigsaw puzzle. For convenience these deformations are often replaced
with *matching rules*, which ensure that the tiles are only connected in ways that guarantee
a non-periodic tiling. (Otherwise, for instance, you could combine the kite and dart to form a rhombus,
and easily create a periodic tiling from there.)

You can construct a Penrose tiling by setting up some prototiles, and adding tiles through trial and error, backtracking whenever you get stuck.

More commonly a method is used that takes advantage of the fact that Penrose tilings, like fractals,
have a self-similarity on different levels. When zooming out it can be observed that groups of tiles are enclosed in areas that
form exactly the same pattern as the tiles on the lower level. Departing from an inflated level, the prototiles can be
subdivided into smaller tiles, always observing the matching rules. The subdivision may have to be repeated several times, before the desired level of detail is reached. This process is called deflation.

More information can be found through the links below.

**The task**: fill a rectangular area with a Penrose tiling.

See also

* A good introduction (ams.org)
* Deflation explained for both sets (tartarus.org)
* Deflation explained for Kite and Dart, includes Python code (preshing.com)
assistant
(formerly Perl 6)

**Works with**: Rakudo version 2018.05

Generated with a P3 tile set using a Lindenmayer system.

```
use SVG;

role Lindenmayer {
    has %.rules;
    method succ {
	    self.comb.map( { %!rules{$^c} // $c } ).join but Lindenmayer(%!rules)
    }
}

my $penrose = '[N]++[N]++[N]++[N]++[N]' but Lindenmayer(
    {
        A => '',
        M => 'OA++PA----NA[-OA----MA]++',
        N => '+OA--PA[---MA--NA]+',
        O => '-MA++NA[+++OA++PA]-',
        P => '--OA++++MA[+PA++++NA]--NA'
    }
);

$penrose++ xx 4;

my @lines;
my @stack;

for $penrose.comb {
    state ($x, $y) = 300, 200;
    state $d = 55 + 0i;
    when 'A' { @lines.push: 'line' => [:x1($x.round(.01)), :y1($y.round(.01)), :x2(($x += $d.re).round(.01)), :y2(($y += $d.im).round(.01))] }
    when '[' { @stack.push: ($x.clone, $y.clone, $d.clone) }
    when ']' { ($x, $y, $d) = @stack.pop }
    when '+' { $d *= cis -π/5 }
    when '-' { $d *= cis  π/5 }
    default { }
}

say SVG.serialize(
    svg => [
        :600width, :400height, :style<stroke:rgb(250,12,210)>,
        :rect[:width<100%>, :height<100%>, :fill<black>],
        |@lines,
    ],
);

```

See: Penrose tiling image