# is_gaussian_prime(z)?

### C, ~~149~~ 118 characters

Edited version (118 characters):

```
int G(int a,int b){a=abs(a);b=abs(b);int n=a*b?a*a+b*b:a+b,
d=2;for(;n/d/d&&n%d;d++);return n/d/d|n<2?0:(a+b&3)>2|a*b;}
```

This is a single function:

*G*(*a*,*b*) returns nonzero (true) if*a*+*bi*is a Gaussian prime, or zero (false) otherwise.

It folds the integer primality test into an expression `n/d/d|n<2`

hidden in the return value calculation. This golfed code also makes use of `a*b`

as a substitute for `a&&b`

(in other words `a!=0 && b!=0`

) and other tricks involving operator precedence and integer division. For example `n/d/d`

is a shorter way of saying `n/d/d>=1`

, which is an overflow-safe way of saying `n>=d*d`

or `d*d<=n`

or in essence `d<=sqrt(n)`

.

Original version (149 characters):

```
int Q(int n){int d=2;for(;n/d/d&&n%d;d++);return n/d/d||n<2;}
int G(int a,int b){a=abs(a);b=abs(b);return!((a|b%4<3|Q(b))*(b|a%4<3|Q(a))*Q(a*a+b*b));}
```

Functions:

*Q*(*n*) returns 0 (false) if*n*is prime, or 1 (true) if*n*is nonprime. It is a helper function for*G*(*a*,*b*).*G*(*a*,*b*) returns 1 (true) if*a*+*bi*is a Gaussian prime, or 0 (false) otherwise.

Sample output (scaled up 200%) for |*a*|,|*b*| ≤ 128:

## Haskell - 77/~~108~~107 Chars

usage: in both the solutions, typing a%b will return whether a+bi is a gaussian prime.

the lowest i managed, but no creativity or performance (77 chars)

```
p n=all(\x->rem n x>0)[2..n-1]
a%0=rem a 4==3&&p(abs a)
0%a=a%0
a%b=p$a^2+b^2
```

this solution just powers through all numbers below n to check if it's prime.

ungolfed version:

```
isprime = all (\x -> rem n x != 0) [2..n-1] -- none of the numbers between 2 and n-1 divide n.
isGaussianPrime a 0 = rem a 4==3 && isprime (abs a)
isGaussianPrime 0 a = isGaussianPrime a 0 -- the definition is symmetric
isGaussianPrime a b = isprime (a^2 + b^2)
```

the next solution has an extra feature - memoization. once you checked if some integer n is prime, you won't need to recalculate the "primeness" of all numbers smaller than or equal to n, as it will be stored in the computer.

(107 chars. the comments are for clarity)

```
s(p:x)=p:s[n|n<-x,rem n p>0] --the sieve function
l=s[2..] --infinite list of primes
p n=n==filter(>=n)l!!0 --check whether n is in the list of primes
a%0=rem a 4==3&&p(abs a)
0%a=a%0
a%b=p$a*a+b*b
```

ungolfed version:

```
primes = sieve [2..] where
sieve (p:xs) = p:filter (\n -> rem n p /= 0) xs
isprime n = n == head (filter (>=n) primes) -- checks if the first prime >= n is equal to n. if it is, n is prime.
isGaussianPrime a 0 = rem a 4==3 && isprime (abs a)
isGaussianPrime 0 a = isGaussianPrime a 0 -- the definition is symmetric
isGaussianPrime a b = isprime (a^2 + b^2)
```

this uses the sieve of Eratosthenes to compute an infinite list of all primes (called l for list in the code). (infinite lists are a well known trick of haskell).

how is it possible to have an infinite list? at the start of the program, the list is unevaluated, and instead of storing the lists elements, the computer stores the way to compute them. but as the program accesses the list it partially evaluates itself up to the request. so, if the program were to request the fourth item in the list, the computer would compute all primes up to the forth that aren't already evaluated, store them, and the rest would remain unevaluated, stored as the way to compute them once needed.

note that all of this is given freely by the lazy nature of the Haskell language, none of that is apparent from the code itself.

both versions of the program are overloaded, so they can handle arbitrarily-sized data.

## APL (Dyalog Unicode), ~~36~~ ~~47~~ ~~48~~ ~~49~~ ~~47~~ ~~43~~ 28 bytes

Takes an array of two integers `a b`

and returns the Boolean value of the statement `a+bi is a Gaussian integer`

.

**Edit:** +11 bytes because I misunderstood the definition of a Gaussian prime. +1 byte from correcting the answer again. +1 byte from a third bug fix. -2 bytes due to using a train instead of a dfn. -4 bytes thanks to ngn due to using a guard `condition: if_true ⋄ if_false`

instead of `if_true⊣⍣condition⊢if_false`

. -15 bytes thanks to ngn due to finding a completely different way to write the condition-if-else as a full train.

```
{2=≢∪⍵∨⍳⍵}|+.×0∘∊⊃|{⍺⍵}3=4||
```

Try it online!

### Explanation

```
{2=≢∪⍵∨⍳⍵}|+.×0∘∊⊃|{⍺⍵}3=4||
| ⍝ abs(a), abs(b) or abs(list)
3=4| ⍝ Check if a and b are congruent to 3 (mod 4)
|{⍺⍵} ⍝ Combine with (abs(a), abs(b))
0∘∊⊃ ⍝ Pick out the original abs(list) if both are non-zero
⍝ Else pick out (if 3 mod 4)
|+.× ⍝ Dot product with abs(list) returns any of
⍝ - All zeroes if neither check passed
⍝ - The zero and the number that IS 3 mod 4
⍝ - a^2 + b^2
{2=≢∪⍵∨⍳⍵} ⍝ Check if any of the above are prime, and return
```