AKS test for primes: Difference between revisions

m
Automated syntax highlighting fixup (second round - minor fixes)
m (syntax highlighting fixup automation)
m (Automated syntax highlighting fixup (second round - minor fixes))
Line 42:
{{trans|Python}}
 
<syntaxhighlight lang="11l">F expand_x_1(p)
V ex = [BigInt(1)]
L(i) 0 .< p
Line 83:
 
=={{header|8th}}==
<syntaxhighlight lang="8th">
with: a
 
Line 156:
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits <br> or android 64 bits with application Termux }}
<syntaxhighlight lang=AArch64"aarch64 Assemblyassembly">
/* ARM assembly AARCH64 Raspberry PI 3B or android 64 bits */
/* program AKS64.s */
Line 400:
 
=={{header|Ada}}==
<syntaxhighlight lang=Ada"ada">with Ada.Text_IO;
 
procedure Test_For_Primes is
Line 506:
The code below uses Algol 68 Genie which provides arbitrary precision arithmetic for LONG LONG modes.
 
<syntaxhighlight lang="algol68">
BEGIN
COMMENT
Line 609:
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi <br> or android 32 bits with application Termux}}
<syntaxhighlight lang=ARM"arm Assemblyassembly">
/* ARM assembly Raspberry PI or android 32 bits */
/* program AKS.s */
Line 837:
=={{header|AutoHotkey}}==
{{works with|AutoHotkey L}}
<syntaxhighlight lang="autohotkey">; 1. Create a function/subroutine/method that given p generates the coefficients of the expanded polynomial representation of (x-1)^p.
; Function modified from http://rosettacode.org/wiki/Pascal%27s_triangle#AutoHotkey
pascalstriangle(n=8) ; n rows of Pascal's triangle
Line 908:
 
The primality test uses a pattern that looks for a fractional factor. If such a factor is found, the test fails. Otherwise it succeeds.
<syntaxhighlight lang="bracmat">( (forceExpansion=.1+!arg+-1)
& (expandx-1P=.forceExpansion$((x+-1)^!arg))
& ( isPrime
Line 956:
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47</pre>
The AKS test kan be written more concisely than the task describes. This prints the primes between 980 and 1000:
<syntaxhighlight lang="bracmat">( out$"Primes between 980 and 1000, short version:"
& 980:?n
& whl
Line 972:
 
=={{header|C}}==
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 1,042:
=={{header|C sharp|C#}}==
{{trans|C}}
<syntaxhighlight lang="csharp">
using System;
public class AksTest
Line 1,100:
=={{header|C++}}==
{{trans|Pascal}}
<syntaxhighlight lang="cpp">
#include <iomanip>
#include <iostream>
Line 1,207:
=={{header|Clojure}}==
The *' function is an arbitrary precision multiplication.
<syntaxhighlight lang="clojure">(defn c
"kth coefficient of (x - 1)^n"
[n k]
Line 1,241:
 
=={{header|CoffeeScript}}==
<syntaxhighlight lang="coffeescript">pascal = () ->
a = []
return () ->
Line 1,293:
 
=={{header|Common Lisp}}==
<syntaxhighlight lang="lisp">(defun coefficients (p)
(cond
((= p 0) #(1))
Line 1,343:
=={{header|Crystal}}==
{{trans|Ruby}}
<syntaxhighlight lang="ruby">def x_minus_1_to_the(p)
p.times.reduce([1]) do |ex, _|
([0_i64] + ex).zip(ex + [0]).map { |x, y| x - y }
Line 1,382:
=={{header|D}}==
{{trans|Python}}
<syntaxhighlight lang="d">import std.stdio, std.range, std.algorithm, std.string, std.bigint;
 
BigInt[] expandX1(in uint p) pure /*nothrow*/ {
Line 1,432:
=={{header|EchoLisp}}==
We use the math.lib library and the poly functions to compute and display the required polynomials. A polynomial P(x) = a0 +a1*x + .. an*x^n is a list of coefficients (a0 a1 .... an).
<syntaxhighlight lang="lisp">
(lib 'math.lib)
;; 1 - x^p : P = (1 0 0 0 ... 0 -1)
Line 1,454:
</syntaxhighlight>
{{Output}}
<syntaxhighlight lang="lisp">
(show-them 13) →
p 1 x -1
Line 1,481:
{{trans|C#}}
ELENA 4.x :
<syntaxhighlight lang="elena">import extensions;
singleton AksTest
Line 1,570:
=={{header|Elixir}}==
{{trans|Erlang}}
<syntaxhighlight lang="elixir">defmodule AKS do
def iterate(f, x), do: fn -> [x | iterate(f, f.(x))] end
Line 1,629:
The Erlang io module can print out lists of characters with any level of nesting as a flat string. (e.g. ["Er", ["la", ["n"]], "g"] prints as "Erlang") which is useful when constructing the strings to print out for the binomial expansions. The program also shows how lazy lists can be implemented in Erlang.
 
<syntaxhighlight lang="erlang">#! /usr/bin/escript
 
-import(lists, [all/2, seq/2, zip/2]).
Line 1,683:
 
=={{header|Factor}}==
<syntaxhighlight lang="factor">USING: combinators formatting io kernel make math math.parser
math.polynomials prettyprint sequences ;
IN: rosetta-code.aks-test
Line 1,738:
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">: coeffs ( u -- nu ... n0 ) \ coefficients of (x-1)^u
1 swap 1+ dup 1 ?do over over i - i */ negate swap loop drop ;
 
Line 1,780:
 
=={{header|Fortran}}==
<syntaxhighlight lang="fortran">
program aks
implicit none
Line 1,935:
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang=FreeBASIC"freebasic">'METHOD -- Use the Pascal triangle to retrieve the coefficients
'UPPER LIMIT OF FREEBASIC ULONGINT GETS PRIMES UP TO 70
Sub string_split(s_in As String,char As String,result() As String)
Line 2,025:
 
=={{header|Go}}==
<syntaxhighlight lang="go">package main
 
import "fmt"
Line 2,104:
 
=={{header|Haskell}}==
<syntaxhighlight lang="haskell">expand p = scanl (\z i -> z * (p-i+1) `div` i) 1 [1..p]
 
 
Line 2,142:
 
=={{header|Idris}}==
<syntaxhighlight lang="idris">import Data.Vect
 
-- Computes Binomial Coefficients
Line 2,231:
=={{header|J}}==
 
'''Solution''':<syntaxhighlight lang="j"> binomialExpansion =: (!~ * _1 ^ 2 | ]) i.&.:<: NB. 1) Create a function that gives the coefficients of (x-1)^p.
testAKS =: 0 *./ .= ] | binomialExpansion NB. 3) Use that function to create another which determines whether p is prime using AKS.</syntaxhighlight>
 
'''Examples''':<syntaxhighlight lang="j"> binomialExpansion&.> i. 8 NB. 2) show the polynomial expansions p in the range 0 to at 7 inclusive.
+-++--+----+-------+-----------+---------------+------------------+
|0||_2|_3 3|_4 6 _4|_5 10 _10 5|_6 15 _20 15 _6|_7 21 _35 35 _21 7|
Line 2,248:
 
{{trans|C}}
'''Solution''':<syntaxhighlight lang="java">public class AksTest {
private static final long[] c = new long[64];
 
Line 2,310:
=={{header|JavaScript}}==
{{trans|CoffeeScript}}
<syntaxhighlight lang="javascript">var i, p, pascal, primerow, primes, show, _i;
 
pascal = function() {
Line 2,401:
The primes upto 50 are: 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47</pre>
Reviewed (ES6):
<syntaxhighlight lang="javascript">function pascal(n) {
var cs = []; if (n) while (n--) coef(); return coef
function coef() {
Line 2,436:
Primes: 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47
{{trans|C}}
<syntaxhighlight lang=JavaScript"javascript">function coef(n) {
for (var c=[1], i=0; i<n; c[0]=-c[0], i+=1) {
c[i+1]=1; for (var j=i; j; j-=1) c[j] = c[j-1]-c[j]
Line 2,485:
easily be adapted to use a BigInt library such as the one at
https://github.com/joelpurra/jq-bigint
<syntaxhighlight lang="jq"># add_pairs is a helper function for optpascal/0
# Input: an OptPascal array
# Output: the next OptPascal array (obtained by adding adjacent items,
Line 2,522:
 
'''Task 1:''' "A method to generate the coefficients of (x-1)^p"
<syntaxhighlight lang="jq">def coefficients:
def alternate_signs: . as $in
| reduce range(0; length) as $i ([]; . + [$in[$i] * (if $i % 2 == 0 then 1 else -1 end )]);
Line 2,528:
'''Task 2:''' "Show here the polynomial expansions of (x − 1)^p for p in the range 0 to at least 7, inclusive."
<syntaxhighlight lang="jq">range(0;8) | "Coefficient for (x - 1)^\(.): \(coefficients)"</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">Coefficients for (x - 1)^0: [1]
Coefficients for (x - 1)^1: [1,-1]
Coefficients for (x - 1)^2: [1,-2,1]
Line 2,542:
 
For brevity, we show here only the relatively efficient solution based on optpascal/0:
<syntaxhighlight lang="jq">def is_prime:
. as $N
| if . < 2 then false
Line 2,550:
 
'''Task 4:''' "Use your AKS test to generate a list of all primes under 35."
<syntaxhighlight lang="jq">range(0;36) | select(is_prime)</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">2
3
5
Line 2,565:
 
'''Task 5:''' "As a stretch goal, generate all primes under 50."
<syntaxhighlight lang="ja">[range(0;50) | select(is_prime)]</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47]</syntaxhighlight>
 
=={{header|Julia}}==
'''Task 1'''
 
<syntaxhighlight lang=Julia"julia">
function polycoefs(n::Int64)
pc = typeof(n)[]
Line 2,591:
'''Task 2'''
 
<syntaxhighlight lang=Julia"julia">using Printf
 
function stringpoly(n::Int64)
Line 2,626:
'''Task 3'''
 
<syntaxhighlight lang=Julia"julia">
function isaksprime(n::Int64)
if n < 2
Line 2,642:
'''Task 4'''
 
<syntaxhighlight lang=Julia"julia">
println("<math>")
println("\\begin{array}{lcl}")
Line 2,684:
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1
 
fun binomial(n: Int, k: Int): Long = when {
Line 2,758:
</pre>
=={{header|Lua}}==
<syntaxhighlight lang="lua">-- AKS test for primes, in Lua, 6/23/2020 db
local function coefs(n)
local list = {[0]=1}
Line 2,810:
 
=={{header|Lambdatalk}}==
<syntaxhighlight lang=Scheme"scheme">
{require lib_BN} // for big numbers
 
Line 2,882:
{{trans|Pascal}}
{{works with|Just BASIC|any}}
<syntaxhighlight lang="lb">
global pasTriMax
pasTriMax = 61
Line 2,980:
=={{header|Maple}}==
Maple handles algebraic manipulation of polynomials natively.
<syntaxhighlight lang=Maple"maple">> for xpr in seq( expand( (x-1)^p ), p = 0 .. 7 ) do print( xpr ) end:
1
 
Line 3,004:
</syntaxhighlight>
To implement the primality test, we write the following procedure that uses the (built-in) polynomial expansion to generate a list of coefficients of the expanded polynomial.
<syntaxhighlight lang=Maple"maple"> polc := p -> [coeffs]( expand( (x-1)^p - (x^p-1) ) ):</syntaxhighlight>
Use <code>polc</code> to implement <code>prime?</code> which does the primality test.
<syntaxhighlight lang=Maple"maple">prime? := n -> n > 1 and {op}( map( modp, polc( n ), n ) ) = {0}</syntaxhighlight>
Of course, rather than calling <code>polc</code>, we can inline it, just for the sake of making the whole thing a one-liner (while adding argument type-checking for good measure):
<syntaxhighlight lang=Maple"maple">prime? := (n::posint) -> n > 1 and {op}( map( modp, [coeffs]( expand( (x-1)^n - (x^n-1) ) ), n ) ) = {0}</syntaxhighlight>
This agrees with the built-in primality test <code>isprime</code>:
<syntaxhighlight lang=Maple"maple">> evalb( seq( prime?(i), i = 1 .. 1000 ) = seq( isprime( i ), i = 1 .. 1000 ) );
true
</syntaxhighlight>
Use <code>prime?</code> with the built-in Maple <code>select</code> procedure to pick off the primes up to 50:
<syntaxhighlight lang=Maple"maple">> select( prime?, [seq](1..50) );
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
</syntaxhighlight>
Line 3,020:
=={{header|Mathematica}} / {{header|Wolfram Language}}==
Algebraic manipulation is built into Mathematica, so there's no need to create a function to do (x-1)^p
<syntaxhighlight lang=Mathematica"mathematica">Print["powers of (x-1)"]
(x - 1)^( Range[0, 7]) // Expand // TableForm
Print["primes under 50"]
Line 3,042:
 
=={{header|Nim}}==
<syntaxhighlight lang=Nim"nim">
from math import binom
import strutils
Line 3,132:
=={{header|Objeck}}==
{{trans|Java}}
<syntaxhighlight lang="objeck">class AksTest {
@c : static : Int[];
Line 3,209:
{{trans|Clojure}}
Uses [http://github.com/c-cube/gen gen] library for lazy streams and [https://forge.ocamlcore.org/projects/zarith zarith] for arbitrarily sized integers. Runs as is through the [https://github.com/diml/utop utop] REPL.
<syntaxhighlight lang=OCaml"ocaml">#require "gen"
#require "zarith"
open Z
Line 3,268:
 
=={{header|Oforth}}==
<syntaxhighlight lang=Oforth"oforth">import: mapping
 
: nextCoef( prev -- [] )
Line 3,306:
 
=={{header|PARI/GP}}==
<syntaxhighlight lang="parigp">getPoly(n)=('x-1)^n;
vector(8,n,getPoly(n-1))
AKS_slow(n)=my(P=getPoly(n));for(i=1,n-1,if(polcoeff(P,i)%n,return(0))); 1;
Line 3,317:
=={{header|Pascal}}==
{{works with|Free Pascal}}
<syntaxhighlight lang="pascal">
const
pasTriMax = 61;
Line 3,426:
 
=={{header|Perl}}==
<syntaxhighlight lang="perl">use strict;
use warnings;
# Select one of these lines. Math::BigInt is in core, but quite slow.
Line 3,473:
 
{{libheader|ntheory}}
<syntaxhighlight lang="perl">use ntheory ":all";
# Uncomment next line to see the r and s values used. Set to 2 for more detail.
# prime_set_config(verbose => 1);
Line 3,481:
 
=={{header|Phix}}==
<!--<syntaxhighlight lang=Phix"phix">-->
<span style="color: #000080;font-style:italic;">-- demo/rosetta/AKSprimes.exw
-- Does not work for primes above 53, which is actually beyond the original task anyway.
Line 3,580:
 
=={{header|Picat}}==
<syntaxhighlight lang=Picat"picat">
pascal([]) = [1].
pascal(L) = [1|sum_adj(L)].
Line 3,652:
 
=={{header|PicoLisp}}==
<syntaxhighlight lang="text">(de pascal (N)
(let D 1
(make
Line 3,689:
 
=={{header|PL/I}}==
<syntaxhighlight lang=PL"pl/Ii">
AKS: procedure options (main, reorder); /* 16 September 2015, derived from Fortran */
 
Line 3,847:
connection can be expressed directly in Prolog by the following prime number
generator:
<syntaxhighlight lang="prolog">
prime(P) :-
pascal([1,P|Xs]),
Line 3,886:
 
===Pascal Triangle Generator===
<syntaxhighlight lang="prolog">
% To generate the n-th row of a Pascal triangle
% pascal(+N, Row)
Line 3,935:
Solutions with output from SWI-Prolog:
 
<syntaxhighlight lang="prolog">
%%% Task 1: "A method to generate the coefficients of (1-X)^p"
 
Line 3,977:
</pre>
 
<syntaxhighlight lang="prolog">
%%% Task 3. Use the previous function in creating [sic]
%%% another function that when given p returns whether p is prime
Line 3,996:
recomputation):
 
<syntaxhighlight lang="prolog">
prime(N) :- optpascal([1,N|Xs]), forall( member(X,Xs), 0 is X mod N).
</syntaxhighlight>
 
<syntaxhighlight lang="prolog">
%%% Task 4. Use your AKS test to generate a list of all primes under 35.
 
Line 4,017:
 
It would be possible to go further and expand (a + b)^n and collect terms, but that turns out to be rather difficult because terms have to be reordered into a canonical form first -- for example, an expansion can produce both j*a*b and k*b*a, and these terms would have to be reordered to get (j+k)*a*b.
<syntaxhighlight lang=Prolog"prolog">
main :- task1(8), nl, task2(50), halt.
 
Line 4,140:
 
=={{header|PureBasic}}==
<syntaxhighlight lang="purebasic">EnableExplicit
Define vzr.b = -1, vzc.b = ~vzr, nMAX.i = 10, n.i , k.i
 
Line 4,201:
=={{header|Python}}==
 
<syntaxhighlight lang="python">def expand_x_1(n):
# This version uses a generator and thus less computations
c =1
Line 4,218:
return True</syntaxhighlight>
or equivalently:
<syntaxhighlight lang="python">def aks(p):
if p==2:return True
c=1
Line 4,226:
return True</syntaxhighlight>
alternatively:
<syntaxhighlight lang="python">def expand_x_1(p):
ex = [1]
for i in range(p):
Line 4,268:
Using a wikitable and math features with the following additional code produces better formatted polynomial output:
 
<syntaxhighlight lang="python">print('''
{| class="wikitable" style="text-align:left;"
|+ Polynomial Expansions and AKS prime test
Line 4,348:
 
<syntaxhighlight lang=R"r">AKS<-function(p){
i<-2:p-1
l<-unique(factorial(p) / (factorial(p-i) * factorial(i)))
Line 4,361:
With copious use of the math/number-theory library...
 
<syntaxhighlight lang="racket">#lang racket
(require math/number-theory)
 
Line 4,449:
The <tt>polyprime</tt> function pretty much reads like the original description. Is it "so" that the p'th expansion's coefficients are all divisible by p? The <tt>.[1 ..^ */2]</tt> slice is done simply to weed out divisions by 1 or by factors we've already tested (since the coefficients are symmetrical in terms of divisibility). If we wanted to write <tt>polyprime</tt> even more idiomatically, we could have made it another infinite constant list that is just a mapping of the first list, but we decided that would just be showing off. <tt>:-)</tt>
 
<syntaxhighlight lang=perl6"raku" line>constant expansions = [1], [1,-1], -> @prior { [|@prior,0 Z- 0,|@prior] } ... *;
 
sub polyprime($p where 2..*) { so expansions[$p].[1 ..^ */2].all %% $p }
Line 4,503:
=={{header|REXX}}==
===version 1===
<syntaxhighlight lang="rexx">/* REXX ---------------------------------------------------------------
* 09.02.2014 Walter Pachl
* 22.02.2014 WP fix 'accounting' problem (courtesy GS)
Line 4,572:
 
The program determines programmatically the required number of decimal digits (precision) for the large coefficients.
<syntaxhighlight lang="rexx">/*REXX program calculates primes via the Agrawal─Kayal─Saxena (AKS) primality test.*/
parse arg Z . /*obtain optional argument from the CL.*/
if Z=='' | Z=="," then Z= 200 /*Not specified? Then use the default.*/
Line 4,685:
Using the `polynomial` Rubygem, this can be written directly from the definition in the description:
 
<syntaxhighlight lang="ruby">require 'polynomial'
 
def x_minus_1_to_the(p)
Line 4,706:
Or without the dependency:
 
<syntaxhighlight lang="ruby">def x_minus_1_to_the(p)
p.times.inject([1]) do |ex, _|
([0] + ex).zip(ex + [0]).map { |x,y| x - y }
Line 4,743:
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">fn aks_coefficients(k: usize) -> Vec<i64> {
let mut coefficients = vec![0i64; k + 1];
coefficients[0] = 1;
Line 4,786:
An alternative version which computes the coefficients in a more functional but less efficient way.
 
<syntaxhighlight lang="rust">
fn aks_coefficients(k: usize) -> Vec<i64> {
if k == 0 {
Line 4,802:
 
=={{header|Scala}}==
<syntaxhighlight lang=Scala"scala">def powerMin1(n: BigInt) = if (n % 2 == 0) BigInt(1) else BigInt(-1)
 
val pascal = (( Vector(Vector(BigInt(1))) /: (1 to 50)) { (rows, i) =>
Line 4,847:
=={{header|Scheme}}==
 
<syntaxhighlight lang=Scheme"scheme">
;; implement mod m arithmetic with polnomials in x
;; as lists of coefficients, x^0 first.
Line 4,908:
=={{header|Scilab}}==
 
<syntaxhighlight lang="text">
clear
xdel(winsid())
Line 5,000:
 
=={{header|Seed7}}==
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const func array integer: expand_x_1 (in integer: p) is func
Line 5,083:
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">func binprime(p) {
p >= 2 || return false
for i in (1 .. p>>1) {
Line 5,125:
Using the [https://ideas.repec.org/c/boc/bocode/s455001.html moremata] library to print the polynomial coefficients. They are in decreasing degree order. To install moremata, type '''ssc install moremata''' in Stata. Since Stata is using double precision floating-point instead of 32 bit integers, the polynomials are exact up to p=54.
 
<syntaxhighlight lang="stata">mata
function pol(n) {
a=J(1,n+1,1)
Line 5,190:
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">func polynomialCoeffs(n: Int) -> [Int] {
var result = [Int](count : n+1, repeatedValue : 0)
Line 5,291:
=={{header|Tcl}}==
A recursive method with memorization would be more efficient, but this is sufficient for small-scale work.
<syntaxhighlight lang="tcl">proc coeffs {p {signs 1}} {
set clist 1
for {set i 0} {$i < $p} {incr i} {
Line 5,357:
=={{header|Transd}}==
{{trans|Python}}
<syntaxhighlight lang="scheme">
#lang transd
 
Line 5,411:
 
=={{header|uBasic/4tH}}==
<syntaxhighlight lang="text">For n = 0 To 9
Push n : Gosub _coef : Gosub _drop
Print "(x-1)^";n;" = ";
Line 5,501:
=={{header|VBA}}==
{{trans|Phix}}
<syntaxhighlight lang="vb">
'-- Does not work for primes above 97, which is actually beyond the original task anyway.
'-- Translated from the C version, just about everything is (working) out-by-1, what fun.
Line 5,594:
=={{header|Vlang}}==
{{trans|go}}
<syntaxhighlight lang="vlang">fn bc(p int) []i64 {
mut c := []i64{len: p+1}
mut r := i64(1)
Line 5,672:
=={{header|Wren}}==
{{trans|Go}}
<syntaxhighlight lang="ecmascript">var bc = Fn.new { |p|
var c = List.filled(p+1, 0)
var r = 1
Line 5,738:
=={{header|Yabasic}}==
{{trans|Phix}}
<syntaxhighlight lang=Yabasic"yabasic">// Does not work for primes above 53, which is actually beyond the original task anyway.
// Translated from the C version, just about everything is (working) out-by-1, what fun.
 
Line 5,826:
=={{header|Zig}}==
Uses Zig's compile-time interpreter to create Pascal's triangle at compile-time.
<syntaxhighlight lang=Zig"zig">
const std = @import("std");
const assert = std.debug.assert;
Line 5,921:
=={{header|zkl}}==
{{trans|Python}}
<syntaxhighlight lang="zkl">var BN=Import("zklBigNum");
fcn expand_x_1(p){
ex := L(BN(1));
10,333

edits