Eisenstein primes: Difference between revisions

m (→‎{{header|Raku}}: deleted!)
Tag: Manual revert
 
(6 intermediate revisions by 5 users not shown)
Line 62:
'marker; markersize 0.3' plot eisensteinprimes 2000</syntaxhighlight>
[[File:J-2000-eisenstein-primes.png]]
 
=={{header|jq}}==
'''Works with jq, the C implementation of jq'''
 
'''Works with gojq, the Go implementation of jq'''
 
'''Adapted from [[#Wren|Wren]]'''
 
In this entry, complex numbers are represented as arrays of pairs: [real, complex],
as in the [[Arithmetic/Complex#jq | jq section on the Complex page]].
The two functions for adding and multiplying complex numbers presented
there are reproduced below so that the program presented here is self-contained.
 
For the "stretch" task, we assume the availability of a tool such as gnuplot;
using gnuplot, a suitable sequence of commands to plot the points produced by `graph`
as defined below would be as follows:
<pre>
reset
set terminal pngcairo
set output "eisenstein-primes.png"
</pre>
<syntaxhighlight lang="jq">
### Complex numbers
def plus(x; y):
if (x|type) == "number" then
if (y|type) == "number" then [ x+y, 0 ]
else [ x + y[0], y[1]]
end
elif (y|type) == "number" then plus(y;x)
else [ x[0] + y[0], x[1] + y[1] ]
end;
def multiply(x; y):
if (x|type) == "number" then
if (y|type) == "number" then [ x*y, 0 ]
else [x * y[0], x * y[1]]
end
elif (y|type) == "number" then multiply(y;x)
else [ x[0] * y[0] - x[1] * y[1], x[0] * y[1] + x[1] * y[0]]
end;
 
### Generic utilities
 
def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;
 
# Require $n > 0
def nwise($n):
def _n: if length <= $n then . else .[:$n] , (.[$n:] | _n) end;
if $n <= 0 then "nwise: argument should be non-negative" else _n end;
 
def is_prime:
. as $n
| if ($n < 2) then false
elif ($n % 2 == 0) then $n == 2
elif ($n % 3 == 0) then $n == 3
elif ($n % 5 == 0) then $n == 5
elif ($n % 7 == 0) then $n == 7
elif ($n % 11 == 0) then $n == 11
elif ($n % 13 == 0) then $n == 13
elif ($n % 17 == 0) then $n == 17
elif ($n % 19 == 0) then $n == 19
else sqrt as $s
| 23
| until( . > $s or ($n % . == 0); . + 2)
| . > $s
end;
 
def OMEGA: [-0.5, (3|sqrt * 0.5)];
 
### Eisenstein numbers and Eisenstein primes
 
def Eisenstein($a; $b):
{$a, $b, n: plus( multiply(OMEGA;$b); $a) };
 
def realEisenstein: .n[0];
def imagEisenstein: .n[1];
def normEisenstein:
.a *.a - .a * .b + .b * .b ;
 
# Replicate the Julia sort order for easy comparison
def sortEisenstein:
sort_by( [ normEisenstein, imagEisenstein, realEisenstein] );
 
def isPrimeEisenstein:
if .a == 0 or .b == 0 or .a == .b
# length ~ abs
then ([.a, .b] | map(length) | max) as $c
| ($c | is_prime) and $c % 3 == 2
else normEisenstein | is_prime
end;
 
# Eisenstein($i;$j) primes for $i and $j in -$n .. $n inclusive
def eprimes($n):
reduce range (-$n; $n+1) as $a ([];
reduce range ( -$n; $n+1) as $b (.;
Eisenstein($a; $b) as $e
| if $e | isPrimeEisenstein
then . + [$e]
else .
end ));
 
### The tasks
 
# pretty-print a complex number
def pp:
def r: 100 * . | trunc / 100;
.[2] = (if .[1] < 0 then "-" else "+" end)
| .[1] |= (if . < 0 then -. else . end)
| "\(.[0]|r|lpad(5)) \(.[2]) \(.[1]|r|lpad(5))i";
 
# Display the input array of complex numbers as a table with $n columns
# proceeding row-wise and using pp/0
def row_wise($n):
nwise($n) | map( pp ) | join(" ");
 
def listing:
{eprimes: (eprimes(10) | sortEisenstein) }
# convert to Complex numbers for easy display
| .eprimes |= map( .n )
| "First 100 Eisenstein primes nearest zero:",
(.eprimes[:100] | row_wise(4) );
 
def graph:
eprimes(100)
| sortEisenstein
| .[:2000][]
| .n
| "\(real(.)) \(imag(.))";
 
# For a listing of the first 100 Eisenstein primes nearest 0:
listing
 
# To produce the points for gnuplot:
# graph
</syntaxhighlight>
{{output}}
The results of `listing` are shown below.
For the graph of the output produced by `graph`, see the graph shown above at [[#J|J]].
<pre>
First 100 Eisenstein primes nearest zero:
0 - 1.73i -1.5 - 0.86i 1.5 - 0.86i -1.5 + 0.86i
1.5 + 0.86i 0 + 1.73i -1 - 1.73i 1 - 1.73i
-2 + 0i 2 + 0i -1 + 1.73i 1 + 1.73i
-0.5 - 2.59i 0.5 - 2.59i -2 - 1.73i 2 - 1.73i
-2.5 - 0.86i 2.5 - 0.86i -2.5 + 0.86i 2.5 + 0.86i
-2 + 1.73i 2 + 1.73i -0.5 + 2.59i 0.5 + 2.59i
-1 - 3.46i 1 - 3.46i -2.5 - 2.59i 2.5 - 2.59i
-3.5 - 0.86i 3.5 - 0.86i -3.5 + 0.86i 3.5 + 0.86i
-2.5 + 2.59i 2.5 + 2.59i -1 + 3.46i 1 + 3.46i
-0.5 - 4.33i 0.5 - 4.33i -3.5 - 2.59i 3.5 - 2.59i
-4 - 1.73i 4 - 1.73i -4 + 1.73i 4 + 1.73i
-3.5 + 2.59i 3.5 + 2.59i -0.5 + 4.33i 0.5 + 4.33i
-2.5 - 4.33i 2.5 - 4.33i -5 + 0i 5 + 0i
-2.5 + 4.33i 2.5 + 4.33i -2 - 5.19i 2 - 5.19i
-3.5 - 4.33i 3.5 - 4.33i -5.5 - 0.86i 5.5 - 0.86i
-5.5 + 0.86i 5.5 + 0.86i -3.5 + 4.33i 3.5 + 4.33i
-2 + 5.19i 2 + 5.19i -0.5 - 6.06i 0.5 - 6.06i
-5 - 3.46i 5 - 3.46i -5.5 - 2.59i 5.5 - 2.59i
-5.5 + 2.59i 5.5 + 2.59i -5 + 3.46i 5 + 3.46i
-0.5 + 6.06i 0.5 + 6.06i -2.5 - 6.06i 2.5 - 6.06i
-4 - 5.19i 4 - 5.19i -6.5 - 0.86i 6.5 - 0.86i
-6.5 + 0.86i 6.5 + 0.86i -4 + 5.19i 4 + 5.19i
-2.5 + 6.06i 2.5 + 6.06i -0.5 - 7.79i 0.5 - 7.79i
-6.5 - 4.33i 6.5 - 4.33i -7 - 3.46i 7 - 3.46i
-7 + 3.46i 7 + 3.46i -6.5 + 4.33i 6.5 + 4.33i
</pre>
 
=={{header|Julia}}==
Line 273 ⟶ 439:
 
[[File:Eisenstein primes (Nim).png|center|Eisenstein primes]]
 
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl" line>
use v5.36;
use Math::AnyNum <pi mod max complex reals is_prime>;
 
my $omega = exp ( complex(0,2) * pi/3 ); my @E;
 
sub norm (@p) { $p[0]**2 - $p[0]*$p[1] + $p[1]**2 }
sub display (@p) { sprintf '%+8.4f%+8.4fi', reals($p[0] + $omega*$p[1]) }
sub X ($a, $b) { my @p; for my $x ($a..$b) { for my $y ($a..$b) { push @p, [$x, $y] } } @p }
sub table ($c, @V) { my $t = $c * (my $w = 1 + max map { length } @V); ( sprintf( ('%'.$w.'s')x@V, @V) ) =~ s/.{1,$t}\K/\n/gr }
 
for (X -10, 10) {
my($a,$b) = @$_;
my $c = max abs($a), abs($b);
push @E, [@$_] if ((0==$a or 0==$b or $a==$b) and is_prime $c and 2 == mod $c,3) or is_prime norm @$_
}
say table 4, (map { display @$_ } sort { norm(@$a) <=> norm(@$b) } @E)[0..99];</syntaxhighlight>
{{out}}
<pre>
-1.5000 -0.8660i -0.0000 -1.7321i -1.5000 +0.8660i +1.5000 -0.8660i
+0.0000 +1.7321i +1.5000 +0.8660i -1.0000 -1.7321i -2.0000 +0.0000i
+1.0000 -1.7321i -1.0000 +1.7321i +2.0000 +0.0000i +1.0000 +1.7321i
-2.0000 -1.7321i -2.5000 -0.8660i -0.5000 -2.5981i -2.5000 +0.8660i
+0.5000 -2.5981i -2.0000 +1.7321i +2.0000 -1.7321i -0.5000 +2.5981i
+2.5000 -0.8660i +0.5000 +2.5981i +2.5000 +0.8660i +2.0000 +1.7321i
-2.5000 -2.5981i -3.5000 -0.8660i -1.0000 -3.4641i -3.5000 +0.8660i
+1.0000 -3.4641i -2.5000 +2.5981i +2.5000 -2.5981i -1.0000 +3.4641i
+3.5000 -0.8660i +1.0000 +3.4641i +3.5000 +0.8660i +2.5000 +2.5981i
-3.5000 -2.5981i -4.0000 -1.7321i -0.5000 -4.3301i -4.0000 +1.7321i
+0.5000 -4.3301i -3.5000 +2.5981i +3.5000 -2.5981i -0.5000 +4.3301i
+4.0000 -1.7321i +0.5000 +4.3301i +4.0000 +1.7321i +3.5000 +2.5981i
-2.5000 -4.3301i -5.0000 +0.0000i +2.5000 -4.3301i -2.5000 +4.3301i
+5.0000 +0.0000i +2.5000 +4.3301i -3.5000 -4.3301i -5.5000 -0.8660i
-2.0000 -5.1962i -5.5000 +0.8660i +2.0000 -5.1962i -3.5000 +4.3301i
+3.5000 -4.3301i -2.0000 +5.1962i +5.5000 -0.8660i +2.0000 +5.1962i
+5.5000 +0.8660i +3.5000 +4.3301i -5.0000 -3.4641i -5.5000 -2.5981i
-0.5000 -6.0622i -5.5000 +2.5981i +0.5000 -6.0622i -5.0000 +3.4641i
+5.0000 -3.4641i -0.5000 +6.0622i +5.5000 -2.5981i +0.5000 +6.0622i
+5.5000 +2.5981i +5.0000 +3.4641i -4.0000 -5.1962i -6.5000 -0.8660i
-2.5000 -6.0622i -6.5000 +0.8660i +2.5000 -6.0622i -4.0000 +5.1962i
+4.0000 -5.1962i -2.5000 +6.0622i +6.5000 -0.8660i +2.5000 +6.0622i
+6.5000 +0.8660i +4.0000 +5.1962i -6.5000 -4.3301i -7.0000 -3.4641i
-0.5000 -7.7942i -7.0000 +3.4641i +0.5000 -7.7942i -6.5000 +4.3301i
+6.5000 -4.3301i -0.5000 +7.7942i +7.0000 -3.4641i +0.5000 +7.7942i
</pre>
 
=={{header|Phix}}==
{{libheader|Phix/xpGUI}}
Note MARKSTYLE=DOT added for this task, 1.0.3 has not yet been released, and won't be until work this needs under pwa/p2js is finished.
<!--<syntaxhighlight lang="phix">(phixonline)-->
Line 325 ⟶ 540:
<!--</syntaxhighlight>-->
Output same as Wren.
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" line>
my \ω = exp 2i × π/3;
 
sub norm (@p) { @p[0]² - @p[0]×@p[1] + @p[1]² }
sub display (@p) { (@p[0] + ω×@p[1]).reals».fmt('%+8.4f').join ~ 'i' }
 
my @E = gather (-10..10 X -10..10).map: -> (\a,\b) {
take (a,b) if 0 == a|b || a == b ?? (.is-prime and 2 == $_ mod 3 given (a,b)».abs.max) !! norm((a,b)).is-prime
}
 
(@E.sort: *.&norm).head(100).map(*.&display).batch(4).join("\n").say;
</syntaxhighlight>
{{out}}
<pre>
-1.5000 -0.8660i -0.0000 -1.7321i -1.5000 +0.8660i +1.5000 -0.8660i
+0.0000 +1.7321i +1.5000 +0.8660i -1.0000 -1.7321i -2.0000 +0.0000i
+1.0000 -1.7321i -1.0000 +1.7321i +2.0000 +0.0000i +1.0000 +1.7321i
-2.0000 -1.7321i -2.5000 -0.8660i -0.5000 -2.5981i -2.5000 +0.8660i
+0.5000 -2.5981i -2.0000 +1.7321i +2.0000 -1.7321i -0.5000 +2.5981i
+2.5000 -0.8660i +0.5000 +2.5981i +2.5000 +0.8660i +2.0000 +1.7321i
-2.5000 -2.5981i -3.5000 -0.8660i -1.0000 -3.4641i -3.5000 +0.8660i
+1.0000 -3.4641i -2.5000 +2.5981i +2.5000 -2.5981i -1.0000 +3.4641i
+3.5000 -0.8660i +1.0000 +3.4641i +3.5000 +0.8660i +2.5000 +2.5981i
-3.5000 -2.5981i -4.0000 -1.7321i -0.5000 -4.3301i -4.0000 +1.7321i
+0.5000 -4.3301i -3.5000 +2.5981i +3.5000 -2.5981i -0.5000 +4.3301i
+4.0000 -1.7321i +0.5000 +4.3301i +4.0000 +1.7321i +3.5000 +2.5981i
-2.5000 -4.3301i -5.0000 +0.0000i +2.5000 -4.3301i -2.5000 +4.3301i
+5.0000 +0.0000i +2.5000 +4.3301i -3.5000 -4.3301i -5.5000 -0.8660i
-2.0000 -5.1962i -5.5000 +0.8660i +2.0000 -5.1962i -3.5000 +4.3301i
+3.5000 -4.3301i -2.0000 +5.1962i +5.5000 -0.8660i +2.0000 +5.1962i
+5.5000 +0.8660i +3.5000 +4.3301i -5.0000 -3.4641i -5.5000 -2.5981i
-0.5000 -6.0622i -5.5000 +2.5981i +0.5000 -6.0622i -5.0000 +3.4641i
+5.0000 -3.4641i -0.5000 +6.0622i +5.5000 -2.5981i +0.5000 +6.0622i
+5.5000 +2.5981i +5.0000 +3.4641i -4.0000 -5.1962i -6.5000 -0.8660i
-2.5000 -6.0622i -6.5000 +0.8660i +2.5000 -6.0622i -4.0000 +5.1962i
+4.0000 -5.1962i -2.5000 +6.0622i +6.5000 -0.8660i +2.5000 +6.0622i
+6.5000 +0.8660i +4.0000 +5.1962i -6.5000 -4.3301i -7.0000 -3.4641i
-0.5000 -7.7942i -7.0000 +3.4641i +0.5000 -7.7942i -6.5000 +4.3301i
+6.5000 -4.3301i -0.5000 +7.7942i +7.0000 -3.4641i +0.5000 +7.7942i
</pre>
 
=={{header|Sidef}}==
{{trans|Raku}}
<syntaxhighlight lang="ruby" line>class Eisenstein(a, b, w = (-1 + sqrt(3).i)/2) {
method norm {
a**2 - a*b + b**2
}
 
method to_s {
sprintf('%+8.4f%+8.4fi', reals(a + b*w))
}
}
 
var E = []
 
for e in (-10..10 ~X -10..10 -> map_2d {|x,y| Eisenstein(x,y) }) {
var c = [e.a,e.b].map{.abs}.max
if (
((0 ~~ [e.a, e.b]) || (e.a == e.b)) ?
(c.is_congruent(2,3) && c.is_prime) : e.norm.is_prime
) {
E << e
}
}
 
E.sort_by { .norm }.first(100).slices(4).each {|s|
say s.join(' ')
}</syntaxhighlight>
{{out}}
<pre>
-1.5000 -0.8660i +0.0000 -1.7321i -1.5000 +0.8660i +1.5000 -0.8660i
+0.0000 +1.7321i +1.5000 +0.8660i -1.0000 -1.7321i -2.0000 +0.0000i
+1.0000 -1.7321i -1.0000 +1.7321i +2.0000 +0.0000i +1.0000 +1.7321i
-2.0000 -1.7321i -2.5000 -0.8660i -0.5000 -2.5981i -2.5000 +0.8660i
+0.5000 -2.5981i -2.0000 +1.7321i +2.0000 -1.7321i -0.5000 +2.5981i
+2.5000 -0.8660i +0.5000 +2.5981i +2.5000 +0.8660i +2.0000 +1.7321i
-2.5000 -2.5981i -3.5000 -0.8660i -1.0000 -3.4641i -3.5000 +0.8660i
+1.0000 -3.4641i -2.5000 +2.5981i +2.5000 -2.5981i -1.0000 +3.4641i
+3.5000 -0.8660i +1.0000 +3.4641i +3.5000 +0.8660i +2.5000 +2.5981i
-3.5000 -2.5981i -4.0000 -1.7321i -0.5000 -4.3301i -4.0000 +1.7321i
+0.5000 -4.3301i -3.5000 +2.5981i +3.5000 -2.5981i -0.5000 +4.3301i
+4.0000 -1.7321i +0.5000 +4.3301i +4.0000 +1.7321i +3.5000 +2.5981i
-2.5000 -4.3301i -5.0000 +0.0000i +2.5000 -4.3301i -2.5000 +4.3301i
+5.0000 +0.0000i +2.5000 +4.3301i -3.5000 -4.3301i -5.5000 -0.8660i
-2.0000 -5.1962i -5.5000 +0.8660i +2.0000 -5.1962i -3.5000 +4.3301i
+3.5000 -4.3301i -2.0000 +5.1962i +5.5000 -0.8660i +2.0000 +5.1962i
+5.5000 +0.8660i +3.5000 +4.3301i -5.0000 -3.4641i -5.5000 -2.5981i
-0.5000 -6.0622i -5.5000 +2.5981i +0.5000 -6.0622i -5.0000 +3.4641i
+5.0000 -3.4641i -0.5000 +6.0622i +5.5000 -2.5981i +0.5000 +6.0622i
+5.5000 +2.5981i +5.0000 +3.4641i -4.0000 -5.1962i -6.5000 -0.8660i
-2.5000 -6.0622i -6.5000 +0.8660i +2.5000 -6.0622i -4.0000 +5.1962i
+4.0000 -5.1962i -2.5000 +6.0622i +6.5000 -0.8660i +2.5000 +6.0622i
+6.5000 +0.8660i +4.0000 +5.1962i -6.5000 -4.3301i -7.0000 -3.4641i
-0.5000 -7.7942i -7.0000 +3.4641i +0.5000 -7.7942i -6.5000 +4.3301i
+6.5000 -4.3301i -0.5000 +7.7942i +7.0000 -3.4641i +0.5000 +7.7942i
</pre>
 
=={{header|Wren}}==
Line 333 ⟶ 646:
{{libheader|Wren-math}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="ecmascriptwren">import "dome" for Window
import "graphics" for Canvas, Color
import "./plot" for Axes
2,502

edits