user
A Gaussian Integer is a complex number such that its real and imaginary parts are both integers.

```
   a + bi where a and b are integers and i is √-1.

```

The norm of a Gaussian integer is its product with its conjugate.

```
   N(a + bi) = (a + bi)(a − bi) = a² + b²

```

A Gaussian integer is a Gaussian prime if and only if either: both **a** and **b** are non-zero and its **norm** is a prime number, or, one of **a** or **b** is zero and it is the product of a unit **(±1, ±i)** and a prime integer of the form **4n + 3**.

Prime integers that are *not* of the form **4n + 3** can be factored into a Gaussian integer and its complex conjugate so are not a Gaussian prime.

```
   E.G. 5 = (2 + i)(2 − i) So 5 is not a Gaussian prime

```

Gaussian primes are octogonally symmetrical on a real / imaginary Cartesian field. If a particular complex norm **a² + b²** is prime, since addition is commutative, **b² + a²** is also prime, as are the complex conjugates and negated instances of both.

Task

Find and show, here on this page, the Gaussian primes with a norm of less than 100, (within a radius of 10 from the origin **0 + 0i** on a complex plane.)

Plot the points corresponding to the Gaussian primes on a Cartesian real / imaginary plane at least up to a radius of 50.

See also

* Wikipedia: Gaussian integers * Wikipedia: Gaussian primes * OEIS: Gaussian primes
assistant
Plotting the points up to a radius of 150.

```
use List::Divvy;

my @next = { :1x, :1y, :2n },;

sub next-interval (Int $int) {
     @next.append: (^$int).map: { %( :x($int), :y($_), :n($int² + .²) ) };
     @next = |@next.sort: *.<n>;
}

my @gaussian = lazy gather {
    my $interval = 1;
    loop {
        my @this = @next.shift;
        @this.push: @next.shift while @next and @next[0]<n> == @this[0]<n>;
        for @this {
            .take if .<n>.is-prime || (!.<y> && .<x>.is-prime && (.<x> - 3) %% 4);
            next-interval(++$interval) if $interval == .<x>
        }
    }
}

# Primes within a radius of 10 from origin
say "Gaussian primes with a norm less than 100 sorted by norm:";
say @gaussian.&before(*.<n> > 10²).map( {
     my (\i, \j) = .<x y>;
    flat ((i,j),(-i,j),(-i,-j),(i,-j),(j,i),(-j,i),(-j,-i),(j,-i)).map: {
        .[0] ?? .[1] ?? (sprintf "%d%s%di", .[0], (.[1] ≥ 0 ?? '+' !! ''), .[1]) !! .[0] !! "{.[1]}i"
    }} )».subst('1i', 'i', :g)».fmt("%6s")».unique.flat.batch(10).join: "\n" ;


# Plot points within a 150 radius
use SVG;

my @points = unique flat @gaussian.&before(*.<n> > 150²).map: {
    my (\i, \j) = .<x y>;
    do for (i,j),(-i,j),(-i,-j),(i,-j),(j,i),(-j,i),(-j,-i),(j,-i) {
        :use['xlink:href'=>'#point', 'transform'=>"translate({500 + 3 × .[0]},{500 + 3 × .[1]})"]
    }
}

'gaussian-primes-raku.svg'.IO.spurt: SVG.serialize(
    svg => [
        :width<1000>, :height<1000>,
        :rect[:width<100%>, :height<100%>, :style<fill:black;>],
        :defs[:g[:id<point>, :circle[:0cx, :0cy, :2r, :fill('gold')]]],
        |@points
    ],
);

```

Output:

```
Gaussian primes with a norm less than 100 sorted by norm:
   1+i   -1+i   -1-i    1-i    2+i   -2+i   -2-i    2-i   1+2i  -1+2i
 -1-2i   1-2i      3     -3     3i    -3i   3+2i  -3+2i  -3-2i   3-2i
  2+3i  -2+3i  -2-3i   2-3i    4+i   -4+i   -4-i    4-i   1+4i  -1+4i
 -1-4i   1-4i   5+2i  -5+2i  -5-2i   5-2i   2+5i  -2+5i  -2-5i   2-5i
   6+i   -6+i   -6-i    6-i   1+6i  -1+6i  -1-6i   1-6i   5+4i  -5+4i
 -5-4i   5-4i   4+5i  -4+5i  -4-5i   4-5i      7     -7     7i    -7i
  7+2i  -7+2i  -7-2i   7-2i   2+7i  -2+7i  -2-7i   2-7i   6+5i  -6+5i
 -6-5i   6-5i   5+6i  -5+6i  -5-6i   5-6i   8+3i  -8+3i  -8-3i   8-3i
  3+8i  -3+8i  -3-8i   3-8i   8+5i  -8+5i  -8-5i   8-5i   5+8i  -5+8i
 -5-8i   5-8i   9+4i  -9+4i  -9-4i   9-4i   4+9i  -4+9i  -4-9i   4-9i
```

Off-site SVG image: gaussian-primes-raku.svg