import std.stdio, std.range, std.algorithm, std.string, std.bigint;

BigInt[] expandX1(in uint p) pure /*nothrow*/ {
    if (p == 0) return [1.BigInt];
    typeof(return) r = [1.BigInt, BigInt(-1)];
    foreach (immutable _; 1 .. p)
        r = zip(r~0.BigInt, 0.BigInt~r).map!(xy => xy[0]-xy[1]).array;
    r.reverse();
    return r;
}

bool aksTest(in uint p) pure /*nothrow*/ {
    if (p < 2) return false;
    auto ex = p.expandX1;
    ex[0]++;
    return !ex[0 .. $ - 1].any!(mult => mult % p);
}

void main() {
    "# p: (x-1)^p for small p:".writeln;
    foreach (immutable p; 0 .. 12)
        writefln("%3d: %s", p, p.expandX1.zip(iota(p + 1)).retro
                 .map!q{"%+dx^%d ".format(a[])}.join.replace("x^0", "")
                 .replace("^1 ", " ").replace("+", "+ ")
                 .replace("-", "- ").replace(" 1x", " x")[2 .. $]);

    "\nSmall primes using the AKS test:".writeln;
    101.iota.filter!aksTest.writeln;
}


(lib 'math.lib)
;; 1 - x^p  :  P = (1 0 0 0 ... 0 -1)
(define (mono p) (append (list 1) (make-list (1- p) 0) (list -1)))

;; compute (x-1)^p ,  p >= 1
(define (aks-poly p)
	(poly-pow (list -1 1) p))

;;
(define (show-them n)
	(for ((p (in-range 1 n)))
		(writeln 'p p (poly->string 'x (aks-poly p)))))

;; aks-test
;; P = (x-1)^p + 1 - x^p
(define (aks-test p)
	(let ((P (poly-add (mono p) (aks-poly p)))
	    (test (lambda(a) (zero? (modulo a p))))) ;; p divides a[i] ?
	    (apply and (map test P)))) ;; returns #t if true for all a[i]


import extensions;

singleton AksTest
{
    static long[] c := new long[](100);

    coef(int n)
    {
        int i := 0;
        int j := 0;

        if ((n < 0) || (n > 63)) { AbortException.raise() }; // gracefully deal with range issue

        c[i] := 1l;
        for (int i := 0, i < n, i += 1) {
            c[1 + i] := 1l;
            for (int j := i, j > 0, j -= 1) {
                c[j] := c[j - 1] - c[j]
            };
            c[0] := c[0].Negative
        }
    }

    bool is_prime(int n)
    {
        int i := n;

        self.coef(n);
        c[0] := c[0] + 1;
        c[i] := c[i] - 1;

        i -= 1;
        while (i + 1 != 0 && c[i+1].mod(n) == 0)
        {
            i -= 1
        };

        ^ i < 0
    }

    show(int n)
    {
        int i := n;
        i += 1;
        while(i != 0)
        {
            i -= 1;
            console.print("+",c[i],"x^",i)
        }
    }
}

public program()
{
    for (int n := 0, n < 10, n += 1) {
        AksTest.coef(n);

		console.print("(x-1)^",n," = ");
		AksTest.show(n);
        console.printLine()
    };

    console.print("Primes:");
    for (int n := 1, n <= 63, n += 1) {
        if (AksTest.is_prime(n))
        {
            console.print(n," ")
        }
    };

    console.printLine().readChar()
}


defmodule AKS do
  def iterate(f, x), do: fn -> [x | iterate(f, f.(x))] end

  def take(0, _lazy), do: []
  def take(n, lazy) do
    [value | next] = lazy.()
    [value | take(n-1, next)]
  end

  def pascal, do: iterate(fn row -> [1 | sum_adj(row)] end, [1])

  defp sum_adj([_] = l), do: l
  defp sum_adj([a, b | _] = row), do: [a+b | sum_adj(tl(row))]

  def show_binomial(row) do
    degree = length(row) - 1
    ["(x - 1)^",  to_char_list(degree), " =", binomial_rhs(row, 1, degree)]
  end

  defp show_x(0), do: ""
  defp show_x(1), do: "x"
  defp show_x(n), do: [?x, ?^ | to_char_list(n)]

  defp binomial_rhs([], _, _), do: []
  defp binomial_rhs([coef | coefs], sgn, exp) do
    signchar = if sgn > 0, do: ?+, else: ?-
    [0x20, signchar, 0x20, to_char_list(coef), show_x(exp) | binomial_rhs(coefs, -sgn, exp-1)]
  end

  def primerow(row, n), do: Enum.all?(row, fn coef -> (coef == 1) or (rem(coef, n) == 0) end)

  def main do
    for row <- take(8, pascal), do: IO.puts show_binomial(row)
    IO.write "\nThe primes upto 50: "
    IO.inspect for {row, n} <- Enum.zip(tl(tl(take(51, pascal))), 2..50), primerow(row, n), do: n
  end
end

AKS.main


#! /usr/bin/escript

-import(lists, [all/2, seq/2, zip/2]).

iterate(F, X) -> fun() -> [X | iterate(F, F(X))] end.

take(0, _lazy) -> [];
take(N, Lazy) ->
    [Value | Next] = Lazy(),
    [Value | take(N-1, Next)].

pascal() -> iterate(fun (Row) -> [1 | sum_adj(Row)] end, [1]).

sum_adj([_] = L) -> L;
sum_adj([A, B | _] = Row) -> [A+B | sum_adj(tl(Row))].

show_binomial(Row) ->
    Degree = length(Row) - 1,
    ["(x - 1)^",  integer_to_list(Degree), " =", binomial_rhs(Row, 1, Degree)].

show_x(0) -> "";
show_x(1) -> "x";
show_x(N) -> [$x, $^ | integer_to_list(N)].

binomial_rhs([], _, _) -> [];
binomial_rhs([Coef | Coefs], Sgn, Exp) ->
    SignChar = if Sgn > 0 -> $+; true -> $- end,
    [$ , SignChar, $ , integer_to_list(Coef), show_x(Exp) | binomial_rhs(Coefs, -Sgn, Exp-1)].

primerow(Row, N) -> all(fun (Coef) -> (Coef =:= 1) or (Coef rem N =:= 0) end, Row).

main(_) ->
    [io:format("~s~n", [show_binomial(Row)]) || Row <- take(8, pascal())],
    io:format("~nThe primes upto 50: ~p~n",
               [[N || {Row, N} <- zip(tl(tl(take(51, pascal()))), seq(2, 50)),
                      primerow(Row, N)]]).


USING: combinators formatting io kernel make math math.parser
math.polynomials prettyprint sequences ;
IN: rosetta-code.aks-test

! Polynomials are represented by the math.polynomials vocabulary
! as sequences with the highest exponent on the right. Hence
! { -1 1 } represents x - 1.
: (x-1)^ ( n -- seq ) { -1 1 } swap p^ ;

: choose-exp ( n -- str )
    { { 0 [ "" ] } { 1 [ "x" ] } [ "x^%d" sprintf ] } case ;

: choose-coeff ( n -- str )
    [ dup neg? [ neg "- " ] [ "+ " ] if % # ] "" make ;

: terms ( coeffs-seq -- terms-seq )
    [ [ choose-coeff ] [ choose-exp append ] bi* ] map-index ;

: (.p) ( n -- str ) (x-1)^ terms <reversed> " " join 3 tail ;

: .p ( n -- ) dup zero? [ drop "1" ] [ (.p) ] if print ;

: show-poly ( n -- ) [ "(x-1)^%d = " printf ] [ .p ] bi ;

: part1 ( -- ) 8 <iota> [ show-poly ] each ;

: (prime?) ( n -- ? )
    (x-1)^ rest but-last dup first [ mod 0 = not ] curry find
    nip not ;

: prime? ( n -- ? ) dup 2 < [ drop f ] [ (prime?) ] if ;

: part2 ( -- )
    "Primes up to 50 via AKS:" print
    50 <iota> [ prime? ] filter . ;

: aks-test ( -- ) part1 nl part2 ;

MAIN: aks-test


: coeffs ( u -- nu ... n0 ) \ coefficients of (x-1)^u
   1 swap 1+ dup 1 ?do over over i - i */ negate swap loop drop ;

: prime? ( u -- f )
   dup 2 < if drop false exit then
   dup >r coeffs 1+
   \ if not prime, this loop consumes at most half the coefficients, otherwise all
   begin dup 1 <> while
      [email protected] mod 0= while
   repeat then rdrop
   dup 1 = >r
   begin 1 = until
   r> ;

: .monom ( u1 u2 -- )
   dup 0> if [char] + emit then 0 .r ?dup if ." x^" . else space then ;
: .poly ( u -- )
   dup >r coeffs 0 r> 1+ 0 ?do
      tuck swap .monom 1+
   loop ;

: main
   11 0 ?do i . ." : " i .poly cr loop cr
   50 1 ?do i prime? if i . then loop
   cr ;


program aks
  implicit none

  ! Coefficients of polynomial expansion
  integer(kind=16), dimension(:), allocatable :: coeffs
  integer(kind=16) :: n
  ! Character variable for I/O
  character(len=40) :: tmp

  ! Point #2
  do n = 0, 7
    write(tmp, *) n
    call polynomial_expansion(n, coeffs)
    write(*, fmt='(A)', advance='no') '(x - 1)^'//trim(adjustl(tmp))//' ='
    call print_polynom(coeffs)
  end do

  ! Point #4
  do n = 2, 35
    if (is_prime(n)) write(*, '(I4)', advance='no') n
  end do
  write(*, *)

  ! Point #5
  do n = 2, 124
    if (is_prime(n)) write(*, '(I4)', advance='no') n
  end do
  write(*, *)

  if (allocated(coeffs)) deallocate(coeffs)
contains
  ! Calculate coefficients of (x - 1)^n using binomial theorem
  subroutine polynomial_expansion(n, coeffs)
    integer(kind=16), intent(in) :: n
    integer(kind=16), dimension(:), allocatable, intent(out) :: coeffs
    integer(kind=16) :: i, j

    if (allocated(coeffs)) deallocate(coeffs)

    allocate(coeffs(n + 1))

    do i = 1, n + 1
      coeffs(i) = binomial(n, i - 1)*(-1)**(n - i - 1)
    end do
  end subroutine

  ! Calculate binomial coefficient using recurrent relation, as calculation
  ! using factorial overflows too quickly.
  function binomial(n, k) result (res)
    integer(kind=16), intent(in) :: n, k
    integer(kind=16) :: res
    integer(kind=16) :: i

    if (k == 0) then
      res = 1
      return
    end if

    res = 1
    do i = 0, k - 1
      res = res*(n - i)/(i + 1)
    end do
  end function

  ! Outputs polynomial with given coefficients
  subroutine print_polynom(coeffs)
    integer(kind=16), dimension(:), allocatable, intent(in) :: coeffs
    integer(kind=4) :: i, p
    character(len=40) :: cbuf, pbuf
    logical(kind=1) :: non_zero

    if (.not. allocated(coeffs)) return

    non_zero = .false.

    do i = 1, size(coeffs)
      if (coeffs(i) .eq. 0) cycle

      p = i - 1
      write(cbuf, '(I40)') abs(coeffs(i))
      write(pbuf, '(I40)') p

      if (non_zero) then
        if (coeffs(i) .gt. 0) then
          write(*, fmt='(A)', advance='no') ' + '
        else
          write(*, fmt='(A)', advance='no') ' - '
        endif
      else
        if (coeffs(i) .gt. 0) then
          write(*, fmt='(A)', advance='no') '   '
        else
          write(*, fmt='(A)', advance='no') ' - '
        endif
      endif

      if (p .eq. 0) then
        write(*, fmt='(A)', advance='no') trim(adjustl(cbuf))
      elseif (p .eq. 1) then
        if (coeffs(i) .eq. 1) then
          write(*, fmt='(A)', advance='no') 'x'
        else
          write(*, fmt='(A)', advance='no') trim(adjustl(cbuf))//'x'
        end if
      else
        if (coeffs(i) .eq. 1) then
          write(*, fmt='(A)', advance='no') 'x^'//trim(adjustl(pbuf))
        else
          write(*, fmt='(A)', advance='no') &
            trim(adjustl(cbuf))//'x^'//trim(adjustl(pbuf))
        end if
      end if
      non_zero = .true.
    end do

    write(*, *)
  end subroutine

  ! Test if n is prime using AKS test. Point #3.
  function is_prime(n) result (res)
    integer(kind=16), intent (in) :: n
    logical(kind=1) :: res
    integer(kind=16), dimension(:), allocatable :: coeffs
    integer(kind=16) :: i

    call polynomial_expansion(n, coeffs)
    coeffs(1) = coeffs(1) + 1
    coeffs(n + 1) = coeffs(n + 1) - 1

    res = .true.

    do i = 1, n + 1
      res = res .and. (mod(coeffs(i), n) == 0)
    end do

    if (allocated(coeffs)) deallocate(coeffs)
  end function
end program aks


'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)
    Dim As String s=s_in,var1,var2
    Dim As Integer n,pst
    #macro split(stri,char,var1,var2)
    pst=Instr(stri,char)
    var1="":var2=""
    If pst<>0 Then
        var1=Mid(stri,1,pst-1)
        var2=Mid(stri,pst+1)
    Else
        var1=stri
    End If
    Redim Preserve result(1 To 1+n-((Len(var1)>0)+(Len(var2)>0)))
    result(n+1)=var1
    #endmacro
    Do
        split(s,char,var1,var2):n=n+1:s=var2
    Loop Until var2=""
    Redim Preserve result(1 To Ubound(result)-1)
End Sub

'Get Pascal triangle components
Function pasc(n As Integer,flag As Integer=0) As String
    n+=1
    Dim As Ulongint V(n):V(1)=1ul
    Dim As String s,sign
    For r  As Integer= 2 To n
        s=""
        For i As Integer = r To 1 Step -1
            V(i) +=  V(i-1)
            If i Mod 2=1 Then sign="" Else sign="-"
            s+=sign+Str(V(i))+","
        Next i
    Next r
    If flag Then 'formatted output
        Dim As String i,i2,i3,g
        Redim As String a(0)
        string_split(s,",",a())
        For n1 As Integer=1 To Ubound(a)
            If Left(a(n1),1)="-" Then sign="" Else sign="+"
            If n1=Ubound(a) Then i2="" Else i2=a(n1)
            If n1=2 Then i3="x" Else i3="x^"+Str(n1-1)
            If n1=1 Then i="":sign=" " Else i=i3
            g+=sign+i2+i+" "
        Next n1
        g="(x-1)^"+Str(n-1)+" = "+g
        Return g
    End If
    Return s
End Function

Function isprime(num As Integer) As Integer
    Redim As String a(0)
    string_split(pasc(num),",",a())
    For n As Integer=Lbound(a)+1 To Ubound(a)-1
        If (Valulng(Ltrim(a(n),"-"))) Mod num<>0 Then Return 0
    Next n
    Return -1
End Function
'====================================
'Formatted output
For n As Integer=1 To 9
    Print pasc(n,1)
Next n

Print
'Limit of Freebasic Ulongint sets about 70 max
Print "Primes up to 70:"
For n As Integer=2 To 70
    If isprime(n) Then Print n;
Next n

Sleep


package main

import "fmt"

func bc(p int) []int64 {
    c := make([]int64, p+1)
    r := int64(1)
    for i, half := 0, p/2; i <= half; i++ {
        c[i] = r
        c[p-i] = r
        r = r * int64(p-i) / int64(i+1)
    }
    for i := p - 1; i >= 0; i -= 2 {
        c[i] = -c[i]
    }
    return c
}

func main() {
    for p := 0; p <= 7; p++ {
        fmt.Printf("%d:  %s\n", p, pp(bc(p)))
    }
    for p := 2; p < 50; p++ {
        if aks(p) {
            fmt.Print(p, " ")
        }
    }
    fmt.Println()
}

var e = []rune("²³⁴⁵⁶⁷")

func pp(c []int64) (s string) {
    if len(c) == 1 {
        return fmt.Sprint(c[0])
    }
    p := len(c) - 1
    if c[p] != 1 {
        s = fmt.Sprint(c[p])
    }
    for i := p; i > 0; i-- {
        s += "x"
        if i != 1 {
            s += string(e[i-2])
        }
        if d := c[i-1]; d < 0 {
            s += fmt.Sprintf(" - %d", -d)
        } else {
            s += fmt.Sprintf(" + %d", d)
        }
    }
    return
}

func aks(p int) bool {
    c := bc(p)
    c[p]--
    c[0]++
    for _, d := range c {
        if d%int64(p) != 0 {
            return false
        }
    }
    return true
}


expand p = scanl (\z i -> z * (p-i+1) `div` i) 1 [1..p]

test p | p < 2     = False
       | otherwise = and [mod n p == 0 | n <- init . tail $ expand p]

printPoly [1] = "1"
printPoly p   = concat [ unwords [pow i, sgn (l-i), show (p!!(i-1))]
                       | i <- [l-1,l-2..1] ] where
    l = length p
    sgn i = if even i then "+" else "-"
    pow i = take i "x^" ++ if i > 1 then show i else ""

main = do
    putStrLn "-- p: (x-1)^p for small p"
    putStrLn $ unlines [show i ++ ": " ++ printPoly (expand i) | i <- [0..10]]
    putStrLn "-- Primes up to 100:"
    print (filter test [1..100])


import Data.Vect

-- Computes Binomial Coefficients
binCoef : Nat -> Nat -> Nat
binCoef _ Z = (S Z)
binCoef (S n) (S k) =
    if n == k then (S Z) else ((S n) * (binCoef n k)) `div` (S k)

-- Binomial Expansion Of (x - 1)^p
expansion : (n : Nat) -> Vect (S n) Integer
expansion n = expansion' n 1
  where
    expansion' : (n : Nat) -> Integer -> Vect (S n) Integer
    expansion' (S m) s = s * (toIntegerNat $ binCoef n (n `minus` (S m))) ::
                            expansion' m (s * -1)
    expansion' Z s = [s]

showExpansion : Vect n Integer -> String
showExpansion [] = " "
showExpansion (x::xs) {n = S k} = (if x < 0 then "-" else "") ++
        term x k ++ showExpansion' xs
  where
        term : Integer -> Nat -> String
        term x n = if n == 0 then (show (abs x)) else
                      (if (abs x) == 1 then "" else
                          (show (abs x))) ++ "x" ++
                            (if n == 1 then "" else "^" ++ show n)

        sign : Integer -> String
        sign x = if x >= 0 then " + " else " - "

        showExpansion' : Vect m Integer -> String
        showExpansion' [] = ""
        showExpansion' (y::ys) {m = S k} = sign y ++ term y k ++
                                                showExpansion' ys

natToFin' : (m : Nat) -> Fin (S m)
natToFin' n with (natToFin n (S n))
    natToFin' n | Just y = y

isPrime : Nat -> Bool
isPrime Z = False
isPrime (S Z ) = False
isPrime n = foldl (\divs, term => divs && (term `mod` (toIntegerNat n)) == 0)
              True (fullExpansion $ expansion n)

    -- (x - 1)^p - ((x^p) - 1)
    where fullExpansion : Vect (S m) Integer -> Vect (S m) Integer
          fullExpansion (x::xs) {m} = updateAt (natToFin' m) (+1) $ (x-1)::xs

printExpansions : Nat -> IO ()
printExpansions n = do
      putStrLn "-- p: (x-1)^p for small p"
      sequence_ $ map printExpansion [0..n]
  where printExpansion : Nat -> IO ()
        printExpansion n = do
            print n
            putStr ": "
            putStrLn $ showExpansion $ expansion n

main : IO()
main = do
  printExpansions 10
  putStrLn "\n-- Primes Up To 100:"
  putStrLn $ show $ filter isPrime [0..100]


   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.


public class AksTest {
    private static final long[] c = new long[64];

    public static void main(String[] args) {
        for (int n = 0; n < 10; n++) {
            coeff(n);
            show(n);
        }

        System.out.print("Primes:");
        for (int n = 1; n < c.length; n++)
            if (isPrime(n))
                System.out.printf(" %d", n);

        System.out.println();
    }

    static void coeff(int n) {
        c[0] = 1;
        for (int i = 0; i < n; c[0] = -c[0], i++) {
            c[1 + i] = 1;
            for (int j = i; j > 0; j--)
                c[j] = c[j - 1] - c[j];
        }
    }

    static boolean isPrime(int n) {
        coeff(n);
        c[0]++;
        c[n]--;

        int i = n;
        while (i-- != 0 && c[i] % n == 0)
            continue;
        return i < 0;
    }

    static void show(int n) {
        System.out.print("(x-1)^" + n + " =");
        for (int i = n; i >= 0; i--) {
            System.out.print(" + " + c[i] + "x^" + i);
        }
        System.out.println();
    }
}


var i, p, pascal, primerow, primes, show, _i;

pascal = function() {
  var a;
  a = [];
  return function() {
    var b, i;
    if (a.length === 0) {
      return a = [1];
    } else {
      b = (function() {
        var _i, _ref, _results;
        _results = [];
        for (i = _i = 0, _ref = a.length - 1; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
          _results.push(a[i] + a[i + 1]);
        }
        return _results;
      })();
      return a = [1].concat(b).concat([1]);
    }
  };
};

show = function(a) {
  var degree, i, sgn, show_x, str, _i, _ref;
  show_x = function(e) {
    switch (e) {
      case 0:
        return "";
      case 1:
        return "x";
      default:
        return "x^" + e;
    }
  };
  degree = a.length - 1;
  str = "(x - 1)^" + degree + " =";
  sgn = 1;
  for (i = _i = 0, _ref = a.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {
    str += ' ' + (sgn > 0 ? "+" : "-") + ' ' + a[i] + show_x(degree - i);
    sgn = -sgn;
  }
  return str;
};

primerow = function(row) {
  var degree;
  degree = row.length - 1;
  return row.slice(1, degree).every(function(x) {
    return x % degree === 0;
  });
};

p = pascal();

for (i = _i = 0; _i <= 7; i = ++_i) {
  console.log(show(p()));
}

p = pascal();

p();

p();

primes = (function() {
  var _j, _results;
  _results = [];
  for (i = _j = 1; _j <= 49; i = ++_j) {
    if (primerow(p())) {
      _results.push(i + 1);
    }
  }
  return _results;
})();

console.log("");

console.log("The primes upto 50 are: " + primes);


# add_pairs is a helper function for optpascal/0
# Input: an OptPascal array
# Output: the next OptPascal array (obtained by adding adjacent items,
# but if the last two items are unequal, then their sum is repeated)
def add_pairs:
  if length <= 1 then .
  elif length == 2 then (.[0] + .[1]) as $S
  | if (.[0] == .[1]) then [$S]
    else [$S,$S]
    end
  else [.[0] + .[1]] + (.[1:]|add_pairs)
  end;

# Input: an OptPascal row
# Output: the next OptPascalRow
def next_optpascal: [1] + add_pairs;

# generate a stream of OptPascal arrays, beginning with []
def optpascals: [] | recurse(next_optpascal);

# generate a stream of Pascal arrays
def pascals:
  # pascalize takes as input an OptPascal array and produces
  # the corresponding Pascal array;
  # if the input ends in a pair, then peel it off before reversing it.
  def pascalize:
  . + ((if .[-2] == .[-1] then .[0:-2] else .[0:-1] end) | reverse);

  optpascals | pascalize;

# Input: integer n
# Output: the n-th Pascal row
def pascal: nth(.; pascals);

def optpascal: nth(.; optpascals);


function polycoefs(n::Int64)
    pc = typeof(n)[]
    if n < 0
        return pc
    end
    sgn = one(n)
    for k in n:-1:0
        push!(pc, sgn*binomial(n, k))
        sgn = -sgn
    end
    return pc
end


// version 1.1

fun binomial(n: Int, k: Int): Long = when {
    n < 0 || k < 0 -> throw IllegalArgumentException("negative numbers not allowed")
    k == 0         -> 1L
    k == n         -> 1L
    else           -> {
        var prod = 1L
        var div  = 1L
        for (i in 1..k) {
            prod *= (n + 1 - i)
            div  *= i
            if (prod % div == 0L) {
                prod /= div
                div = 1L
            }
        }
        prod
    }
}

fun isPrime(n: Int): Boolean {
    if (n < 2) return false
    return (1 until n).none { binomial(n, it) % n.toLong() != 0L }
}

fun main(args: Array<String>) {
    var coeff: Long
    var sign: Int
    var op: String
    for (n in 0..9) {
        print("(x - 1)^$n = ")
        sign = 1
        for (k in n downTo 0) {
            coeff = binomial(n, k)
            op = if (sign == 1) " + " else " - "
            when (k) {
                n    -> print("x^$n")
                0    -> println("${op}1")
                else -> print("$op${coeff}x^$k")
            }
            if (n == 0) println()
            sign *= -1
        }
    }
    // generate primes under 62
    var p = 2
    val primes = mutableListOf<Int>()
    do {
        if (isPrime(p)) primes.add(p)
        if (p != 2) p += 2 else p = 3
    }
    while (p < 62)
    println("\nThe prime numbers under 62 are:")
    println(primes)
}


-- AKS test for primes, in Lua, 6/23/2020 db
local function coefs(n)
  local list = {[0]=1}
  for k = 0, n do list[k+1] = math.floor(list[k] * (n-k) / (k+1)) end
  for k = 1, n, 2 do list[k] = -list[k] end
  return list
end

local function isprimeaks(n)
  local c = coefs(n)
  c[0], c[n] = c[0]-1, c[n]+1
  for i = 0, n do
    if (c[i] % n ~= 0) then return false end
  end
  return true
end

local function pprintcoefs(n, list)
  local result = ""
  for i = 0, n do
    local s = i==0 and "" or list[i]>=0 and " + " or " - "
    local c, e = math.abs(list[i]), n-i
    if (c==1 and e > 0) then c = "" end
    local x = e==0 and "" or e==1 and "x" or "x^"..e
    result = result .. s .. c .. x
  end
  print("(x-1)^" .. n .." : " .. result)
end

for i = 0, 9 do
  pprintcoefs(i, coefs(i))
end

local primes = {}
for i = 2, 53 do
  if (isprimeaks(i)) then primes[#primes+1] = i end
end
print(table.concat(primes, ", "))


{require lib_BN}  // for big numbers

1) pascalian binomial coefficient C(n,p) = n!/(p!(n-p)!) = (n*(n-1)...(n-p+1))/(p*(p-1)...2*1)

{def coeff
 {lambda {:n :p}
  {BN.intPart
   {BN./ {S.reduce BN.* {S.serie :n {- :n :p -1} -1}}
         {S.reduce BN.* {S.serie :p 1 -1}}}}}}
-> coeff

2) polynomial expansions of (x − 1)^p

{def sign
 {lambda {:n}
  {if {= {% :n 2} 0} then + else -}}}
-> sign

{def coeffs
 {lambda {:n}
  {br}(x - 1)^:n =
   {if {= :n 0}
   then + 1x^0
   else {if {= :n 1}
   then + 1x^1 - 1x^0
   else {sign 0} 1x^:n
        {S.map {{lambda {:p :n} {sign {- :p :n}} {coeff :p :n}x^{- :p :n}} :n}
                {S.serie 1 {- :n 1}}}
        {sign :n} 1x^0}}}}
-> coeffs

{S.map coeffs {S.serie 0 7}}
->
(x - 1)^0 = + 1x^0
(x - 1)^1 = + 1x^1 - 1x^0
(x - 1)^2 = + 1x^2 - 2x^1 + 1x^0
(x - 1)^3 = + 1x^3 + 3x^2 - 3x^1 - 1x^0
(x - 1)^4 = + 1x^4 - 4x^3 + 6x^2 - 4x^1 + 1x^0
(x - 1)^5 = + 1x^5 + 5x^4 - 10x^3 + 10x^2 - 5x^1 - 1x^0
(x - 1)^6 = + 1x^6 - 6x^5 + 15x^4 - 20x^3 + 15x^2 - 6x^1 + 1x^0
(x - 1)^7 = + 1x^7 + 7x^6 - 21x^5 + 35x^4 - 35x^3 + 21x^2 - 7x^1 - 1x^0

3) primality test

Taking into account the symmetry of the list of coefficients and the uselessness of the sign
in the calculation of the divisibility, one can limit the tests to half of the list,
and define a simplified function, aks_coeffs:

{def aks_coeffs
 {lambda {:n}
  {S.map {coeff :n} {S.serie 1 {+ {/ {- :n 1} 2} 1}}}}}
-> aks_coeffs

{def divide
 {lambda {:a :b}
  {= {BN.compare {BN.% :b :a} 0} 0}}}
-> divide

{def isprime
 {lambda {:n}
  {if {and {S.map {divide :n} {aks_coeffs :n}}} then :n else .}}}
-> isprime

{S.map isprime {S.serie 2 100}}
-> 2 3 . 5 . 7 . . . 11 . 13 . . . 17 . 19 . . . 23 . . . . . 29 . 31 . . . . . 37 . . . 41 . 43 . . . 47
. . . . . 53 . . . . . 59 . 61 . . . . . 67 . . . 71 . 73 . . . . . 79 . . . 83 . . . . . 89 . . . . . . . 97 . . .


global pasTriMax
pasTriMax = 61
dim pasTri(pasTriMax + 1)

for n = 0 to 9
  call expandPoly n
next n
for n = 2 to pasTriMax
  if isPrime(n) <> 0 then
    print using("###", n);
  end if
next n
print
end

sub expandPoly n
  n = int(n)
  dim vz$(1)
  vz$(0) = "+"
  vz$(1) = "-"
  if n > pasTriMax then
    print n; " is out of range"
    end
  end if
  select case n
    case 0
      print "(x-1)^0 = 1"
    case 1
      print "(x-1)^1 = x-1"
    case else
      call pascalTriangle n
      print "(x-1)^"; n; " = ";
      print "x^"; n;
      bVz = 1
      nDiv2 = int(n / 2)
      for j = n - 1 to nDiv2 + 1 step -1
        print vz$(bVz); pasTri(n - j); "*x^"; j;
        bVz = abs(1 - bVz)
      next j
      for j = nDiv2 to 2 step -1
        print vz$(bVz); pasTri(j); "*x^"; j;
        bVz = abs(1 - bVz)
      next j
      print vz$(bVz); pasTri(1); "*x";
      bVz = abs(1 - bVz)
      print vz$(bVz); pasTri(0)
  end select
end sub

function isPrime(n)
  n = int(n)
  if n > pasTriMax then
    print n; " is out of range"
    end
  end if
  call pascalTriangle n
  res = 1
  i = int(n / 2)
  while res and (i > 1)
    res = res and (pasTri(i) mod n = 0)
    i = i - 1
  wend
  isPrime = res
end function

sub pascalTriangle n
  rem Calculate the n'th line 0.. middle
  n = int(n)
  pasTri(0) = 1
  j = 1
  while j <= n
    j = j + 1
    k = int(j / 2)
    pasTri(k) = pasTri(k - 1)
    for k = k to 1 step -1
      pasTri(k) = pasTri(k) + pasTri(k - 1)
    next k
  wend
end sub


Print["powers of (x-1)"]
(x - 1)^( Range[0, 7]) // Expand // TableForm
Print["primes under 50"]
poly[p_] := (x - 1)^p - (x^p - 1) // Expand;
coefflist[p_Integer] := Coefficient[poly[p], x, #] & /@ Range[0, p - 1];
AKSPrimeQ[p_Integer] := (Mod[coefflist[p] , p] // Union) == {0};
Select[Range[1, 50], AKSPrimeQ]


from math import binom
import strutils

# Table of unicode superscript characters.
const Exponents: array[0..9, string] = ["⁰", "¹", "²", "³", "⁴", "⁵", "⁶", "⁷", "⁸", "⁹"]

iterator coeffs(n: int): int =
  ## Yield the coefficients of the expansion of (x - 1)ⁿ.
  var sign = 1
  for k in 0..n:
    yield binom(n, k) * sign
    sign = -sign

iterator polyExpansion(n: int): tuple[c, e: int] =
  ## Yield the coefficients and the exponents of the expansion of (x - 1)ⁿ.
  var e = n
  for c in coeffs(n):
    yield(c, e)
    dec e

proc termString(c, e: int): string =
  ## Return the string for the term c * e^n.
  if e == 0:
    result.addInt(c)
  else:
    if c != 1:
      result.addInt(c)
    result.add('x')
    if e != 1:
      result.add(Exponents[e])

proc polyString(n: int): string =
  ## Return the string for the expansion of (x - 1)ⁿ.
  for (c, e) in polyExpansion(n):
    if c < 0:
      result.add(" - ")
    elif e != n:
      result.add(" + ")
    result.add(termString(abs(c), e))

proc isPrime(n: int): bool =
  ## Check if a number is prime using the polynome expansion.
  result = true
  for (c, e) in polyExpansion(n):
    if e in 1..(n-1):   # xⁿ and 1 are eliminated by the subtraction.
      if c mod n != 0:
        return false

#---------------------------------------------------------------------------------------------------

echo "Polynome expansions:"
for p in 0..9:
  echo "(x - 1)$1 = $2".format(Exponents[p], polyString(p))

var primes: string
for p in 2..34:
  if p.isPrime():
    primes.addSep(", ", 0)
    primes.addInt(p)
echo "\nPrimes under 35: ", primes

for p in 35..50:
  if p.isPrime():
    primes.add(", ")
    primes.addInt(p)
echo "\nPrimes under 50: ", primes


#require "gen"
#require "zarith"
open Z
let range ?(step=one) i j = if i = j then Gen.empty else Gen.unfold (fun k ->
    if compare i j = compare k j then Some (k, (add step k)) else None) i

(* kth coefficient of (x - 1)^n *)
let coeff n k =
  let numer = Gen.fold mul one
    (range n (sub n k) ~step:minus_one) in
  let denom = Gen.fold mul one
    (range k zero ~step:minus_one) in
  div numer denom |> mul @@
    if
      compare k n < 0 && is_even k
    then
      minus_one
    else
      one

(* coefficient series for (x - 1)^n, k=[0..n] *)
let coeff_series n =
  Gen.map (coeff n) (range zero (succ n))

let middle g = Gen.drop 1 g |> Gen.peek |> Gen.filter_map
  (function (_, None) -> None | (e, _) -> Some e)

let is_mod_p ~p n = rem n p = zero

let aks p =
  coeff_series p |> middle |> Gen.for_all (is_mod_p ~p)

let _ =
  print_endline "coefficient series n (k[0] .. k[n])";
  Gen.iter
    (fun n -> Format.printf "%d (%s)\n" (to_int n)
      (Gen.map to_string (coeff_series n) |> Gen.to_list |> String.concat " "))
    (range zero (of_int 10));
  print_endline "";
  print_endline ("primes < 50 per AKS: " ^
    (Gen.filter aks (range (of_int 2) (of_int 50)) |>
    Gen.map to_string |> Gen.to_list |> String.concat " "))


import: mapping

: nextCoef( prev -- [] )
| i |
   Array new 0 over dup
   prev size 1- loop: i [ prev at(i) prev at(i 1+) - over add ]
   0 over add
;

: coefs( n -- [] )
    [ 0, 1, 0 ] #nextCoef times(n) extract(2, n 2 + ) ;

: prime?( n -- b)
    coefs( n ) extract(2, n) conform?( #[n mod 0 == ] ) ;

: aks
| i |
   0 10 for: i [ System.Out "(x-1)^" << i << " = " << coefs( i ) << cr ]
   50 seq filter( #prime? ) apply(#.) printcr
;


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;
AKS(n)=my(X=('x-1)*Mod(1,n));X^n=='x^n-1;
select(AKS, [1..50])


const
  pasTriMax = 61;

type
  TPasTri = array[0 .. pasTriMax] of UInt64;

var
  pasTri: TPasTri;

procedure PascalTriangle(n: LongWord);
// Calculate the n'th line 0.. middle
var
  j, k: LongWord;
begin
  pasTri[0] := 1;
  j := 1;
  while j <= n do
  begin
    Inc(j);
    k := j div 2;
    pasTri[k] := pasTri[k - 1];
    for k := k downto 1 do
      Inc(pasTri[k], pasTri[k - 1]);
  end;
end;

function IsPrime(n: LongWord): Boolean;
var
  i: Integer;
begin
  if n > pasTriMax then
  begin
    WriteLn(n, ' is out of range');
    Halt;
  end;

  PascalTriangle(n);
  Result := true;
  i := n div 2;
  while Result and (i > 1) do
  begin
    Result := Result and (pasTri[i] mod n = 0);
    Dec(i);
  end;
end;

procedure ExpandPoly(n: LongWord);
const
  Vz: array[Boolean] of Char = ('+', '-');
var
  j: LongWord;
  bVz: Boolean;
begin
  if n > pasTriMax then
  begin
    WriteLn(n,' is out of range');
    Halt;
  end;

  case n of
    0: WriteLn('(x-1)^0 = 1');
    1: WriteLn('(x-1)^1 = x-1');
  else
    PascalTriangle(n);
    Write('(x-1)^', n, ' = ');
    Write('x^', n);
    bVz := true;
    for j := n - 1 downto n div 2 + 1 do
    begin
      Write(vz[bVz], pasTri[n - j], '*x^', j);
      bVz := not bVz;
    end;
    for j := n div 2 downto 2 do
    begin
      Write(vz[bVz], pasTri[j], '*x^', j);
      bVz := not bVz;
    end;
    Write(vz[bVz], pasTri[1], '*x');
    bVz := not bVz;
    WriteLn(vz[bVz], pasTri[0]);
  end;
end;

var
  n: LongWord;
begin
  for n := 0 to 9 do
    ExpandPoly(n);
  for n := 2 to pasTriMax do
    if IsPrime(n) then
      Write(n:3);
  WriteLn;
end.


use strict;
use warnings;
# Select one of these lines.  Math::BigInt is in core, but quite slow.
use Math::BigInt;  sub binomial { Math::BigInt->new(shift)->bnok(shift) }
# use Math::Pari "binomial";
# use ntheory "binomial";

sub binprime {
  my $p = shift;
  return 0 unless $p >= 2;
  # binomial is symmetric, so only test half the terms
  for (1 .. ($p>>1)) { return 0 if binomial($p,$_) % $p }
  1;
}
sub coef {                   # For prettier printing
  my($n,$e) = @_;
  return $n unless $e;
  $n = "" if $n==1;
  $e==1 ? "${n}x" : "${n}x^$e";
}
sub binpoly {
  my $p = shift;
  join(" ", coef(1,$p),
            map { join("",("+","-")[($p-$_)&1]," ",coef(binomial($p,$_),$_)) }
            reverse 0..$p-1 );
}
print "expansions of (x-1)^p:\n";
print binpoly($_),"\n" for 0..9;
print "Primes to 80: [", join(",", grep { binprime($_) } 2..80), "]\n";


-- demo/rosetta/AKSprimes.exw
-- 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.

sequence c = repeat(0,100)

procedure coef(integer n)
-- out-by-1, ie coef(1)==^0, coef(2)==^1, coef(3)==^2 etc.
    c[n] = 1
    for i=n-1 to 2 by -1 do
        c[i] = c[i]+c[i-1]
    end for
end procedure

function is_aks_prime(integer n)
    coef(n+1); -- (I said it was out-by-1)
    for i=2 to n-1 do   -- (technically "to n" is more correct)
        if remainder(c[i],n)!=0 then
            return 0
        end if
    end for
    return 1
end function

procedure show(integer n)
-- (As per coef, this is (working) out-by-1)
object ci
    for i=n to 1 by -1 do
        ci = c[i]
        if ci=1 then
            if remainder(n-i,2)=0 then
                if i=1 then
                    if n=1 then
                        ci = "1"
                    else
                        ci = "+1"
                    end if
                else
                    ci = ""
                end if
            else
                ci = "-1"
            end if
        else
            if remainder(n-i,2)=0 then
                ci = sprintf("+%d",ci)
            else
                ci = sprintf("-%d",ci)
            end if
        end if
        if i=1 then -- ie ^0
            printf(1,"%s",{ci})
        elsif i=2 then -- ie ^1
            printf(1,"%sx",{ci})
        else
            printf(1,"%sx^%d",{ci,i-1})
        end if
    end for
end procedure

procedure main()
    for n=1 to 10 do -- (0 to 9 really)
        coef(n);
        printf(1,"(x-1)^%d = ", n-1);
        show(n);
        puts(1,'\n');
    end for

    puts(1,"\nprimes (<=53):");
--  coef(2); -- (needed to reset c, if we want to avoid saying 1 is prime...)
    c[2] = 1 -- (this manages "", which is all that call did anyway...)
    for n = 2 to 53 do
        if is_aks_prime(n) then
            printf(1," %d", n);
        end if
    end for
    puts(1,'\n');
    if getc(0) then end if
end procedure
main()


pascal([]) = [1].
pascal(L) = [1|sum_adj(L)].

sum_adj(Row) = Next =>
    Next = L,
    while (Row = [A,B|_])
        L = [A+B|Rest],
        L := Rest,
        Row := tail(Row)
    end,
    L = Row.

show_x(0) = "".
show_x(1) = "x".
show_x(N) = S, N > 1 => S = [x, '^' | to_string(N)].

show_term(Coef, Exp) = cond((Coef != 1; Exp == 0), Coef.to_string, "") ++ show_x(Exp).

expansions(N) =>
    Row = [],
    foreach (I in 0..N-1)
        Row := pascal(Row),
        writef("(x - 1)^%d = ", I),
        Exp = I,
        Sgn = '+',
        foreach (Coef in Row)
            if Exp != I then
                writef(" %w ", Sgn)
            end,
            writef("%s", show_term(Coef, Exp)),
            Exp := Exp - 1,
            Sgn := cond(Sgn == '+', '-', '+')
        end,
        nl
    end.

primerow([], _).
primerow([A,A|_], _).  % end when we've seen half the list.
primerow([A|As], N) :- (A mod N == 0; A == 1), primerow(As, N).

primes_upto(N) = Primes =>
    Primes = L,
    Row = [1, 1],
    foreach (K in 2..N)
        Row := pascal(Row),
        if primerow(Row, K) then
            L = [K|Rest],
            L := Rest
        end
    end,
    L = [].

main =>
    expansions(8),
    writef("%nThe primes upto 50 (via AKS) are: %w%n", primes_upto(50)).


(de pascal (N)
   (let D 1
      (make
         (for X (inc N)
            (link D)
            (setq D
               (*/ D (- (inc N) X) (- X)) ) ) ) ) )

(for (X 0 (> 10 X) (inc X))
   (println X '-> (pascal X) ) )

(println
   (filter
      '((X)
         (fully
            '((Y) (=0 (% Y X)))
            (cdr (head -1 (pascal X))) ) )
      (range 2 50) ) )

(bye)


AKS: procedure options (main, reorder); /* 16 September 2015, derived from Fortran */

  /* Coefficients of polynomial expansion */
  declare coeffs(*) fixed (31) controlled;
  declare n fixed(3);

  /* Point #2 */
  do n = 0 to 7;
    call polynomial_expansion(n, coeffs);
    put edit ( '(x - 1)^', trim(n), ' =' ) (a);
    call print_polynomial (coeffs);
  end;

  /* Point #4 */
   put skip;
  do n = 2 to 35;
    if is_prime(n) then put edit ( trim (n) ) (x(1), a);
  end;

  /* Point #5 */
  put skip;
  do n = 2 to 97;
    if is_prime(n) then put edit ( trim (n) ) (x(1), a);
  end;
  put skip;

  /* Calculate coefficients of (x - 1)^n using binomial theorem */
polynomial_expansion: procedure (n, coeffs);
    declare n fixed binary;
    declare coeffs (*) fixed (31) controlled;
    declare i fixed binary;

    if allocation(coeffs) > 0 then free coeffs;
    allocate coeffs (n+1);

    do i = 1 to n + 1;
      coeffs(i) = binomial(n, i - 1);
      if iand(n - i - 1, 1) = 1 then coeffs(i) = -coeffs(i);
    end;
  end polynomial_expansion;

  /* Calculate binomial coefficient using recurrent relation, as calculation	*/
  /* using factorial overflows too quickly.					*/
binomial: procedure (n, k) returns (fixed(31));
    declare (n, k) fixed;
    declare i fixed;
    declare result fixed (31) initial (n);

    if k = 0 then return (1);

    do i = 1 to k - 1;
      result = (result*(n - i))/(i + 1);
    end;
    return (result);
  end binomial;

  /* Outputs polynomial with given coefficients */
print_polynomial: procedure (coeffs);
    declare coeffs (*) fixed (31) controlled;
    declare ( i, p ) fixed binary;
    declare non_zero bit (1) aligned;
    declare (true initial ('1'b), false initial ('0'b)) bit (1);

    if allocation(coeffs) = 0 then return;

    non_zero = false;

    do i = 1 to hbound(coeffs);
      if coeffs(i) = 0 then iterate;

      p = i - 1;

      if non_zero then
         do;
            if coeffs(i) > 0 then
               put edit ( ' + ' ) (a);
            else
               put edit ( ' - ' ) (a);
         end;
      else
        do;
           if coeffs(i) > 0 then
              put edit ( '   ' ) (a);
           else
              put edit ( ' - ' ) (a);
        end;

      if p = 0 then
        put edit ( trim(abs(coeffs(i))) ) (a);
      else if p = 1 then
         do;
            if coeffs(i) = 1 then
               put edit ( 'x' ) (a);
            else
               put edit ( trim(abs(coeffs(i))), 'x' ) (a);
        end;
      else
        do;
            if coeffs(i) = 1 then
               put edit ( 'x^', trim(p) ) (a);
            else
               put edit (  trim(abs(coeffs(i)) ), 'x^', trim(p)) (a);
        end;

      non_zero = true;
    end;

    put skip;
  end print_polynomial;

  /* Test if n is prime using AKS test. Point #3. */
is_prime: procedure (n) returns (bit (1));
    declare n fixed (15);
    declare result bit (1) aligned;
    declare coeffs (*) fixed (31) controlled;
    declare i fixed binary;

    call polynomial_expansion(n, coeffs);
    coeffs(1) = coeffs(1) + 1;
    coeffs(n + 1) = coeffs(n + 1) - 1;

    result = '1'b;

    do i = 1 to n + 1;
      result = result & (mod(coeffs(i), n) = 0);
    end;

    if allocation(coeffs) > 0 then free coeffs;
    return (result);
  end is_prime;

end AKS;


  prime(P) :-
    pascal([1,P|Xs]),
    append(Xs, [1], Rest),
    forall( member(X,Xs), 0 is X mod P).


EnableExplicit
Define vzr.b = -1, vzc.b = ~vzr, nMAX.i = 10, n.i , k.i

Procedure coeff(nRow.i, Array pd.i(2))
  Define n.i, k.i
  For n=1 To nRow
    For k=0 To n
      If k=0 Or k=n : pd(n,k)=1 : Continue : EndIf
      pd(n,k)=pd(n-1,k-1)+pd(n-1,k)
    Next
  Next
EndProcedure

Procedure.b isPrime(n.i, Array pd.i(2))
  Define m.i
  For m=1 To n-1
    If Not pd(n,m) % n = 0 : ProcedureReturn #False : EndIf
  Next
  ProcedureReturn #True
EndProcedure

Dim pd.i(nMAX,nMAX)
pd(0,0)=1 : coeff(nMAX, pd())
OpenConsole()

For n=0 To nMAX
  Print(RSet(Str(n),3,Chr(32))+": ")
  If vzr : Print("+") : Else : Print("-") : EndIf
  For k=0 To n
    If k>0 : If vzc : Print("+") : Else : Print("-") : EndIf : vzc = ~vzc : EndIf
    Print(RSet(Str(pd(n,k)),3,Chr(32))+Space(3))
  Next
  PrintN("")
  vzr = ~vzr : vzc = ~vzr
Next
PrintN("")

nMAX=50 : Dim pd.i(nMAX,nMAX)
Print("Primes n<=50 : ") : coeff(nMAX, pd())
For n=2 To 50
  If isPrime(n,pd()) : Print(Str(n)+Space(2)) : EndIf
Next
Input()


def expand_x_1(n):
# This version uses a generator and thus less computations
    c =1
    for i in range(n//2+1):
        c = c*(n-i)//(i+1)
        yield c

def aks(p):
    if p==2:
        return True

    for i in expand_x_1(p):
        if i % p:
# we stop without computing all possible solutions
            return False
    return True


AKS<-function(p){
  i<-2:p-1
  l<-unique(factorial(p) / (factorial(p-i) * factorial(i)))
  if(all(l%%p==0)){
    print(noquote("It is prime."))
  }else{
   print(noquote("It isn't prime."))
  }
}


#lang racket
(require math/number-theory)

;; 1. coefficients of expanded polynomial (x-1)^p
;;    produces a vector because in-vector can provide a start
;;    and stop (of 1 and p) which allow us to drop the (-1)^p
;;    and the x^p terms, respectively.
;;
;;    (vector-ref (coefficients p) e) is the coefficient for p^e
(define (coefficients p)
  (for/vector ((e (in-range 0 (add1 p))))
    (define sign (expt -1 (- p e)))
    (* sign (binomial p e))))

;; 2. Show the polynomial expansions from p=0 .. 7 (inclusive)
;; (it's possible some of these can be merged...)
(define (format-coefficient c e leftmost?)
  (define (format-c.x^e c e)
    (define +c (abs c))
    (match* (+c e)
      [(_ 0) (format "~a" +c)]
      [(1 _) (format "x^~a" e)]
      [(_ _) (format "~ax^~a" +c e)]))
  (define +/- (if (negative? c) "-" "+"))
  (define +c.x^e (format-c.x^e c e))
  (match* (c e leftmost?)
    [(0 _ _) ""]
    [((? negative?) _ #t) (format "-~a" +c.x^e)]
    [(_ _ #t) +c.x^e]
    [(_ _ _) (format " ~a ~a" +/- +c.x^e)]))

(define (format-polynomial cs)
  (define cs-length (sequence-length cs))
  (apply
   string-append
   (reverse ; convention is to display highest exponent first
    (for/list ((c cs) (e (in-naturals)))
      (format-coefficient c e (= e (sub1 cs-length)))))))

(for ((p (in-range 0 (add1 11))))
  (printf "p=~a: ~a~%" p (format-polynomial (coefficients p))))

;; 3. AKS primeality test
(define (prime?/AKS p)
  (define cs (coefficients p))
  (and
   (or (= (vector-ref cs 0) -1) ; c_0 = -1 -> c_0 - (-1) = 0
       (divides? p 2))        ; c_0 = 1 -> c_0 - (-1) = 2 -> divides?
   (for/and ((c (in-vector cs 1 p))) (divides? p c))))

;; there is some discussion (see Discussion) about what to do with the perennial "1"
;; case. This is my way of saying that I'm ignoring it
(define lowest-tested-number 2)

;; 4. list of numbers < 35 that are prime (note that 1 is prime
;;    by the definition of the AKS test for primes):
(displayln (for/list ((i (in-range lowest-tested-number 35)) #:when (prime?/AKS i)) i))

;; 5. stretch goal: all prime numbers under 50
(displayln (for/list ((i (in-range lowest-tested-number 50)) #:when (prime?/AKS i)) i))
(displayln (for/list ((i (in-range lowest-tested-number 100)) #:when (prime?/AKS i)) i))


constant expansions = [1], [1,-1], -> @prior { [|@prior,0 Z- 0,|@prior] } ... *;

sub polyprime($p where 2..*) { so expansions[$p].[1 ..^ */2].all %% $p }

# Showing the expansions:

say ' p: (x-1)ᵖ';
say '-----------';

sub super ($n) {
    $n.trans: '0123456789'
           => '⁰¹²³⁴⁵⁶⁷⁸⁹';
}

for ^13 -> $d {
    say $d.fmt('%2i: '), (
        expansions[$d].kv.map: -> $i, $n {
            my $p = $d - $i;
            [~] gather {
                take < + - >[$n < 0] ~ ' ' unless $p == $d;
                take $n.abs                unless $p == $d > 0;
                take 'x'                   if $p > 0;
                take super $p - $i         if $p > 1;
            }
        }
    )
}

#  And testing the function:

print "\nPrimes up to 100:\n  { grep &polyprime, 2..100 }\n";


/* REXX ---------------------------------------------------------------
* 09.02.2014 Walter Pachl
* 22.02.2014 WP fix 'accounting' problem (courtesy GS)
*--------------------------------------------------------------------*/
c.=1
Numeric Digits 100
limit=200
pl=''
mmm=0
Do p=3 To limit
  pm1=p-1
  c.p.1=1
  c.p.p=1
  Do j=2 To p-1
    jm1=j-1
    c.p.j=c.pm1.jm1+c.pm1.j
    mmm=max(mmm,c.p.j)
    End
  End
Say '(x-1)**0 = 1'
do i=2 To limit
  im1=i-1
  sign='+'
  ol='(x-1)^'im1 '='
  Do j=i to 2 by -1
    If j=2 Then
      term='x  '
    Else
      term='x^'||(j-1)
    If j=i Then
      ol=ol term
    Else
      ol=ol sign c.i.j'*'term
    sign=translate(sign,'+-','-+')
    End
  If i<10 then
    Say ol sign 1
  Do j=2 To i-1
    If c.i.j//(i-1)>0 Then
      Leave
    End
  If j>i-1 Then
    pl=pl (i-1)
  End
Say ' '
Say 'Primes:' subword(pl,2,27)
Say '       ' subword(pl,29)
Say 'Largest coefficient:' mmm
Say 'This has' length(mmm) 'digits'


require 'polynomial'

def x_minus_1_to_the(p)
  return Polynomial.new(-1,1)**p
end

def prime?(p)
  return false if p < 2
  (x_minus_1_to_the(p) - Polynomial.from_string("x**#{p}-1")).coefs.all?{|n| n%p==0}
end

8.times do |n|
  # the default Polynomial#to_s would be OK here; the substitutions just make the
  # output match the other version below.
  puts "(x-1)^#{n} = #{x_minus_1_to_the(n).to_s.gsub(/\*\*/,'^').gsub(/\*/,'')}"
end

puts "\nPrimes below 50:", 50.times.select {|n| prime? n}.join(',')


fn aks_coefficients(k: usize) -> Vec<i64> {
    let mut coefficients = vec![0i64; k + 1];
    coefficients[0] = 1;
    for i in 1..(k + 1) {
        coefficients[i] = -(1..i).fold(coefficients[0], |prev, j|{
            let old = coefficients[j];
            coefficients[j] = old - prev;
            old
        });
    }
    coefficients
}

fn is_prime(p: usize) -> bool {
    if p < 2 {
        false
    } else {
        let c = aks_coefficients(p);
        (1..p / 2 + 1).all(|i| c[i] % p as i64 == 0)
    }
}

fn main() {
    for i in 0..8 {
        println!("{}: {:?}", i, aks_coefficients(i));
    }
    for i in (1..=50).filter(|&i| is_prime(i)) {
        print!("{} ", i);
    }
}


def powerMin1(n: BigInt) = if (n % 2 == 0) BigInt(1) else BigInt(-1)

val pascal = (( Vector(Vector(BigInt(1))) /: (1 to 50)) { (rows, i) =>
    val v = rows.head
    val newVector = ((1 until v.length) map (j =>
        powerMin1(j+i) * (v(j-1).abs + v(j).abs))
    ).toVector
    (powerMin1(i) +: newVector :+ powerMin1(i+v.length)) +: rows
}).reverse

def poly2String(poly: Vector[BigInt]) = ((0 until poly.length) map { i =>
    (i, poly(i)) match {
        case (0, c) => c.toString
        case (_, c) =>
            (if (c >= 0) "+" else "-") +
            (if (c == 1) "x" else c.abs + "x") +
            (if (i == 1) "" else "^" + i)
    }
}) mkString ""

def isPrime(n: Int) = {
    val poly = pascal(n)
    poly.slice(1, poly.length - 1).forall(i => i % n == 0)
}

for(i <- 0 to 7) { println( f"(x-1)^$i = ${poly2String( pascal(i) )}" ) }

val primes = (2 to 50).filter(isPrime)
println
println(primes mkString " ")


;; implement mod m arithmetic with polnomials in x
;; as lists of coefficients, x^0 first.
;;
;; so x^3 + 5 is represented as (5 0 0 1)

(define (+/m m a b)
  ;; add two polynomials
  (cond ((null? a) b)
        ((null? b) a)
        (else (cons (modulo (+ (car a) (car b)) m)
                    (+/m m (cdr a) (cdr b))))))

(define (*c/m m c a)
  ;; multiplication by a constant
  (map (lambda (v) (modulo (* c v) m)) a))

(define (*/m m a b)
  ;; multiply two polynomials
  (let loop ((a a))
    (if (null? a)
        '()
        (+/m m (*c/m m (car a) b)
             (cons 0 (*/m m (cdr a) b))))))

(define (x^n/m m n)
  (if (= n 0)
      '(1)
      (cons 0 (x^n/m m (- n 1)))))

(define (^n/m m a n)
  ;; calculate the n'th power of polynomial a
  (cond ((= n 0) '(1))
        ((= n 1) a)
        (else (*/m m a (^n/m m a (- n 1))))))

;; test case
;;
;; ? lift(Mod((x^3 + 5)*(4 + 3*x + x^2),6))
;; %13 = x^5 + 3*x^4 + 4*x^3 + 5*x^2 + 3*x + 2
;;
;; > (*/m 6 '(5 0 0 1) '(4 3 1))
;; '(2 3 5 4 3 1)
;;
;; working correctly

(define (rosetta-aks-test p)
  (if (or (= p 0) (= p 1))
      #f
      ;; u = (x - 1)^p
      ;; v = (x^p - 1)
      (let ((u (^n/m p (list -1 1) p))
            (v (+/m p (x^n/m p p) (list -1))))
        (every zero? (+/m p u (*c/m p -1 v))))))

;; > (filter rosetta-aks-test (iota 50))
;; '(2 3 5 7 11 13 17 19 23 29 31 37 41 43 47)


clear
xdel(winsid())

stacksize('max')
sz=stacksize();

n=7; //For the expansion up to power of n
g=50; //For test of primes up to g

function X = pascal(g) //Pascal´s triangle
    X(1,1)=1; //Zeroth power
    X(2,1)=1; //First power
    X(2,2)=1;
    for q=3:1:g+1 //From second power use this loop
       X(q,1)=1;
       X(q,q)=1;
        for p=2:1:q-1
            X(q,p)=X(q-1,p-1)+X(q-1,p);
        end
    end
endfunction

Z=pascal(g); //Generate Pascal's triangle up to g

Q(0+1)="(x-1)^0 = 1"; //For nicer display
Q(1+1)="(x-1)^1 = x^1-1"; //For nicer display

disp(Q(1))
disp(Q(2))

function cf=coef(Z,q,p) //Return coeffiecents for nicer display of expansion without "ones"
    if Z(q,p)==1 then
        cf="";
    else
        cf=string(Z(q,p));
    end
endfunction

for q=3:n+1  //Generate and display the expansions
    Q(q)=strcat(["(x-1)^",string(q-1)," = "]);
    sing=""; //Sign of coeff.
        for p=1:q-1 //Number of coefficients equals power minus 1
            Q(q)=strcat([Q(q),sing,coef(Z,q,p),"x^",string(q-p)]);
            if sing=="-" then sing="+"; else sing="-"; end
        end
        Q(q)=strcat([Q(q),sing,string(1)]);
    disp(Q(q))
    clear Q
end

function prime=prime(Z,g)
    prime="true";
    for p=2:g
        if abs(floor(Z(g+1,p)/g)-Z(g+1,p)/g)>0 then
            prime="false";
            break;
        end
    end
endfunction

R="2"; //For nicer display
for r=3:g
    if prime(Z,r)=="true" then
        R=strcat([R, ", ",string(r)]);
    end
end
disp(R)


$ include "seed7_05.s7i";

const func array integer: expand_x_1 (in integer: p) is func
  result
    var array integer: ex is [] (1);
  local
    var integer: i is 0;
  begin
    for i range 0 to p - 1 do
      ex := [] (ex[1] * -(p - i) div (i + 1)) & ex;
    end for;
  end func;

const func boolean: aks_test (in integer: p) is func
  result
    var boolean: aks_test is FALSE;
  local
    var array integer: ex is 0 times 0;
    var integer: idx is 0;
  begin
    if p >= 2 then
      ex := expand_x_1(p);
      ex[1] +:= 1;
      for idx range 1 to pred(length(ex)) until ex[idx] rem p <> 0 do
        noop;
      end for;
      aks_test := idx = length(ex);
    end if;
  end func;

const proc: main is func
  local
    var integer: p is 0;
    var integer: n is 0;
    var integer: e is 0;
  begin
    writeln("# p: (x-1)^p for small p");
    for p range 0 to 11 do
      write(p lpad 3 <& ": ");
      for n key e range expand_x_1(p) do
        write(" ");
        if n >= 0 then
          write("+");
        end if;
        write(n);
        if e > 1 then
          write("x^" <& pred(e));
        end if;
      end for;
      writeln;
    end for;
    writeln;
    writeln("# small primes using the aks test");
    for p range 0 to 61 do
      if aks_test(p) then
        write(p <& " ");
      end if;
    end for;
    writeln;
  end func;


func binprime(p) {
    p >= 2 || return false
    for i in (1 .. p>>1) {
        (binomial(p, i) % p) && return false
    }
    return true
}

func coef(n, e) {
    (e == 0) && return "#{n}"
    (n == 1) && (n = "")
    (e == 1) ? "#{n}x" : "#{n}x^#{e}"
}

func binpoly(p) {
    join(" ", coef(1, p), ^p -> map {|i|
        join(" ", %w(+ -)[(p-i)&1], coef(binomial(p, i), i))
    }.reverse...)
}

say "expansions of (x-1)^p:"
for i in ^10 { say binpoly(i) }
say "Primes to 80: [#{2..80 -> grep { binprime(_) }.join(' ')}]"


func polynomialCoeffs(n: Int) -> [Int] {
    var result = [Int](count : n+1, repeatedValue : 0)

    result[0]=1
    for i in 1 ..< n/2+1 { //Progress up, until reaching the middle value
        result[i] = result[i-1] * (n-i+1)/i;
    }
    for i in n/2+1 ..< n+1 { //Copy the inverse of the first part
        result[i] = result[n-i];
    }
    // Take into account the sign
    for i in stride(from: 1, through: n, by: 2) {
        result[i] = -result[i]
    }

    return result
}

func isPrime(n: Int) -> Bool {

    var coeffs = polynomialCoeffs(n)

    coeffs[0]--
    coeffs[n]++

    for i in 1 ... n {
        if coeffs[i]%n != 0 {
            return false
        }
    }

    return true
}

for i in 0...10 {

    let coeffs = polynomialCoeffs(i)

    print("(x-1)^\(i) = ")
    if i == 0 {
        print("1")
    } else {
        if i == 1 {
            print("x")
        } else {
            print("x^\(i)")
            if i == 2 {
                print("\(coeffs[i-1])x")
            } else {
                for j in 1...(i - 2) {
                    if j%2 == 0 {
                        print("+\(coeffs[j])x^\(i-j)")
                    } else {
                        print("\(coeffs[j])x^\(i-j)")
                    }
                }
                if (i-1)%2 == 0 {
                    print("+\(coeffs[i-1])x")
                } else {
                    print("\(coeffs[i-1])x")
                }
            }
        }
        if i%2 == 0 {
            print("+\(coeffs[i])")
        } else {
            print("\(coeffs[i])")
        }
    }
    println()
}

println()
print("Primes under 50 : ")

for i in 1...50 {
    if isPrime(i) {
        print("\(i) ")
    }
}


proc coeffs {p {signs 1}} {
    set clist 1
    for {set i 0} {$i < $p} {incr i} {
	set clist [lmap x [list 0 {*}$clist] y [list {*}$clist 0] {
	    expr {$x + $y}
	}]
    }
    if {$signs} {
	set s -1
	set clist [lmap c $clist {expr {[set s [expr {-$s}]] * $c}}]
    }
    return $clist
}
proc aksprime {p} {
    if {$p < 2} {
	return false
    }
    foreach c [coeffs $p 0] {
	if {$c == 1} continue
	if {$c % $p} {
	    return false
	}
    }
    return true
}

for {set i 0} {$i <= 7} {incr i} {
    puts -nonewline "(x-1)^$i ="
    set j $i
    foreach c [coeffs $i] {
	puts -nonewline [format " %+dx^%d" $c $j]
	incr j -1
    }
    puts ""
}

set sub35primes {}
for {set i 1} {$i < 35} {incr i} {
    if {[aksprime $i]} {
	lappend sub35primes $i
    }
}
puts "primes under 35: [join $sub35primes ,]"

set sub50primes {}
for {set i 1} {$i < 50} {incr i} {
    if {[aksprime $i]} {
	lappend sub50primes $i
    }
}
puts "primes under 50: [join $sub50primes ,]"


#lang transd

MainModule: {
    poly: (λ n Long()
        (with v Vector<Long>([1])
            (for i in Range(n) do
                (append v (/ (* (get v -1) (- (- n i))) (to-Long (+ i 1))))
            )
            (reverse v)
            (ret v)
        )
    ),

    aks_test: (λ n Long() -> Bool()
        (if (< n 2) (ret false))
        (with v (poly n)
            (set-el v 0 (+ (get v 0) 1))
            (ret (not (any Range(in: v 0 -1) (λ (mod @it n)))))
        )
    ),

    _start: (λ (with v Vector<Long>()
        (for p in Seq( 12 ) do
            (set v (poly p))
            (textout "(x - 1)^" p " = ")
            (for i in v do (textout :sign i "x^" @idx " "))
            (textout "\n")
        )
        (textout "\nList of primes in 2-62 interval:\n")
        (for p in Seq( 2 62 ) do
            (if (aks_test p) (textout p " "))
        )
    ))
}


For n = 0 To 9
  Push n : Gosub _coef : Gosub _drop
  Print "(x-1)^";n;" = ";
  Push n : Gosub _show
  Print
Next

Print
Print "primes (never mind the 1):";

For n = 1 To 34
  Push n : Gosub _isprime
  If Pop() Then Print " ";n;
Next

Print
End

                                       ' show polynomial expansions
_show                                  ' ( n --)
  Do
    If @(Tos()) > -1 Then Print "+";
    Print @(Tos());"x^";Tos();
  While (Tos())
    Push Pop() - 1
  Loop

  Gosub _drop
Return

                                       ' test whether number is a prime
_isprime                               ' ( n --)
  Gosub _coef

  i = Tos()
  @(0) = @(0) + 1
  @(i) = @(i) - 1

  Do While (i) * ((@(i) % Tos()) = 0)
    i = i - 1
  Loop

  Gosub _drop
  Push (i = 0)
Return

                                       ' generate coefficients
_coef                                  ' ( n -- n)
  If (Tos() < 0) + (Tos() > 34) Then End
                                       ' gracefully deal with range issue
  i = 0
  @(i) = 1

  Do While i < Tos()
    j = i
    @(j+1) = 1

    Do While j > 0
      @(j) = @(j-1) - @(j)
      j = j - 1
    Loop

    @(0) = [email protected](0)
    i = i + 1
  Loop
Return

                                       ' drop a value from the stack
_drop                                  ' ( n --)
  If Pop() Endif
Return


'-- 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.
'-- This updated VBA version utilizes the Decimal datatype to handle numbers requiring
'-- more than 32 bits.
Const MAX = 99
Dim c(MAX + 1) As Variant
Private Sub coef(n As Integer)
'-- out-by-1, ie coef(1)==^0, coef(2)==^1, coef(3)==^2 etc.
    c(n) = CDec(1) 'converts c(n) from Variant to Decimal, a 12 byte data type
    For i = n - 1 To 2 Step -1
        c(i) = c(i) + c(i - 1)
    Next i
End Sub
Private Function is_prime(fn As Variant) As Boolean
    fn = CDec(fn)
    Call coef(fn + 1)   '-- (I said it was out-by-1)
    For i = 2 To fn - 1 '-- (technically "to n" is more correct)
        If c(i) - fn * Int(c(i) / fn) <> 0 Then 'c(i) Mod fn <> 0 Then --Mod works upto 32 bit numbers
            is_prime = False: Exit Function
        End If
    Next i
    is_prime = True
End Function
Private Sub show(n As Integer)
'-- (As per coef, this is (working) out-by-1)
    Dim ci As Variant
    For i = n To 1 Step -1
        ci = c(i)
        If ci = 1 Then
            If (n - i) Mod 2 = 0 Then
                If i = 1 Then
                    If n = 1 Then
                        ci = "1"
                    Else
                        ci = "+1"
                    End If
                Else
                    ci = ""
                End If
            Else
                ci = "-1"
            End If
        Else
            If (n - i) Mod 2 = 0 Then
                ci = "+" & ci
            Else
                ci = "-" & ci
            End If
        End If
        If i = 1 Then '-- ie ^0
            Debug.Print ci
        Else
            If i = 2 Then '-- ie ^1
                Debug.Print ci & "x";
            Else
                Debug.Print ci & "x^" & i - 1;
            End If
        End If
    Next i
End Sub
Public Sub AKS_test_for_primes()
    Dim n As Integer
    For n = 1 To 10 '-- (0 to 9 really)
        coef n
        Debug.Print "(x-1)^" & n - 1 & " = ";
        show n
    Next n
    Debug.Print "primes (<="; MAX; "):"
    coef 2 '-- (needed to reset c, if we want to avoid saying 1 is prime...)
    For n = 2 To MAX
        If is_prime(n) Then
            Debug.Print n;
        End If
    Next n
End Sub


fn bc(p int) []i64 {
    mut c := []i64{len: p+1}
    mut r := i64(1)
    for i, half := 0, p/2; i <= half; i++ {
        c[i] = r
        c[p-i] = r
        r = r * i64(p-i) / i64(i+1)
    }
    for i := p - 1; i >= 0; i -= 2 {
        c[i] = -c[i]
    }
    return c
}

fn main() {
    for p := 0; p <= 7; p++ {
        println("$p:  ${pp(bc(p))}")
    }
    for p := 2; p < 50; p++ {
        if aks(p) {
            print("$p ")
        }
    }
    println('')
}

const e = [`²`,`³`,`⁴`,`⁵`,`⁶`,`⁷`]

fn pp(c []i64) string {
    mut s := ''
    if c.len == 1 {
        return c[0].str()
    }
    p := c.len - 1
    if c[p] != 1 {
        s = c[p].str()
    }
    for i := p; i > 0; i-- {
        s += "x"
        if i != 1 {
            s += e[i-2].str()
        }
        d := c[i-1]
        if d < 0 {
            s += " - ${-d}"
        } else {
            s += " + $d"
        }
    }
    return s
}

fn aks(p int) bool {
    mut c := bc(p)
    c[p]--
    c[0]++
    for d in c {
        if d%i64(p) != 0 {
            return false
        }
    }
    return true
}


var bc = Fn.new { |p|
    var c = List.filled(p+1, 0)
    var r = 1
    var half = (p/2).floor
    for (i in 0..half) {
        c[i] = r
        c[p-i] = r
        r = (r * (p-i) / (i+1)).floor
    }
    var j = p - 1
    while (j >= 0) {
        c[j] = -c[j]
        j = j - 2
    }
    return c
}

var e = "²³⁴⁵⁶⁷".codePoints.toList

var pp = Fn.new { |c|
    if (c.count == 1) return "%(c[0])"
    var p = c.count - 1
    var s = ""
    if (c[p] != 1) s = "%(c[p])"
    if (p == 0) return s
    for (i in p..1) {
        s = s + "x"
        if (i != 1) s = s + String.fromCodePoint(e[i-2])
        var d = c[i-1]
        s = s + ((d < 0) ? "  - %(-d)" : "  + %(d)")
    }
    return s
}

var aks = Fn.new { |p|
    var c = bc.call(p)
    c[p] = c[p] - 1
    c[0] = c[0] + 1
    for (d in c) {
        if (d%p != 0) return false
    }
    return true
}

for (p in 0..7) System.print("%(p):  %(pp.call(bc.call(p)))")
System.print("\nAll primes under 50:")
for (p in 2..49) if (aks.call(p)) System.write("%(p) ")
System.print()


F accumulator(n)
   T Accumulator
      Float s
      F (Float n)
         .s = n
      F ()(Float n)
         .s += n
         R .s
   R Accumulator(n)

V x = accumulator(1)
print(x(5))
print(x(2.3))

V x2 = accumulator(3)
print(x2(5))
print(x2(3.3))
print(x2(0))


// 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.

dim c(100)

sub coef(n)
	local i
// out-by-1, ie coef(1)==^0, coef(2)==^1, coef(3)==^2 etc.
    c(n) = 1
    for i = n-1 to 2 step -1
        c(i) = c(i) + c(i-1)
    next
end sub

sub is_prime(n)
	local i

    coef(n+1) // (I said it was out-by-1)
    for i = 2 to n-1   // (technically "to n" is more correct)
        if int(c(i)/n) <> c(i)/n then
            return 0
        end if
    next
    return 1
end sub

sub show(n)
// (As per coef, this is (working) out-by-1)
	local ci, ci$, i

    for i = n to 1 step -1
        ci = c(i)
        if ci = 1 then
            if mod(n-i, 2) = 0 then
                if i = 1 then
                    if n = 1 then
                        ci$ = "1"
                    else
                        ci$ = "+1"
                    end if
                else
                    ci$ = ""
                end if
            else
                ci$ = "-1"
            end if
        else
            if mod(n-i, 2) = 0 then
                ci$ = "+" + str$(ci)
            else
                ci$ = "-" + str$(ci)
            end if
        end if
        if i = 1 then // ie ^0
        	print ci$;
        elsif i=2 then // ie ^1
            print ci$, "x";
        else
            print ci$, "x^", i-1;
        end if
    next
end sub

sub AKS_test_for_primes()
	local n

    for n = 1 to 10 // (0 to 9 really)
        coef(n)
        print "(x-1)^", n-1, " = ";
        show(n)
        print
    next

    print "\nprimes (<=53): ";

    c(2) = 1 // (this manages "", which is all that call did anyway...)
    for n = 2 to 53
        if is_prime(n) then
            print " ", n;
        end if
    next
    print
end sub

AKS_test_for_primes()


const std = @import("std");
const assert = std.debug.assert;
const stdout = std.io.getStdOut().writer();

pub fn main() !void {
    var i: u6 = 0;
    while (i < 8) : (i += 1)
        try showBinomial(i);

    try stdout.print("\nThe primes upto 50 (via AKS) are: ", .{});
    i = 2;
    while (i <= 50) : (i += 1) if (aksPrime(i))
        try stdout.print("{} ", .{i});
    try stdout.print("\n", .{});
}

fn showBinomial(n: u6) !void {
    const row = binomial(n).?;
    var sign: u8 = '+';
    var exp = row.len;
    try stdout.print("(x - 1)^{} =", .{n});
    for (row) |coef| {
        try stdout.print(" ", .{});
        if (exp != row.len)
            try stdout.print("{c} ", .{sign});
        exp -= 1;
        if (coef != 1 or exp == 0)
            try stdout.print("{}", .{coef});
        if (exp >= 1) {
            try stdout.print("x", .{});
            if (exp > 1)
                try stdout.print("^{}", .{exp});
        }
        sign = if (sign == '+') '-' else '+';
    }
    try stdout.print("\n", .{});
}

fn aksPrime(n: u6) bool {
    return for (binomial(n).?) |coef| {
        if (coef > 1 and coef % n != 0)
            break false;
    } else true;
}

pub fn binomial(n: u32) ?[]const u64 {
    if (n >= rmax)
        return null
    else {
        const k = n * (n + 1) / 2;
        return pascal[k .. k + n + 1];
    }
}

const rmax = 68;

const pascal = build: {
    @setEvalBranchQuota(100_000);
    var coefficients: [(rmax * (rmax + 1)) / 2]u64 = undefined;
    coefficients[0] = 1;
    var j: u32 = 0;
    var k: u32 = 1;
    var n: u32 = 1;
    while (n < rmax) : (n += 1) {
        var prev = coefficients[j .. j + n];
        var next = coefficients[k .. k + n + 1];
        next[0] = 1;
        var i: u32 = 1;
        while (i < n) : (i += 1)
            next[i] = prev[i] + prev[i - 1];
        next[i] = 1;
        j = k;
        k += n + 1;
    }
    break :build coefficients;
};


\ RossetaCode 'accumulator factory'

\ The 'accumulate' word stores the accumulated value in an array, because arrays
\ are mutable:
: accumulate \ n [m] -- n+m \ [m] -> [n+m]
  a:pop rot n:+
  tuck a:push swap ;

\ To comply with the rules, this takes a number and wraps it in an array, and
\ then curries it.  Since 'curry:' is "immediate", we need to postpone its
\ action using 'p:.

: make-accumulator
  1 a:close
  ' accumulate
  p: curry: ;

\ We 'curry' the initial value along with 'accumulate' to create
\ a new word, '+10', which will give us the accumulated values
10 make-accumulator +10

\ This loop will add 1, then 2, then 3, to the accumulator, which prints the
\ results 11,13,16:
( +10 . cr ) 1 3 loop
bye


report z_accumulator
class acc definition.
  public section.
    methods:
      call importing iv_i type any default 0 exporting ev_r type any,
      constructor importing iv_d type f.
  private section.
    data a_sum type f.
endclass.

class acc implementation.
  method call.
      add iv_i to a_sum.
      ev_r = a_sum.
  endmethod.

start-of-selection.

data: cl_acc type ref to acc,
      lv_ret2 type f,
      lv_ret1 type i.

create object cl_acc exporting iv_d = 1.
cl_acc->call( exporting iv_i = 5 ).
cl_acc->call( exporting iv_i = '2.3' importing ev_r = lv_ret2 ).
cl_acc->call( exporting iv_i = 2 importing ev_r = lv_ret1 ).
write : / lv_ret2 decimals 2 exponent 0 left-justified, / lv_ret1 left-justified.


var BN=Import("zklBigNum");
fcn expand_x_1(p){
    ex := L(BN(1));
    foreach i in (p){ ex.append(ex[-1] * -(p-i) / (i+1)) }
    return(ex.reverse())
 }
fcn aks_test(p){
    if (p < 2) return(False);
    ex := expand_x_1(p);
    ex[0] = ex[0] + 1;
    return(not ex[0,-1].filter('%.fp1(p)));
}
println("# p: (x-1)^p for small p");
foreach p in (12){
    println("%3d: ".fmt(p),expand_x_1(p).enumerate()
       .pump(String,fcn([(n,e)]){"%+d%s ".fmt(e,n and "x^%d".fmt(n) or "")}));
}

println("\n# small primes using the aks test");
println([0..110].filter(aks_test).toString(*));


//Throw an error if a non-number argument is used. (typeof evaluates to
// "number" for both integers and reals)
function checkType(obj:Object):void {
    if(typeof obj != "number")
	throw new ArgumentError("Expected integer or float argument. Recieved " + typeof obj);
}
function accumulator(sum:Object):Function {
    checkType(sum);
    return function(n:Object):Object {checkType(n); return sum += n};
}
var acc:Function=accumulator(2);
trace(acc(10));
trace(acc(4));
trace(acc("123")); //This causes an ArgumentError to be thrown.


with Accumulator;
with Ada.Text_IO; use Ada.Text_IO;

procedure Example is
   package A is new Accumulator;
   package B is new Accumulator;
begin
   Put_Line (Integer'Image (A.The_Function (5)));
   Put_Line (Integer'Image (B.The_Function (3)));
   Put_Line (Float'Image (A.The_Function (2.3)));
end;


function accumulator (sum:real) {
    return function(n:real) { return sum += n }
}

var x = accumulator(1)
x(5)
println (accumulator)
println (x(2.3))


af(list l, object o)
{
    l[0] = l[0] + o;
}

main(void)
{
    object (*f)(object);

    f = af.apply(list(1));

    f(5);
    af.apply(list(3));
    o_(f(2.3), "\n");

    0;
}


MODE NUMBER =  UNION(INT,REAL,COMPL);

PROC plus = (NUMBER in a, in b)NUMBER: (
    CASE in a IN
        (INT a):   CASE in b IN (INT b): a+b, (REAL b): a+b, (COMPL b): a+b ESAC,
        (REAL a):  CASE in b IN (INT b): a+b, (REAL b): a+b, (COMPL b): a+b ESAC,
        (COMPL a): CASE in b IN (INT b): a+b, (REAL b): a+b, (COMPL b): a+b ESAC
    ESAC
);

main: (

# now override the + and +:= OPerators #
  OP + = (NUMBER a, b)NUMBER: plus(a,b);

  OP +:= = (REF NUMBER lhs, NUMBER rhs)NUMBER:
      lhs := lhs + rhs;

  PROC accumulator  = (REF NUMBER sum)PROC(NUMBER)NUMBER:
      (NUMBER n)NUMBER:
          sum +:= n;

  PROC (NUMBER)NUMBER x = accumulator(LOC NUMBER := 1);
  x(5);
  print(("x:",x(2.3), new line));

  PROC (NUMBER)NUMBER y = accumulator(LOC NUMBER := 100);
  y(500);
  print(("y:",y(230), new line));

  print(("x:",x(0), new line))

)


on accumulator(n)
	-- Returns a new script object
	-- containing a handler.
	script
		on call(i)
			set n to n + i -- Returns n.
		end call
	end script
end accumulator

set x to accumulator(10)
log x's call(1)
set y to accumulator(5)
log y's call(2)
log x's call(3.5)
-- Event Log: (*11*) (*7*) (*14.5*)


use std, array

let A = accumulator 42
print(A 0)
print(A 1)
print(A 10)
print(A 100)

let B = accumulator 4.2
print(B 0)
print(B 1)
print(B 10.0)
print(B 100.4)

~A ; ~B
(: use dbg; check mem leak :)

(: accumulator call :)
=: <accumulator a> <num x> := -> (a.t)
   call ((a.func) as function(any)(a.t)->(a.t)) with (a.data) ((Cgen x) as a.t)

(: accumulator constructors :)
.: accumulator <int x> :. -> int accumulator
   (val (int accumulator) A).init(x)
   (A as Accumulator).func = ( .:<int& accu, int x>:. ->int {accu += x; accu} )
   A

.: accumulator <real x> :. -> real accumulator
   (val (real accumulator) A).init(x)
   (A as Accumulator).func = ( .:<real&accu,real x>:. ->real{accu += x; accu} )
   A

=: <accumulator& a>.init <num x> :=
   a = new (Accumulator)
   a.data = (new array of 1 a.t)
   *(a.data as (a.t*)) = Cgen x

(: accumulator destructor :)
.: del Accumulator <Accumulator a>:.
   free a.data
   free a
=: ~ <accumulator a> := {del Accumulator a}

(: accumulator type :)
class Accumulator
  function	func
  any		data

=: [<type t=(int)>] accumulator := -> type
   Accumulator.prefix
   Accumulator.suffix

autocast accumulator<->Accumulator


fun accumulator(var sum): :: Real -> _
    n => sum += n

let f = accumulator!(5)
print f(5)   # 10
print f(10)  # 20
print f(2.4) # 22.4


      x = FNaccumulator(1)
      dummy = FN(x)(5)
      dummy = FNaccumulator(3)
      PRINT FN(x)(2.3)
      END

      DEF FNaccumulator(sum)
      LOCAL I%, P%, Q%
      DIM P% 53 : Q% = !^FNdummy()
      FOR I% = 0 TO 49 : P%?I% = Q%?I% : NEXT
      P%!I% = P% : sum = FN(P%+I%)(sum)
      = P%+I%

      DEF FNdummy(n)
      PRIVATE sum
      sum += n
      = sum


( ( accumulator
  =
    .
      ' ( add sum object
        .   (object=add=$arg+!arg)
          & !(object.add):?sum
          & '($($sum)+!arg):(=?(object.add))
          & !sum
        )
  )
& accumulator$1:(=?x)
& x$5
& accumulator$3
& out$(x$23/10)
)


accumulator = { sum |
  { n | sum = sum + n }
}

x = accumulator 1
x 5
accumulator 3 #Does not affect x
p x 2.3 #Prints 8.3 (1 + 5 + 2.3)


Acc ← {
  𝕊 sum:
  {sum+↩𝕩}
}
x ← Acc 1
X 5
Acc 3
X 2.3


#include <stdio.h>
//~ Take a number n and return a function that takes a number i
#define ACCUMULATOR(name,n) __typeof__(n) name (__typeof__(n) i) { \
    static __typeof__(n) _n=n; LOGIC; }
//~ have it return n incremented by the accumulation of i
#define LOGIC return _n+=i
ACCUMULATOR(x,1.0)
ACCUMULATOR(y,3)
ACCUMULATOR(z,'a')
#undef LOGIC
int main (void) {
    printf ("%f\n", x(5));   /* 6.000000 */
    printf ("%f\n", x(2.3)); /* 8.300000 */
    printf ("%i\n", y(5.0)); /* 8 */
    printf ("%i\n", y(3.3)); /* 11 */
    printf ("%c\n", z(5));   /* f */
    return 0;
}


using System;

class Program
{
    static Func<dynamic, dynamic> Foo(dynamic n)
    {
        return i => n += i;
    }

    static void Main(string[] args)
    {
        var x = Foo(1);
        x(5);
        Foo(3);
        Console.WriteLine(x(2.3));
    }
}


#include <iostream>

class Acc
{
public:
    Acc(int init)
        : _type(intType)
        , _intVal(init)
    {}

    Acc(float init)
        : _type(floatType)
        , _floatVal(init)
    {}

    int operator()(int x)
    {
        if( _type == intType )
        {
            _intVal += x;
            return _intVal;
        }
        else
        {
            _floatVal += x;
            return static_cast<int>(_floatVal);
        }
    }

    float operator()(float x)
    {
        if( _type == intType )
        {
            _floatVal = _intVal + x;
            _type = floatType;
            return _floatVal;
        }
        else
        {
            _floatVal += x;
            return _floatVal;
        }
    }
private:
    enum {floatType, intType} _type;
    float _floatVal;
    int _intVal;
};

int main()
{
    Acc a(1);
    a(5);
    Acc(3);
    std::cout << a(2.3f);
    return 0;
}


shared void run() {
    Integer|Float accumulator
            (variable Integer|Float n)
            (Integer|Float i)
        =>  switch (i)
            case (is Integer)
                (n = n.plusInteger(i))
            case (is Float)
                (n = i + (switch(prev = n)
                          case (is Float) prev
                          case (is Integer) prev.float));

    value x = accumulator(1);
    print(x(5));
    print(accumulator(3));
    print(x(2.3));
}


(defn accum [n]
  (let [acc (atom n)]
    (fn [m] (swap! acc + m))))


accumulator = (sum) ->
  (n) -> sum += n

f = accumulator(1)
console.log f(5)
console.log f(2.3)


(defun accumulator (sum)
  (lambda (n)
    (incf sum n)))


# Make types a bit easier with an alias
alias Num = Int32 | Int64 | Float32 | Float64

def accumulator(sum : Num)
  # This proc is very similar to a Ruby lambda
  ->(n : Num){ sum += n }
end

x = accumulator(5)
puts x.call(5)   #=> 10
puts x.call(10)  #=> 20
puts x.call(2.4) #=> 22.4


import std.stdio;

void main() {
    auto x = acc(1);
    x(5);
    acc(3);
    writeln(x(2.3));
}

auto acc(U = real, T)(T initvalue) { // U is type of the accumulator
    auto accum = cast(U)initvalue ;
    return (U n) { return accum += n ; } ;
}


accum n:
	labda i:
		set :n + n i
		n

local :x accum 1
drop x 5
drop accum 3
!print x 2.3


program Accumulator_factory;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Variants;

type
  TFn = TFunc<variant, variant>;

function Foo(n: variant): TFn;
begin
  Result :=
    function(i: variant): variant
    begin
      n:= n + i;
      Result := n;
    end;
end;

begin
  var x := Foo(1);
  x(5);
  Foo(3); // do nothing
  Writeln(x(2.3));
  Readln;
end.


def foo(var x) {
  return fn y { x += y }
}


(define-syntax-rule (inc x v) (set! x (+ x v)))
(define (accumulator (sum 0)) (lambda(x) (inc sum x) sum))

(define x (accumulator 1)) → x
(x 5) → 6

;; another closure
(accumulator 3) → (🔒 λ (_x) (📝 #set! sum (#+ sum _x)) sum)

(x 2.3) → 8.3


function(acc)
    = (n => acc.append:n);

accumulator(n)
    = function(new Variable(n));

public program()
{
    var x := accumulator(1);

    x(5);

    var y := accumulator(3);

    console.write(x(2.3r))
}


defmodule AccumulatorFactory do
  def new(initial) do
    {:ok, pid} = Agent.start_link(fn() -> initial end)
    fn (a) ->
      Agent.get_and_update(pid, fn(old) -> {a + old, a + old} end)
    end
  end
end


-module(acc_factory).
-export([loop/1,new/1]).

loop(N)->
    receive
        {P,I}->
            S =N+I, P!S, loop(S)
    end.

new(N)->
    P=spawn(acc_factory,loop,[N]),
    fun(I)->
            P!{self(),I},
            receive
                V-> V
            end
    end.


PROGRAM ACCUMULATOR

PROCEDURE ACCUMULATOR(SUM,N,A->SUM)
    IF NOT A THEN SUM=N ELSE SUM=SUM+N
END PROCEDURE

BEGIN
   PRINT(CHR$(12);) ! CLS
   ACCUMULATOR(X,1,FALSE->X)  ! INIT FIRST ACCUMULATOR
   ACCUMULATOR(X,-15,TRUE->X)
   ACCUMULATOR(X,2.3,TRUE->X)

   ACCUMULATOR(Z,3,FALSE->Z)  ! INIT SECOND ACCUMULATOR
   ACCUMULATOR(Z,5,TRUE->Z)
   ACCUMULATOR(Z,2.3,TRUE->Z)
   PRINT(X,Z)
END PROGRAM


// dynamically typed add
let add (x: obj) (y: obj) =
  match x, y with
  | (:? int as m), (:? int as n) -> box(m+n)
  | (:? int as n), (:? float as x)
  | (:? float as x), (:? int as n) -> box(x + float n)
  | (:? float as x), (:? float as y) -> box(x + y)
  | _ -> failwith "Run-time type error"

let acc init =
  let state = ref (box init)
  fun y ->
    state := add !state (box y)
    !state

do
  let x : obj -> obj = acc 1
  printfn "%A" (x 5) // prints "6"
  acc 3 |> ignore
  printfn "%A" (x 2.3) // prints "8.3"


USE: locals
:: accumulator ( n! -- quot ) [ n + dup n! ] ;

1 accumulator
[ 5 swap call drop ]
[ drop 3 accumulator drop ]
[ 2.3 swap call ] tri .


class AccumulatorFactory
{
  static |Num -> Num| accumulator (Num sum)
  {
    return |Num a -> Num|
    { // switch on type of sum
      if (sum is Int)
      { // and then type of a
        if (a is Int)
          return sum = sum->plus(a)
        else if (a is Float)
          return sum = sum->plusFloat(a)
        else
          return sum = sum->plusDecimal(a)
      }
      else if (sum is Float)
      {
        if (a is Int)
          return sum = sum->plusInt(a)
        else if (a is Float)
          return sum = sum->plus(a)
        else
          return sum = sum->plusDecimal(a)
      }
      else // if (sum is Decimal)
      {
        if (a is Int)
          return sum = sum->plusInt(a)
        else if (a is Float)
          return sum = sum->plusFloat(a)
        else
          return sum = sum->plus(a)
      }
    }
  }

  public static Void main ()
  {
    x := accumulator (3.1)
    y := accumulator (3f)
    echo (x(5))              // the Decimal sum combines with an Int
    echo (x(2))
    echo (y(5.1))            // the Float sum combines with a Decimal

    x = accumulator (1)
    x (5)
    accumulator (3)
    echo (x(2.3))          // the Int sum is now a Decimal
  }
}


: accumulator
  create ( n -- ) ,
  does> ( n -- acc+n ) tuck +! @ ;

0 accumulator foo

1 foo .  \ 1
2 foo .  \ 3
3 foo .  \ 6


#define foo(type,g,nn) \
typex function g(i);\
typex i,s,n;\
data s,n/0,nn/;\
s=s+i;\
g=s+n;\
end

      foo(real,x,1)
      foo(integer,y,3)

      program acc
      real x, temp
      integer y, itemp
      temp = x(5.0)
      print *, x(2.3)
      itemp = y(5)
      print *, y(2)
      stop
      end


' FB 1.05.0 Win64

' uses overloaded methods to deal with the integer/float aspect (long and single are both 4 bytes)
Type Bar
  Public:
    Declare Constructor(As Long)
    Declare Constructor(As Single)
    Declare Function g(As Long) As Long
    Declare Function g(As Single) As Single
  Private:
    As Single sum_   '' can't be altered by external code
End Type

Constructor Bar(i As Long)
  sum_ = i
End Constructor

Constructor Bar(s As Single)
  sum_ = s
End Constructor

Function Bar.g(i As Long) As Long
  sum_ += i
  Return sum_  '' would round down to a Long if non-integral Singles had been added previously
End Function

Function Bar.g(s As Single) As Single
  sum_ += s
  Return sum_
End Function

Function foo Overload(i As Long) As Bar  '' returns a Bar object rather than a pointer to Bar.g
  Dim b As Bar = Bar(i)
  Return b
End Function

Function foo Overload(s As Single) As Bar  '' overload of foo to deal with Single argument
  Dim b As Bar = Bar(s)
  Return b
End Function

Dim x As Bar = foo(1)  '' assigns Bar object to x
x.g(5)  '' calls the Long overload of g on the Bar object
foo(3)  '' creates a separate Bar object which is unused
print x.g(2.3) '' calls the Single overload of g on the Bar object and should print 1 + 5 + 2.3 = 8.3

Print
Print "Press any key to quit"
Sleep


package main

import "fmt"

func accumulator(sum interface{}) func(interface{}) interface{} {
    return func(nv interface{}) interface{} {
        switch s := sum.(type) {
        case int:
            switch n := nv.(type) {
            case int:
                sum = s + n
            case float64:
                sum = float64(s) + n
            }
        case float64:
            switch n := nv.(type) {
            case int:
                sum = s + float64(n)
            case float64:
                sum = s + n
            }
        default:
            sum = nv
        }
        return sum
    }
}

func main() {
    x := accumulator(1)
    x(5)
    accumulator(3)
    fmt.Println(x(2.3))
}


#!/usr/bin/env golosh
----
An accumulator factory example for Rosetta Code.
This one uses the box function to create an AtomicReference.
----
module rosetta.AccumulatorFactory

function accumulator = |n| {
  let number = box(n)
  return |i| -> number: accumulateAndGet(i, |a, b| -> a + b)
}

function main = |args| {
  let acc = accumulator(3)
  println(acc(1))
  println(acc(1.1))
  println(acc(10))
  println(acc(100.101))
}


def accumulator = { Number n ->
    def value = n;
    { it = 0 -> value += it}
}


import Control.Monad.ST
import Data.STRef

accumulator :: (Num a) => a -> ST s (a -> ST s a)
accumulator sum0 = do
  sum <- newSTRef sum0
  return $ \n -> do
    modifySTRef sum (+ n)
    readSTRef sum

main :: IO ()
main = print foo
    where foo = runST $ do
                  x <- accumulator 1
                  x 5
                  accumulator 3
                  x 2.3


procedure main()
    a := genAcc(3)
    b := genAcc(5)

    write("        " ,center("a",5),  " ", center("b", 5))
    write("genAcc: ", right(a(4),5),  " ", right(b(4), 5))
    write("genAcc: ", right(a(2),5),  " ", right(b(3),5))
    write("genAcc: ", right(a(4.5),5)," ", right(b(1.3),5))
end

procedure genAcc(n)   # The generator factory
    return makeProc { while i := (n@&source)[1] do n +:= i }
end

procedure makeProc(A) # A Programmer-Defined Control Operation
    return (@A[1],A[1])
end


accumulator := method(sum,
    block(x, sum = sum + x) setIsActivatable(true)
)
x := accumulator(1)
x(5)
accumulator(3)
x(2.3) println  // --> 8.3000000000000007


public class Accumulator
    //implements java.util.function.UnaryOperator<Number> // Java 8
{
    private Number sum;

    public Accumulator(Number sum0) {
	sum = sum0;
    }

    public Number apply(Number n) {
	// Acts like sum += n, but chooses long or double.
	// Converts weird types (like BigInteger) to double.
	return (longable(sum) && longable(n)) ?
	    (sum = sum.longValue() + n.longValue()) :
	    (sum = sum.doubleValue() + n.doubleValue());
    }

    private static boolean longable(Number n) {
	return n instanceof Byte || n instanceof Short ||
	    n instanceof Integer || n instanceof Long;
    }

    public static void main(String[] args) {
	Accumulator x = new Accumulator(1);
	x.apply(5);
	new Accumulator(3);
	System.out.println(x.apply(2.3));
    }
}


function accumulator(sum) {
  return function(n) {
    return sum += n;
  }
}
var x = accumulator(1);
x(5);
console.log(accumulator(3).toString() + '<br>');
console.log(x(2.3));


/* Accumulator factory, in Jsish */
function accumulator(sum) {
    return function(n) {
        return sum += n;
    };
}

provide('accumulatorFactory', '0.6');

if (Interp.conf('unitTest')) {
var x,y;
;x = accumulator(1);
;accumulator;
;x;
;x(5);
;accumulator(3);
;x(2.3);

;y = accumulator(0);
;y;
;x(1);
;y(2);
;x(3);
;y(4);
;x(5);
}

/*
=!EXPECTSTART!=
x = accumulator(1) ==> "function(n) {\n        return sum += n;\n    }"
accumulator ==> "function accumulator(sum) {\n    return function(n) {\n        return sum += n;\n    };\n}"
x ==> "function(n) {\n        return sum += n;\n    }"
x(5) ==> 6
accumulator(3) ==> "function(n) {\n        return sum += n;\n    }"
x(2.3) ==> 8.3
y = accumulator(0) ==> "function(n) {\n        return sum += n;\n    }"
y ==> "function(n) {\n        return sum += n;\n    }"
x(1) ==> 9.3
y(2) ==> 2
x(3) ==> 12.3
y(4) ==> 6
x(5) ==> 17.3
=!EXPECTEND!=
*/


function accumulator(i)
	f(n) = i += n
	return f
end

x = accumulator(1)
@show x(5)

accumulator(3)
@show x(2.3)


// version 1.1

fun foo(n: Double): (d: Double) -> Double {
    var nn = n
    return { nn += it; nn }
}

fun foo(n: Int): (i: Int) -> Int {
    var nn = n
    return { nn += it; nn }
}

fun main(args: Array<String>) {
    val x = foo(1.0) // calls 'Double' overload
    x(5.0)
    foo(3.0)
    println(x(2.3))
    val y = foo(1)   // calls 'Int' overload
    y(5)
    foo(5)
    println(y(2))
}


{def acc
 {lambda {:a :n}
  {+ {A.toS {A.addlast! :n :a}}}}}
-> acc

1) using a global:

{def A {A.new 1}}
-> A
{acc {A} 5}
-> 6
{acc {A} 2.3}
-> 8.3

2) inside a local context:

{let { {:a {A.new 1}}
     } {br}{acc :a 5}
       {br}{acc :a 2.3}
} ->
6
8.3


(defun accum (m)
    (lambda (n)
      (let ((sum (+ m n)))
        `(#(func ,(accum sum))
          #(sum ,sum)))))


function acc(init)
  init = init or 0
  return function(delta)
    init = init + (delta or 0)
    return init
  end
end


\\ M2000 Interpreter
\\ accumulator factory
foo=lambda acc=0 (n as double=0) -> {
      \\ interpreter place this: read n as double=0 as first line of lambda function
      if n=0 then =acc : exit
      acc+=n
      \\ acc passed as a closuer to lambda (a copy of acc in the result lambda function)
      =lambda acc -> {
            ' if stack of values is empty then return a copy of acc
            if empty then =acc : exit
            read x
            \\ x has no type here, can be any numeric type (also can be an object too)
            \\ accumulator is double, and is a closure (a copy of acc in foo)
            acc+=x
            \\ any variable in M2000 hold  first type
            \\ if x is an object then we get error, except if object use this operator
            x=acc
            \\ so we return x type
            =x
      }
}
x=foo(1&)   ' 1& is long type (32bit)
call void x(5) ' 5 is double type (the default type for M2000)
call void foo(3#)   ' void tell to interpreter to throw result, 3# is Currency type
print x([email protected]) ' print 8.3,   [email protected] is Decimal type
print foo()=4 ' print true
def ExpType$(z)=type$(z)
print ExpType$(foo())="Double"
print ExpType$(x(0&))="Long"
print ExpType$(x([email protected]))="Decimal"
print ExpType$(x())="Double"
print ExpType$(foo(20))="lambda"


AccumulatorFactory := proc( initial := 0 )
        local   total := initial;
        proc( val := 1 ) total := total + val end
end proc:


accFactory[initial_] :=
  Module[{total = initial},
    Function[x, total += x]
  ]
x=accFactory[1];
x[5.0];
accFactory[3];
x[2.3]


:- module accum.
:- interface.

:- typeclass addable(T) where [
    func T + T = T
].

:- impure func gen(T) = (impure (func(T)) = T) <= addable(T).

:- implementation.
:- import_module bt_array, univ, int.

:- mutable(states, bt_array(univ), make_empty_array(0), ground, [untrailed]).

gen(N) = F :-
    some [!S] (
        semipure get_states(!:S),
        size(!.S, Size),
        resize(!.S, 0, Size + 1, univ(N), !:S),
        impure set_states(!.S)
    ),
    F = (impure (func(Add)) = M :-
        some [!SF] (
            semipure get_states(!:SF),
            !.SF ^ elem(Size) = U,
            det_univ_to_type(U, M0),
            M = M0 + Add,
            !SF ^ elem(Size) := univ(M),
            impure set_states(!.SF)
        )).


def Foo(n) {
    mutable value : object = n;
    fun (i : object) {
        match(i) {
            |x is int    => match(value) {
                                |y is int => value = x + y;
                                |y is double => value = x + y;
                            }
            |x is double => match(value) {
                                |y is int => value = x + (y :> double);
                                |y is double => value = x + y;
                            }
        }
        value
    }
}

def x = Foo(1);
def y = Foo(2.2);
x(5);
System.Console.WriteLine(x(2.3));
System.Console.WriteLine(y(3));


{
	F Acc(start:Int) {
		sum = start
		F acc(i:Int) {
			sum = sum + i
			sum
		}
	}

	acc = Acc(10)
	echo(acc(5))
	echo(acc(2))
}


proc accumulator[T: SomeNumber](x: T): auto =
  var sum = float(x)
  result = proc (n: float): float =
             sum += n
             result = sum

let acc = accumulator(1)
echo acc(5)             # 6
discard accumulator(3)  # Create another accumulator.
echo acc(2.3)           # 8.3


# The `accumulator factory` task.
#
# Nit has no first-class function.
# A class is used to store the state.
module accumulator_factory

class Accumulator
	# The accumulated sum
	# Numeric is used, so Int and Float are accepted
	private var sum: Numeric
	fun call(n: Numeric): Numeric
	do
		# `add` is the safe `+` method on Numeric
		sum = sum.add(n)
		return sum
	end
end

var x = new Accumulator(1)
x.call(5)
var y = new Accumulator(3)
print x.call(2.3)


bundle Default {
  class Accumulator {
    @sum : Float;

    New(sum : Float) {
      @sum := sum;
    }

    method : public : Call(n : Float) ~ Float {
      @sum += n;
      return @sum;
    }

    function : Main(args : String[]) ~ Nil {
      x := Accumulator->New(1.0);
      x->Call(5.0  );
      x->Call(2.3)->PrintLine();
    }
  }
}


#import <Foundation/Foundation.h>

typedef double (^Accumulator)(double);

Accumulator accumulator_factory(double initial) {
    __block double sum = initial;
    Accumulator acc = ^(double n){
        return sum += n;
    };
    return acc;
}

int main (int argc, const char * argv[]) {
    @autoreleasepool {

        Accumulator x = accumulator_factory(1);
        x(5);
        accumulator_factory(3);
        NSLog(@"%f", x(2.3));

    }
    return 0;
}


let accumulator sum0 =
  let sum = ref sum0 in
  fun n ->
    sum := !sum +. n;
    !sum;;

let _ =
  let x = accumulator 1.0 in
  ignore (x 5.0);
  let _ = accumulator 3.0 in
  Printf.printf "%g\n" (x 2.3)
;;


# not a function file:
1;
function fun = foo(init)
  currentSum = init;
  fun = @(add) currentSum = currentSum + add; currentSum;
endfunction

x = foo(1);
x(5);
foo(3);
disp(x(2.3));


: foo( n -- bl )
   #[ n swap + dup ->n ] ;


x = .accumulator~new(1)    -- new accumulator with initial value of "1"
x~call(5)
x~call(2.3)
say "Accumulator value is now" x    -- displays current value

-- an accumulator class instance can be instantiated and
-- used to sum up a series of numbers
::class accumulator
::method init    -- instance initializer...sets the accumulator initial value
  expose sum
  use strict arg sum = 0 -- sets default sum value if not specified

-- perform the accumulator function
::method call
  expose sum
  use strict arg n
  sum += n       -- bump the accumulator
  return sum     -- return the new value

-- extra credit...display the current accumulator value
::method string
  expose sum
  return sum


Class AccumFactory
'=================

  double v

  method constructor()
  end method

  method destructor()
  end method

  method Accum(double n) as AccumFactory
  new AccumFactory af
  af.v=v+n
  return af
  end method

  method FloatValue() as double
  return v
  end method

  method IntValue() as sys
  return v
  end method

  method StringValue(sys dp=16) as string
  return str v,dp
  end method

end class

'=======================
'TESTS (all results: PI)
'=======================

new AccumFactory af

'GENERATE ACCUMULATORS

let a=af.Accum(1)   'integer
let b=a.Accum(pi)   'float
let c=b.Accum("-1") 'string

'STRING OUTPUT

print c.StringValue(4) ' show 4 decimal places

'FLOAT OUTPUT

print c.FloatValue

'USE FUNCTIONS IN EXPRESSION

print 10 * c.FloatValue() / ( 10 * a.IntValue() )

'FINISH

del af : del a : del b : del c


declare
  fun {Acc Init}
     State = {NewCell Init}
  in
     fun {$ X}
        OldState
     in
        {Exchange State OldState} = {Sum OldState X}
     end
  end

  fun {Sum A B}
     if {All [A B] Int.is} then A+B
     else {ToFloat A}+{ToFloat B}
     end
  end

  fun {ToFloat X}
     if {Float.is X} then X
     elseif {Int.is X} then {Int.toFloat X}
     end
  end

  X = {Acc 1}
in
  {X 5 _}
  {Acc 3 _}
  {Show {X 2.3}}


stack = List([1]);
factory(b,c=0) = my(a=stack[1]++);listput(stack,c);(b)->stack[a]+=b;

foo(f) = factory(0, f);     \\ initialize the factory


sub accumulator {
  my $sum = shift;
  sub { $sum += shift }
}

my $x = accumulator(1);
$x->(5);
accumulator(3);
print $x->(2.3), "\n";


sequence accumulators = {}

function accumulate(integer id, atom v)
    accumulators[id] += v
    return accumulators[id]
end function
constant r_accumulate = routine_id("accumulate")

function accumulator_factory(atom initv=0)
    accumulators = append(accumulators,initv)
    return {r_accumulate,length(accumulators)}
end function

function call_function(object rid, object args)
    if sequence(rid) then
        {rid, integer id} = rid
        args = id&args
    end if
    return call_func(rid,args)
end function

function standard_function()
    return "standard function"
end function
constant r_standard_function = routine_id("standard_function")

constant x = accumulator_factory(1),
         y = accumulator_factory(3)
{} = call_function(x,5)
{} = call_function(y,3)
?call_function(x,2.3)
?call_function(y,4)
?call_function(r_standard_function,{})


<?php
function accumulator($start){
 return create_function('$x','static $v='.$start.';return $v+=$x;');
}
$acc = accumulator(5);
echo $acc(5), "\n"; //prints 10
echo $acc(10), "\n"; //prints 20
?>


(de accumulator (Sum)
   (curry (Sum) (N)
      (inc 'Sum N) ) )

(def 'a (accumulator 7))
(a 1)  # Output: -> 8
(a 2)  # Output: -> 10
(a -5)  # Output: -> 5


use "assert"
class Accumulator
    var value:(I64|F64)
    new create(v:(I64|F64))=>
        value=v
    fun ref apply(v:(I64|F64)=I64(0)):(I64|F64)=>
        value=match value
        | let x:I64=>match v
            | let y:I64=>x+y
            | let y:F64=>x.f64()+y
            end
        | let x:F64=>match v
            | let y:I64=>x+y.f64()
            | let y:F64=>x+y
            end
        end
        value

actor Main
    new create(env:Env)=>
        var r:Accumulator=Accumulator(I64(0))
        r(I64(5))
        r(I64(2))
        try
        Fact(match r()
            |let x:I64=>x==7
            |let y:F64=>y==7.0
            end)?
        env.out.print("The value I have so far is " + r().string())
        else
            env.out.print("An error of some sort happened!")
        end
        r(F64(5.5))
        env.out.print("This is okay..." + r().string())


/mk-acc  {             % accumulator generator
  {0 add 0 0 2 index put}
  7 array copy
  dup 0 4 -1 roll put
  dup dup 2 exch put
  cvx
}  def

% Examples (= is a printing command in PostScript):
/a 1 mk-acc def        % create accumulator #1, name it a
5 a =                  % add 5 to 1, print it
10 mk-acc              % create accumulator #2, leave it anonymous on the stack
2.71 a =               % add 2.71 to 6, print it
dup 3.14 exch exec =   % add 3.14 to 10, print it
dup 100 exch exec =    % add 100 to 13.14, print it
12 a =                 % add 12 to 8.71, print it
                       % accumulator #2 is still available on the stack


function Get-Accumulator ([double]$Start)
{
    {param([double]$Plus) return $script:Start += $Plus}.GetNewClosure()
}


:- use_module(library(lambda)).

define_g(N, G) :-
	put_attr(V, user, N),
	G = V +\X^Y^(get_attr(V, user, N1),
		  Y is X + N1,
		  put_attr(V, user, Y)).

accumulator :-
	define_g(1, G),
	format('Code of g : ~w~n', [G]),
	call(G, 5, S),
	writeln(S),
	call(G, 2.3, R1),
	writeln(R1).


  [ tuck tally share ]this[ swap ] is accumulate ( n s --> [ n )

  [ [ stack ] copy tuck put nested
    ' accumulate nested join ]     is factory    (   n --> [   )


accumulatorFactory <- function(init) {
  currentSum <- init
  function(add) {
    currentSum <<- currentSum + add
    currentSum
  }
}


#lang racket
(define ((accumulator n) i)
  (set! n (+ n i))
  n)


sub accum ($n is copy) { sub { $n += $^x } }

#Example use:
my $a = accum 5;
$a(4.5);
say $a(.5);   # Prints "10".

# You can also use the "&" sigil to create a function that behaves syntactically
# like any other function (i.e. no sigil nor parentheses needed to call it):

my &b = accum 5;
say b 3;   # Prints "8".


make-acc-gen: func [start-val] [
    use [state] [
        state: start-val
        func [value] [
            state: state + value
        ]
    ]
]


:acc (ns-)
  d:create , [ [ fetch ] [ v:inc ] bi ] does ;


/*REXX program shows one method an   accumulator factory   could be implemented.        */
x=.accumulator(1)                                /*initialize accumulator with a 1 value*/
x=call(5)
x=call(2.3)
say '          X value is now'   x               /*displays the current value of   X.   */
say 'Accumulator value is now'  sum              /*displays the current value of  accum.*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
.accumulator:  procedure expose sum;   if symbol('SUM')=="LIT"  then sum=0   /*1st time?*/
               sum=sum + arg(1)                                              /*add──►sum*/
               return sum
/*──────────────────────────────────────────────────────────────────────────────────────*/
call:  procedure expose sum;  sum=sum+arg(1);    return sum          /*add arg1 ──► sum.*/


oGenerator = new Generator

Func main
   oGenerator {
       accumulator = generator(1)
       see call accumulator(5)
       see nl
       generator(3)
       see call accumulator(2.3)
   }

Class Generator
    aN = []

    func generator i
    aN + i
        return eval(substr("return func d {
           oGenerator {
               aN[#id#] += d
               return aN[#id#]
           }
       }","#id#",string(len(aN))))


def accumulator(sum)
  lambda {|n| sum += n}
end

# mixing Integer and Float
x = accumulator(1)
x.call(5)
accumulator(3)
puts x.call(2.3)  # prints 8.3


// rustc 1.26.0 or later

use std::ops::Add;

fn foo<Num>(n: Num) -> impl FnMut(Num) -> Num
        where Num: Add<Output=Num> + Copy + 'static {
    let mut acc = n;
    move |i: Num| {
        acc = acc + i;
        acc
    }
}

fn main() {
    let mut x = foo(1.);
    x(5.);
    foo(3.);
    println!("{}", x(2.3));
}


def AccumulatorFactory[N](n: N)(implicit num: Numeric[N]) = {
  import num._
  var acc = n
  (inc: N) => {
    acc = acc + inc
    acc
  }
}


(define (accumulator sum)
  (lambda (n)
    (set! sum (+ sum n))
    sum))

;; or:

(define ((accumulator sum) n)
  (set! sum (+ sum n))
  sum)

(define x (accumulator 1))
(x 5)
(display (accumulator 3)) (newline)
(display (x 2.3)) (newline)


class Accumulator(sum) {
    method add(num) {
        sum += num;
    }
}

var x = Accumulator(1);
x.add(5);
Accumulator(3);
say x.add(2.3);               # prints: 8.3