--
-- demo\rosetta\Peripheral_Drift_Illusion.exw
-- ==========================================
--
-- converted from https://codepen.io/josetxu/pen/rNmXjrq
--
with javascript_semantics
include pGUI.e
Ihandle dlg, canvas
cdCanvas cdcanvas

constant title = "Peripheral Drift Illusion",
         CD_LIGHT_OLIVE = #d3d004,
         CD_PALE_BLUE = #3250ff,
         dxy = {{45,45},{0,45},{0,0},{45,0},{45,45},{0,45}}

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
    integer {width, height} = IupGetIntInt(canvas, "DRAWSIZE")
    cdCanvasActivate(cdcanvas)
    cdCanvasSetBackground(cdcanvas, CD_LIGHT_OLIVE)
    cdCanvasClear(cdcanvas)
    integer c = 0,
            cy = floor(height/2)*2-81
    while cy>100 do
        integer d = c,
                cx = 81
        while cx<width-100 do
            cdCanvasSetForeground(cdcanvas, CD_WHITE)
            cdCanvasBox(cdcanvas, cx, cx+45, cy, cy-45)
            cdCanvasSetForeground(cdcanvas, CD_BLACK)
            cdCanvasBegin(cdcanvas, CD_FILL)
            for i=4 to 6 do
                integer {dy,dx} = dxy[i-d]
                cdCanvasVertex(cdcanvas, cx+dx, cy-dy)
            end for
            cdCanvasEnd(cdcanvas)
            cdCanvasSetForeground(cdcanvas, CD_PALE_BLUE)
            cdCanvasBox(cdcanvas, cx+4, cx+41, cy-4, cy-41)
            d = remainder(d+(odd(cx)==odd(cy)),4)
            cx += 63
        end while
        c = remainder(c+4-even(cy),4)
        cy -= 63
    end while
    cdCanvasFlush(cdcanvas)
    return IUP_DEFAULT
end function

function map_cb(Ihandle ih)
    atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
    IupGLMakeCurrent(canvas)
    if platform()=JS then
        cdcanvas = cdCreateCanvas(CD_IUP, canvas)
    else
        cdcanvas = cdCreateCanvas(CD_GL, "10x10 %g", {res})
    end if
    cdCanvasSetBackground(cdcanvas, CD_PARCHMENT)
    return IUP_DEFAULT
end function

function canvas_resize_cb(Ihandle /*canvas*/)
    integer {cw, ch} = IupGetIntInt(canvas, "DRAWSIZE")
    atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
    cdCanvasSetAttribute(cdcanvas, "SIZE", "%dx%d %g", {cw, ch, res})
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()
    canvas = IupGLCanvas("RASTERSIZE=780x600") -- (sensible restore size)
    sequence cb = {"MAP_CB", Icallback("map_cb"),
                   "ACTION", Icallback("redraw_cb"),
                   "RESIZE_CB", Icallback("canvas_resize_cb")}
    IupSetCallbacks(canvas, cb)
    dlg = IupDialog(canvas,`TITLE="%s",PLACEMENT=MAXIMIZED`,{title})
    IupShow(dlg)
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure
main()


import "dome" for Window
import "graphics" for Canvas, Color

// signifies the white edges on the blue squares
var LT = 0
var TR = 1
var RB = 2
var BL = 3

var Edges = [
    [LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB],
    [LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL],
    [TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL],
    [TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT],
    [RB, TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT],
    [RB, RB, TR, TR, LT, LT, BL, BL, RB, RB, TR, TR],
    [BL, RB, RB, TR, TR, LT, LT, BL, BL, RB, RB, TR],
    [BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB, RB],
    [LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL, RB],
    [LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL, BL],
    [TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT, BL],
    [TR, TR, LT, LT, BL, BL, RB, RB, TR, TR, LT, LT]
]

var Light_olive = Color.hex("#d3d004")
var Pale_blue   = Color.hex("#3250ff")

var W = Color.white
var B = Color.black

var Colors = [
    [W, B, B, W],
    [W, W, B, B],
    [B, W, W, B],
    [B, B, W, W]
]

class PeripheralDrift {
    construct new() {
        Window.resize(1000, 1000)
        Canvas.resize(1000, 1000)
        Window.title = "Peripheral drift illusion"
    }

    init() {
        Canvas.cls(Light_olive)
        for (x in 0..11) {
            var px = 90 + x * 70
            for (y in 0..11) {
                var py = 90 + y * 70
                Canvas.rectfill(px, py, 50, 50, Pale_blue)
                drawEdge(px, py, Edges[y][x])
            }
        }
    }

    drawEdge(px, py, edge) {
        var c = Colors[edge]
        Canvas.line(px, py, px + 46, py, c[0], 4)
        Canvas.line(px + 46, py, px + 46, py + 46, c[1], 4)
        Canvas.line(px, py + 46, px + 46, py + 46, c[2], 4)
        Canvas.line(px, py + 46, px, py, c[3], 4)
    }

    update() {}

    draw(alpha) {}
}

var Game = PeripheralDrift.new()


procedure pi (q, r, t, k, n, l)
  first := "yes"
  repeat { # infinite loop
    if (4*q+r-t < n*t) then {
      suspend n
      if (\first) := &null then suspend "."
      # compute and update variables for next cycle
      nr := 10*(r-n*t)
      n := ((10*(3*q+r)) / t) - 10*n
      q *:= 10
      r := nr
    } else {
      # compute and update variables for next cycle
      nr := (2*q+r)*l
      nn := (q*(7*k+2)+r*l) / (t*l)
      q *:= k
      t *:= l
      l +:= 2
      k +:= 1
      n := nn
      r := nr
    }
  }
end

procedure main ()
  every (writes (pi (1,0,1,1,3,3)))
end


pi=: 3 :0
  echo"0 '3.1'
  i=. 0
  while. i=. i + 1 do.
    echo -/ 1 10 * <[email protected] 10x ^ 1 0 + i
  end.
)


import java.math.BigInteger ;

public class Pi {
  final BigInteger TWO = BigInteger.valueOf(2) ;
  final BigInteger THREE = BigInteger.valueOf(3) ;
  final BigInteger FOUR = BigInteger.valueOf(4) ;
  final BigInteger SEVEN = BigInteger.valueOf(7) ;

  BigInteger q = BigInteger.ONE ;
  BigInteger r = BigInteger.ZERO ;
  BigInteger t = BigInteger.ONE ;
  BigInteger k = BigInteger.ONE ;
  BigInteger n = BigInteger.valueOf(3) ;
  BigInteger l = BigInteger.valueOf(3) ;

  public void calcPiDigits(){
    BigInteger nn, nr ;
    boolean first = true ;
    while(true){
        if(FOUR.multiply(q).add(r).subtract(t).compareTo(n.multiply(t)) == -1){
          System.out.print(n) ;
          if(first){System.out.print(".") ; first = false ;}
          nr = BigInteger.TEN.multiply(r.subtract(n.multiply(t))) ;
          n = BigInteger.TEN.multiply(THREE.multiply(q).add(r)).divide(t).subtract(BigInteger.TEN.multiply(n)) ;
          q = q.multiply(BigInteger.TEN) ;
          r = nr ;
          System.out.flush() ;
        }else{
          nr = TWO.multiply(q).add(r).multiply(l) ;
          nn = q.multiply((SEVEN.multiply(k))).add(TWO).add(r.multiply(l)).divide(t.multiply(l)) ;
          q = q.multiply(k) ;
          t = t.multiply(l) ;
          l = l.add(TWO) ;
          k = k.add(BigInteger.ONE) ;
          n = nn ;
          r = nr ;
        }
    }
  }

  public static void main(String[] args) {
    Pi p = new Pi() ;
    p.calcPiDigits() ;
  }
}


# The Gibbons spigot, in the mold of the [[#Groovy]] and [[#Python]] programs shown on this page.
# The "bigint" functions needed are:
# long_minus long_add long_multiply long_div

def pi_spigot:

  # S is the sixtuple:
  # q      r      t      k      n      l
  # 0      1      2      3      4      5

  def long_lt(x;y): if x == y then false else lessOrEqual(x;y) end;

  def check:
     long_lt(long_minus(long_add(long_multiply("4"; .[0]); .[1]) ; .[2]);
             long_multiply(.[4]; .[2]));

  # state: [d, S] where digit is null or a digit ready to be printed
  def next:
    .[1] as $S
    | $S[0] as $q | $S[1] as $r | $S[2] as $t | $S[3] as $k | $S[4] as $n | $S[5] as $l
    | if $S|check
      then [$n,
             [long_multiply("10"; $q),
              long_multiply("10"; long_minus($r; long_multiply($n;$t))),
              $t,
              $k,
              long_minus( long_div(long_multiply("10";long_add(long_multiply("3"; $q); $r)); $t );
                          long_multiply("10";$n)),
              $l ]]
      else [null,
             [long_multiply($q;$k),
              long_multiply( long_add(long_multiply("2";$q); $r); $l),
              long_multiply($t;$l),
              long_add($k; "1"),
              long_div( long_add(long_multiply($q; long_add(long_multiply("7";$k); "2")) ; long_multiply($r;$l));
                        long_multiply($t;$l) ),
              long_add($l; "2") ]]
      end;

  # Input: input to the filter "nextstate"
  # Output:  [count, space, digit] for successive digits produced by "nextstate"
  def decorate( nextstate ):

     # For efficiency it is important that the recursive
     # function have arity 0 and be tail-recursive:
     def count:
       .[0] as $count
       | .[1] as $state
       | $state[0] as $value
       | ($state[1] | map(length) | add) as $space
       | (if $value then [$count, $space, $value] else empty end),
         ( [if $value then $count+1 else $count end, ($state | nextstate)] | count);
  [0, .] | count;

  #       q=1, r=0, t=1, k=1, n=3, l=3
  [null, ["1", "0", "1", "1", "3", "3"]] | decorate(next)
;

pi_spigot


let prec = precision(BigFloat), spi = "", digit = 1
    while true
      if digit > lastindex(spi)
        prec *= 2
        setprecision(prec)
        spi = string(big(π))
      end
      print(spi[digit])
      digit += 1
    end
end


// version 1.1.2

import java.math.BigInteger

val ZERO  = BigInteger.ZERO
val ONE   = BigInteger.ONE
val TWO   = BigInteger.valueOf(2L)
val THREE = BigInteger.valueOf(3L)
val FOUR  = BigInteger.valueOf(4L)
val SEVEN = BigInteger.valueOf(7L)
val TEN   = BigInteger.TEN

fun calcPi() {
    var nn: BigInteger
    var nr: BigInteger
    var q = ONE
    var r = ZERO
    var t = ONE
    var k = ONE
    var n = THREE
    var l = THREE
    var first = true
    while (true) {
        if (FOUR * q + r - t < n * t) {
            print(n)
            if (first) { print ("."); first = false }
            nr = TEN * (r - n * t)
            n = TEN * (THREE * q + r) / t - TEN * n
            q *= TEN
            r = nr
        }
        else {
            nr = (TWO * q + r) * l
            nn = (q * SEVEN * k + TWO + r * l) / (t * l)
            q *= k
            t *= l
            l += TWO
            k += ONE
            n = nn
            r = nr
        }
    }
}

fun main(args: Array<String>) = calcPi()


#!/usr/bin/lasso9

define generatePi => {
  yield currentCapture

  local(r = array(), i, k, b, d, c = 0, x)
  with i in generateSeries(1, 2800)
  do #r->insert(2000)
  with k in generateSeries(2800, 1, -14)
  do {
    #d = 0
    #i = #k
    while(true) => {
      #d += #r->get(#i) * 10000
      #b = 2 * #i - 1
      #r->get(#i) = #d % #b
      #d /= #b
      #i--
      !#i ? loop_abort
      #d *= #i
    }
    #x = (#c + #d / 10000)
    yield (#k == 2800 ? ((#x * 0.001)->asstring(-precision = 3)) | #x->asstring(-padding=4, -padChar='0'))
    #c = #d % 10000
  }
}

local(pi_digits) = generatePi
loop(200) => {
    stdout(#pi_digits())
}


    ndigits = 0

    q       = 1
    r       = 0
    t       = q
    k       = q
    n       = 3
    L       = n

   first = 666  '   ANY non-zero =='true' in LB.

    while ndigits <100
        if ( 4 *q +r -t) <( n *t) then
            print n;
            ndigits =ndigits +1
            if not( ndigits mod 40) then print: print "  ";
            if first =666 then first = 0: print ".";
            nr =10 *( r -n *t)
            n  =int( ( (10 *( 3 *q +r)) /t) -10 *n)
            q  =q *10
            r  =nr
        else
            nr =( 2 *q +r) *L
            nn =(q *( 7 *k +2) +r *L) /( t *L)
            q  =q *k
            t  =t *L
            L  =L +2
            k  =k +1
            n  =int( nn)
            r  =nr
        end if
        scan
wend

end


a = {}
n = 1000
len = math.modf( 10 * n / 3 )

for j = 1, len do
    a[j] = 2
end
nines = 0
predigit = 0
for j = 1, n do
    q = 0
    for i = len, 1, -1 do
        x = 10 * a[i] + q * i
        a[i] = math.fmod( x, 2 * i - 1 )
        q = math.modf( x / ( 2 * i - 1 ) )
    end
    a[1] = math.fmod( q, 10 )
    q = math.modf( q / 10 )
    if q == 9 then
        nines = nines + 1
    else
        if q == 10 then
            io.write( predigit + 1 )
            for k = 1, nines do
                io.write(0)
            end
            predigit = 0
            nines = 0
        else
            io.write( predigit )
            predigit = q
            if nines ~= 0 then
                for k = 1, nines do
                    io.write( 9 )
                end
                nines = 0
            end
        end
    end
end
print( predigit )


Module Checkpi {
      Module FindPi(Digits){
            Digits++
            n=Int(3.32*Digits)
            PlusOne=Lambda N=0% -> {
                  =N
                  N++
            }
            PlusTwo=Lambda N=1% -> {
                  =N
                  N+=2
            }
            Dim A(n)<<PlusOne(), B(n)<<PlusTwo()
            Dim Ten(n),  CarrierOver(n), Sum(n),Remainder(n)=2
            OutPutDigits=Digits
            Predigits=Stack
            CallBack=lambda fl=true, Chars=0 (x)->{
                  Print x;
                  Chars++
                  If fl then Print "." : Print " "; : fl=false : Chars=0 : exit
                  If Chars=50 then {
                        Print
                        Print " ";
                        Chars=0
                        Refresh
                  } else.if (Chars mod 5)=0 then {
                         Print " ";
                         Refresh
                  }
                  \\ explicitly refresh output layer, using Fast ! mode of speed
            }
            Print "Pi=";
             While Digits {
                  NextDigit(&CallBack, &Digits)
            }
            print
            Refresh
            Sub NextDigit(&f, &D)
                CarrierOver=0
                  For k=n-1 to 1 {
                  Ten(k)=Remainder(k)*10%
                  CarrierOver(k)=CarrierOver
                  Sum(k)=Ten(k)+CarrierOver(k)
                  q=Sum(k) div  B(k)
                  Remainder(k)=Sum(k)-B(k)*q
                  CarrierOver=A(k)*q
                  }
                  Ten(0)=Remainder(0)*10%
                  CarrierOver(0)=CarrierOver
                  Sum(0)=Ten(0)+CarrierOver(0)
                  q=Sum(0) div  10%
                  Remainder(0)=Sum(0)-10%*q
                  if q<>9 and q<>10 then {
                        Stack Predigits {
                              While not empty {
                                Call f(Number)
                                if D>0 then D--
                                If D=0 then flush ' empty stack
                              }
                              Push q
                        }
                  } else.if q=9 Then {
                        Stack Predigits { Data q }
                  } else {
                        Stack Predigits {
                        While not empty {
                              Call f((Number+1) mod 10)
                              if D>0 then D--
                              If D=0 then flush ' empty stack
                        }
                        Push 0
                        }
                  }
            End Sub
      }
      \\ reduce time to share with OS
      \\ Need explicitly use of refresh output layer (M2000 console)
      \\ Slow for a screen refresh per statement and give more time to OS
      Rem Set Slow
      \\ Fast is normal screen refresh, per Refresh time, and give standard time to OS
      Rem Set Fast
      \\ Fast ! use Refresh for screen refresh, and give less time o OS than standard
      \\ Esc key work when Refresh executed (and OS get little time)
      Set Fast !
      FindPi 4
      FindPi 28
      Print Pi  ' pi in M2000 is Decimal type with 29 digits (1 plus 28 after dot, is same as FindPi 28)
      Refresh
      FindPi 50
}
Flush ' empty stack of values
CheckPi
List  ' no variables exist
Modules ? ' current module exist
Stack ' Stack of values  ' has to be empty, we didn't use current stack for values.


WriteString[$Output, "3."];
For[i = -1, True, i--,
  WriteString[$Output, RealDigits[Pi, 10, 1, i][[1, 1]]]; Pause[.05]];


q = 1; r = 0; t = 1
k = 1; n = 3; l = 3

nn = null; nr = null
first = true

while true
	if (((4 * q) + r) - t) < (n * t)
		print n
		if first
			print "."
			first = false
		end
		nr = int(10 * (r - (n * t)))
		n = int((10 * ((3 * q) + r)) / t) - (10 * n)
		q *= 10
		r = nr
	else
		nr = int(((2 * q) + r) * l)
		nn = int((((q * (7 * k)) + 2) + (r * l)) / (t * l))
		q *= k
		t *= l
		l += 2
		k += 1
		n = nn
		r = nr
	end if
end while


V data = [85, 88, 75, 66, 25, 29, 83, 39, 97,
      68, 41, 10, 49, 16, 65, 32, 92, 28, 98]

F pick(at, remain, accu, treat)
   I remain == 0
      R I accu > treat {1} E 0
   R pick(at - 1, remain - 1, accu + :data[at - 1], treat) +
      (I at > remain {pick(at - 1, remain, accu, treat)} E 0)

V treat = 0
V total = 1.0
L(i) 0..8
   treat += data[i]
L(i) (19..11).step(-1)
   total *= i
L(i) (9..1).step(-1)
   total /= i

V gt = pick(19, 9, 0, treat)
V le = Int(total - gt)

print(‘<= : #.6%  #.’.format(100 * le / total, le))
print(‘ > : #.6%  #.’.format(100 * gt / total, gt))


/* NetRexx */
options replace format comments java crossref symbols binary
import java.math.BigInteger

runSample(arg)
return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
  parse arg places .
  if places = '' then places = -1

  TWO   = BigInteger.valueOf(2)
  THREE = BigInteger.valueOf(3)
  FOUR  = BigInteger.valueOf(4)
  SEVEN = BigInteger.valueOf(7)

  q_ = BigInteger.ONE
  r_ = BigInteger.ZERO
  t_ = BigInteger.ONE
  k_ = BigInteger.ONE
  n_ = BigInteger.valueOf(3)
  l_ = BigInteger.valueOf(3)

  nn = BigInteger
  nr = BigInteger

  first = isTrue()
  digitCt = 0
  loop forever
    if FOUR.multiply(q_).add(r_).subtract(t_).compareTo(n_.multiply(t_)) == -1 then do
      digitCt = digitCt + 1
      if places > 0 & digitCt - 1 > places then leave
      say n_'\-'
      if first then do
        say '.\-'
        first = isFalse()
        end
      nr = BigInteger.TEN.multiply(r_.subtract(n_.multiply(t_)))
      n_ = BigInteger.TEN.multiply(THREE.multiply(q_).add(r_)).divide(t_).subtract(BigInteger.TEN.multiply(n_))
      q_ = q_.multiply(BigInteger.TEN)
      r_ = nr
      end
    else do
      nr = TWO.multiply(q_).add(r_).multiply(l_)
      nn = q_.multiply((SEVEN.multiply(k_))).add(TWO).add(r_.multiply(l_)).divide(t_.multiply(l_))
      q_ = q_.multiply(k_)
      t_ = t_.multiply(l_)
      l_ = l_.add(TWO)
      k_ = k_.add(BigInteger.ONE)
      n_ = nn
      r_ = nr
      end
    end
  say

  return

method isTrue() private static returns boolean
  return (1 == 1)
method isFalse() private static returns boolean
  return \isTrue()


with Ada.Text_IO; with Iterate_Subsets;

procedure Permutation_Test is

   type Group_Type is array(Positive range <>) of Positive;

   Treat_Group: constant Group_Type := (85, 88, 75, 66, 25, 29, 83, 39, 97);
   Ctrl_Group:  constant Group_Type := (68, 41, 10, 49, 16, 65, 32, 92, 28, 98);

   package Iter is new Iterate_Subsets(Treat_Group'Length, Ctrl_Group'Length);

   Full_Group: constant Group_Type(1 .. Iter.All_Elements)
     := Treat_Group & Ctrl_Group;

   function Mean(S: Iter.Subset) return Float is
      Sum: Natural := 0;
   begin
      for I in S'Range loop
         Sum := Sum + Full_Group(S(I));
      end loop;
      return Float(Sum)/Float(S'Length);
   end Mean;

   package FIO is new Ada.Text_IO.Float_IO(Float);

   T_Avg: Float := Mean(Iter.First);
   S_Avg: Float;
   S:     Iter.Subset := Iter.First;
   Equal:  Positive := 1; -- Mean(Iter'First) = Mean(Iter'First)
   Higher: Natural  := 0;
   Lower:  Natural  := 0;

begin -- Permutation_Test;
   -- first, count the subsets with a higher, an equal or a lower mean
   loop
      Iter.Next(S);
      S_Avg := Mean(S);
      if S_Avg = T_Avg then
         Equal := Equal + 1;
      elsif S_Avg >= T_Avg then
         Higher := Higher + 1;
      else
         Lower := Lower + 1;
      end if;
      exit when Iter.Last(S);
   end loop;

   -- second, output the results
   declare
      use Ada.Text_IO;
      Sum: Float := Float(Higher + Equal + Lower);
   begin
      Put("Less or Equal: ");
      FIO.Put(100.0*Float(Lower+Equal) / Sum, Fore=>3, Aft=>1, Exp=>0);
      Put(Integer'Image(Lower+Equal));
      New_Line;
      Put("More:          ");
      FIO.Put(100.0*Float(Higher) / Sum,      Fore=>3, Aft=>1, Exp=>0);
      Put(Integer'Image(Higher));
      New_Line;
   end;
end Permutation_Test;


# syntax: GAWK -f PERMUTATION_TEST.AWK
# converted from C
BEGIN {
#             "treatment..................control......................"
    n = split("85,88,75,66,25,29,83,39,97,68,41,10,49,16,65,32,92,28,98",data,",")
    for (i=1; i<=n; i++) { # make AWK array look like a C array
      data[i-1] = data[i]
    }
    delete data[n]
    total = 1
    for (i=0; i<9; i++) { treat += data[i] }
    for (i=19; i>10; i--) { total *= i }
    for (i=9; i>0; i--) { total /= i }
    gt = pick(19,9,0,treat)
    le = total - gt
    printf("<= : %9.6f%% %6d\n",100*le/total,le)
    printf(" > : %9.6f%% %6d\n",100*gt/total,gt)
    exit(0)
}
function pick(at,remain,accu,treat) {
    if (!remain) {
      return (accu > treat) ? 1 : 0
    }
    return pick(at-1,remain-1,accu+data[at-1],treat) + ( (at > remain) ? pick(at-1,remain,accu,treat) : 0 )
}


import bigints

var
  tmp1, tmp2, tmp3, acc, k = initBigInt(0)
  den, num, k2 = initBigInt(1)

proc extractDigit(): int32 =
  if num > acc:
    return -1

  tmp3 = num shl 1 + num + acc
  tmp1 = tmp3 div den
  tmp2 = tmp3 mod den + num

  if tmp2 >= den:
    return -1

  result = int32(tmp1.limbs[0])

proc eliminateDigit(d: int32) =
  acc -= den * d
  acc *= 10
  num *= 10

proc nextTerm() =
  k += 1
  k2 += 2
  acc += num shl 1
  acc *= k2
  den *= k2
  num *= k

var i = 0

while true:
  var d: int32 = -1
  while d < 0:
    nextTerm()
    d = extractDigit()

  stdout.write chr(ord('0') + d)
  inc i
  if i == 40:
    echo ""
    i = 0
  eliminateDigit d


open Creal;;

let block = 100 in
let segment n =
   let s = to_string pi (n*block) in
   String.sub s ((n-1)*block) block in
let counter = ref 1 in
while true do
   print_string (segment !counter);
   flush stdout;
   incr counter
done


      ntreated% = 9
      nplacebo% = 10
      DIM results%(ntreated% + nplacebo% - 1)
      results%() = 85, 88, 75, 66, 25, 29, 83, 39, 97, \    REM treated group
      \            68, 41, 10, 49, 16, 65, 32, 92, 28, 98 : REM placebo group

      greater% = 0
      FOR comb% = 0 TO 2^(ntreated%+nplacebo%)-1
        IF FNnbits(comb%) = ntreated% THEN
          tsum% = 0 : psum% = 0
          FOR b% = 0 TO ntreated%+nplacebo%-1
            IF comb% AND 2^b% THEN
              tsum% += results%(b%)
            ELSE
              psum% += results%(b%)
            ENDIF
          NEXT
          meandiff = tsum%/ntreated% - psum%/nplacebo%
          IF comb% = 2^ntreated% - 1 THEN
            actual = meandiff
          ELSE
            greater% -= meandiff > actual
            groups% += 1
          ENDIF
        ENDIF
      NEXT

      percent = 100 * greater%/groups%
      PRINT "Percentage groupings <= actual experiment: "; 100 - percent
      PRINT "Percentage groupings >  actual experiment: "; percent
      END

      DEF FNnbits(N%)
      N% -= N% >>> 1 AND &55555555
      N% = (N% AND &33333333) + (N% >>> 2 AND &33333333)
      N% = (N% + (N% >>> 4)) AND &0F0F0F0F
      N% += N% >>> 8 : N% += N% >>> 16
      = N% AND &7F


#include <stdio.h>

int data[] = {  85, 88, 75, 66, 25, 29, 83, 39, 97,
                68, 41, 10, 49, 16, 65, 32, 92, 28, 98 };

int pick(int at, int remain, int accu, int treat)
{
        if (!remain) return (accu > treat) ? 1 : 0;

        return  pick(at - 1, remain - 1, accu + data[at - 1], treat) +
                ( at > remain ? pick(at - 1, remain, accu, treat) : 0 );
}

int main()
{
        int treat = 0, i;
        int le, gt;
        double total = 1;
        for (i = 0; i < 9; i++) treat += data[i];
        for (i = 19; i > 10; i--) total *= i;
        for (i = 9; i > 0; i--) total /= i;

        gt = pick(19, 9, 0, treat);
        le = total - gt;

        printf("<= : %f%%  %d\n > : %f%%  %d\n",
               100 * le / total, le, 100 * gt / total, gt);
        return 0;
}


; 'numbers' is count of numbers or #false for eternal pleasure.
(define (pi numbers)
   (let loop ((q 1) (r 0) (t 1) (k 1) (n 3) (l 3) (numbers numbers))
      (unless (eq? numbers 0)
         (if (< (- (+ (* 4 q) r) t) (* n t))
            (begin
               (display n)
               (loop (* q  10)
                     (* 10 (- r (* n t)))
                     t
                     k
                     (- (div (* 10 (+ (* 3 q) r)) t) (* 10 n))
                     l
                     (if numbers (- numbers 1))))
            (begin
               (loop (* q k)
                     (* (+ (* 2 q) r) l)
                     (* t l)
                     (+ k 1)
                     (div (+ (* q (* 7 k)) 2 (* r l)) (* t l))
                     (+ l 2)
                     (if numbers (- numbers 1))))))))

(pi #false)


pi()={
  my(x=Pi,n=0,t);
  print1("3.");
  while(1,
    if(n>=default(realprecision),
      default(realprecision,default(realprecision)*2);
      x=Pi
    );
    print1(floor(x*10^n++)%10)
  )
};


using System;
using System.Collections.Generic;

namespace PermutationTest {
    class Program {
        static readonly List<int> DATA = new List<int>{
            85, 88, 75, 66, 25, 29, 83, 39, 97,
            68, 41, 10, 49, 16, 65, 32, 92, 28, 98
        };

        static int Pick(int at, int remain, int accu, int treat) {
            if (remain == 0) {
                return (accu > treat) ? 1 : 0;
            }
            return Pick(at - 1, remain - 1, accu + DATA[at - 1], treat)
                + ((at > remain) ? Pick(at - 1, remain, accu, treat) : 0);
        }

        static void Main() {
            int treat = 0;
            double total = 1.0;
            for (int i = 0; i <= 8; i++) {
                treat += DATA[i];
            }
            for (int i = 19; i >= 11; i--) {
                total *= i;
            }
            for (int i = 9; i >= 1; --i) {
                total /= i;
            }
            int gt = Pick(19, 9, 0, treat);
            int le = (int) (total - gt);
            Console.WriteLine("<= {0}%  {1}", 100.0 * le / total, le);
            Console.WriteLine(" > {0}%  {1}", 100.0 * gt / total, gt);
        }
    }
}


#include<iostream>
#include<vector>
#include<numeric>
#include<functional>

class
{
public:
    int64_t operator()(int n, int k){ return partial_factorial(n, k) / factorial(n - k);}
private:
    int64_t partial_factorial(int from, int to) { return from == to ? 1 : from * partial_factorial(from - 1, to); }
    int64_t factorial(int n) { return n == 0 ? 1 : n * factorial(n - 1);}
}combinations;

int main()
{
    static constexpr int treatment = 9;
    const std::vector<int> data{ 85, 88, 75, 66, 25, 29, 83, 39, 97,
                                 68, 41, 10, 49, 16, 65, 32, 92, 28, 98 };

    int treated = std::accumulate(data.begin(), data.begin() + treatment, 0);

    std::function<int (int, int, int)> pick;
    pick = [&](int n, int from, int accumulated)
            {
                if(n == 0)
                    return accumulated > treated ? 1 : 0;
                else
                    return pick(n - 1, from - 1, accumulated + data[from - 1]) +
                            (from > n ? pick(n, from - 1, accumulated) : 0);
            };

    int total   = combinations(data.size(), treatment);
    int greater = pick(treatment, data.size(), 0);
    int lesser  = total - greater;

    std::cout << "<= : " << 100.0 * lesser  / total << "%  " << lesser  << std::endl
              << " > : " << 100.0 * greater / total << "%  " << greater << std::endl;
}


//
//  main.swift
//  pi digits
//
//  Created by max goren on 11/11/21.
//  Copyright © 2021 maxcodes. All rights reserved.
//

import Foundation

var r = [Int]()
var i = 0
var k = 2800
var b = 0
var c = 0
var d = 0

for _ in 0...2800 {
    r.append(2000);
}
while k > 0 {
    d = 0;
    i = k;
    while (true) {
        d = d + r[i] * 10000
        b = 2 * i - 1
        r[i] = d % b
        d = d / b
        i = i - 1
        if i == 0 {
            break;
        }
        d = d * i;
    }
    print(c +  d / 10000, "")
    c = d % 10000
    k = k - 14
}


Program Pi_Spigot;
const
  n   = 1000;
  len = 10*n div 3;

var
  j, k, q, nines, predigit: integer;
  a: array[0..len] of longint;

function OneLoop(i:integer):integer;
var
  x: integer;
begin
  {Only calculate as far as needed }
  {+16 for security digits ~5 decimals}
  i := i*10 div 3+16;
  IF i > len then
    i := len;
  result := 0;
  repeat   {Work backwards}
    x  := 10*a[i] + result*i;
    result := x div (2*i - 1);
    a[i]   := x - result*(2*i - 1);//x mod (2*i - 1)
    dec(i);
  until i<= 0 ;
end;

begin

  for j := 1 to len do
    a[j] := 2;                 {Start with 2s}
  nines := 0;
  predigit := 0;               {First predigit is a 0}

  for j := 1 to n do
  begin
    q := OneLoop(n-j);
    a[1] := q mod 10;
    q := q div 10;
    if q = 9 then
      nines := nines + 1
    else
      if q = 10 then
      begin
        write(predigit+1);
        for k := 1 to nines do
          write(0);            {zeros}
        predigit := 0;
        nines := 0
      end
      else
      begin
        write(predigit);
        predigit := q;
        if nines <> 0 then
        begin
          for k := 1 to nines do
            write(9);
          nines := 0
        end
      end
  end;
  writeln(predigit);
end.


(defun perm-test (s1 s2)
  (let ((more 0) (leq 0)
	(all-data (append s1 s2))
	(thresh (apply #'+ s1)))
    (labels
      ((recur (data sum need avail)
	      (cond ((zerop need)   (if (>= sum thresh)
				      (incf more)
				      (incf leq)))
		    ((>= avail need)
		       (recur (cdr data) sum need (1- avail))
		       (recur (cdr data) (+ sum (car data)) (1- need) (1- avail))))))

      (recur all-data 0 (length s1) (length all-data))
      (cons more leq))))

(let* ((a (perm-test '(68 41 10 49 16 65 32 92 28 98)
		     '(85 88 75 66 25 29 83 39 97)))
       (x (car a))
       (y (cdr a))
       (s (+ x y)))
  (format t "<=: ~a ~6f%~% >: ~a ~6f%~%"
	  x (* 100e0 (/ x s))
	  y (* 100e0 (/ y s))))


import std.stdio, std.algorithm, std.array, combinations3;

auto permutationTest(T)(in T[] a, in T[] b) pure nothrow @safe {
    immutable tObs = a.sum;
    auto combs = combinations!false(a ~ b, a.length);
    immutable under = combs.count!(perm => perm.sum <= tObs);
    return under * 100.0 / combs.length;
}

void main() {
    immutable treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97];
    immutable controlGroup = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];
    immutable under = permutationTest(treatmentGroup, controlGroup);
    writefln("Under =%6.2f%%\nOver  =%6.2f%%", under, 100.0 - under);
}


program Permutation_test;

{$APPTYPE CONSOLE}

uses
  System.SysUtils;

procedure Comb(n, m: Integer; emit: TProc<TArray<Integer>>);
var
  s: TArray<Integer>;
  last: Integer;

  procedure rc(i, next: Integer);
  begin
    for var j := next to n - 1 do
    begin
      s[i] := j;
      if i = last then
        emit(s)
      else
        rc(i + 1, j + 1);
    end;
  end;

begin
  SetLength(s, m);
  last := m - 1;
  rc(0, 0);
end;

begin
  var tr: TArray<Integer> := [85, 88, 75, 66, 25, 29, 83, 39, 97];
  var ct: TArray<Integer> := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];

  // collect all results in a single list
  var all: TArray<Integer> := concat(tr, ct);

  // compute sum of all data, useful as intermediate result
  var sumAll := 0;
  for var r in all do
    inc(sumAll, r);

  // closure for computing scaled difference.
  // compute results scaled by len(tr)*len(ct).
  // this allows all math to be done in integers.
  var sd :=
    function(trc: TArray<Integer>): Integer
    begin
      var sumTr := 0;
      for var x in trc do
        inc(sumTr, all[x]);
      result := sumTr * length(ct) - (sumAll - sumTr) * length(tr);
    end;

  // compute observed difference, as an intermediate result
  var a: TArray<Integer>;
  SetLength(a, length(tr));
  for var i := 0 to High(a) do
    a[i] := i;

  var sdObs := sd(a);

  // iterate over all combinations.  for each, compute (scaled)
  // difference and tally whether leq or gt observed difference.
  var nLe, nGt: Integer;

  comb(length(all), length(tr),
    procedure(c: TArray<Integer>)
    begin
      if sd(c) > sdObs then
        inc(nGt)
      else
        inc(nle);
    end);

  // print results as percentage
  var pc := 100 / (nLe + nGt);
  writeln(format('differences <= observed: %f%%', [nle * pc]));
  writeln(format('differences  > observed: %f%%', [ngt * pc]));

  {$IFNDEF UNIX} readln; {$ENDIF}
end.


with javascript_semantics
integer a=10000,b,c=8400,d,e=0,g sequence f=repeat(floor(a/5),c+1) while c>0 do g=2*c d=0
b=c while b>0 do d+=f[b]*a g-=1 f[b]=remainder(d, g) d=floor(d/g) g-=1 b-=1 if b!=0 then
d*=b end if end while printf(1,"%04d",e+floor(d/a)) c-=14 e = remainder(d,a) end while


defmodule Permutation do
  def statistic(ab, a) do
    sumab = Enum.sum(ab)
    suma  = Enum.sum(a)
    suma / length(a) - (sumab - suma) / (length(ab) - length(a))
  end

  def test(a, b) do
    ab = a ++ b
    tobs = statistic(ab, a)
    {under, count} = Enum.reduce(comb(ab, length(a)), {0,0}, fn perm, {under, count} ->
      if statistic(ab, perm) <= tobs, do: {under+1, count+1},
                                    else: {under  , count+1}
    end)
    under * 100.0 / count
  end

  defp comb(_, 0), do: [[]]
  defp comb([], _), do: []
  defp comb([h|t], m) do
    (for l <- comb(t, m-1), do: [h|l]) ++ comb(t, m)
  end
end

treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97]
controlGroup   = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = Permutation.test(treatmentGroup, controlGroup)
:io.fwrite "under = ~.2f%, over = ~.2f%~n", [under, 100-under]


a := [85, 88, 75, 66, 25, 29, 83, 39, 97];
b := [68, 41, 10, 49, 16, 65, 32, 92, 28, 98];

# Compute a decimal approximation of a rational
Approx := function(x, d)
	local neg, a, b, n, m, s;
	if x < 0 then
		x := -x;
		neg := true;
	else
		neg := false;
	fi;
	a := NumeratorRat(x);
	b := DenominatorRat(x);
	n := QuoInt(a, b);
	a := RemInt(a, b);
	m := 10^d;
	s := "";
	if neg then
		Append(s, "-");
	fi;
	Append(s, String(n));
	n := Size(s) + 1;
	Append(s, String(m + QuoInt(a*m, b)));
	s[n] := '.';
	return s;
end;

PermTest := function(a, b)
	local c, d, p, q, u, v, m, n, k, diff, all;
	p := Size(a);
	q := Size(b);
	v := Concatenation(a, b);
	n := p + q;
	m := Binomial(n, p);
	diff := Sum(a)/p - Sum(b)/q;
	all := [1 .. n];
	k := 0;
	for u in Combinations(all, p) do
		c := List(u, i -> v[i]);
		d := List(Difference(all, u), i -> v[i]);
		if Sum(c)/p - Sum(d)/q > diff then
			k := k + 1;
		fi;
	od;
	return [Approx((1 - k/m)*100, 3), Approx(k/m*100, 3)];
end;

# in order, % less or greater than original diff
PermTest(a, b);
[ "87.197", "12.802" ]


Dim Shared datos(18) As Integer => {85, 88, 75, 66, 25, 29, 83, 39, 97,_
                                    68, 41, 10, 49, 16, 65, 32, 92, 28, 98}

Function pick(at As Integer, remain As Integer, accu As Integer, treat As Integer) As Integer
    If remain = 0 Then
        If accu > treat Then Return 1 Else Return 0
    End If

    Dim a As Integer
    If at > remain Then a = pick(at-1, remain, accu, treat) Else a = 0
    Return pick(at-1, remain-1, accu+datos(at), treat) + a
End Function

Dim As Integer treat = 0, le, gt, total = 1, i

For i = 1 To 9
    treat += datos(i)
Next i
For i = 19 To 11 Step -1
    total *= i
Next i
For i = 9 To 1 Step -1
    total /= i
Next i

gt = pick(19, 9, 0, treat)
le = total - gt

Print Using "<= : ##.######%  #####"; 100*le/total; le
Print Using " > : ##.######%  #####"; 100*gt/total; gt
Sleep


/* Uses the algorithm of S. Rabinowicz and S. Wagon, "A Spigot Algorithm */
/* for the Digits of Pi".                                                */
(subrg, fofl, size):
Pi_Spigot: procedure options (main);                 /* 21 January 2012. */
   declare (n, len) fixed binary;

   n = 1000;
   len = 10*n / 3;
   begin;
      declare ( i, j, k, q, nines, predigit ) fixed binary;
      declare x fixed binary (31);
      declare a(len) fixed binary (31);

      a = 2; /* Start with 2s */
      nines, predigit = 0; /* First predigit is a 0 */
      do j = 1 to n;
         q = 0;
         do i = len to 1 by -1; /* Work backwards */
            x = 10*a(i) + q*i;
            a(i) = mod (x, (2*i-1));
            q = x / (2*i-1);
         end;
         a(1) = mod(q, 10); q = q / 10;
         if q = 9 then nines = nines + 1;
         else if q = 10 then
            do;
               put edit(predigit+1) (f(1));
               do k = 1 to nines;
                  put edit ('0')(a(1)); /* zeros */
               end;
               predigit, nines = 0;
            end;
         else
            do;
               put edit(predigit) (f(1)); predigit = q;
               do k = 1 to nines; put edit ('9')(a(1)); end;
               nines = 0;
            end;
      end;
      put edit(predigit) (f(1));
   end; /* of begin block */
end Pi_Spigot;


package main

import "fmt"

var tr = []int{85, 88, 75, 66, 25, 29, 83, 39, 97}
var ct = []int{68, 41, 10, 49, 16, 65, 32, 92, 28, 98}

func main() {
    // collect all results in a single list
    all := make([]int, len(tr)+len(ct))
    copy(all, tr)
    copy(all[len(tr):], ct)

    // compute sum of all data, useful as intermediate result
    var sumAll int
    for _, r := range all {
        sumAll += r
    }

    // closure for computing scaled difference.
    // compute results scaled by len(tr)*len(ct).
    // this allows all math to be done in integers.
    sd := func(trc []int) int {
        var sumTr int
        for _, x := range trc {
            sumTr += all[x]
        }
        return sumTr*len(ct) - (sumAll-sumTr)*len(tr)
    }

    // compute observed difference, as an intermediate result
    a := make([]int, len(tr))
    for i, _ := range a {
        a[i] = i
    }
    sdObs := sd(a)

    // iterate over all combinations.  for each, compute (scaled)
    // difference and tally whether leq or gt observed difference.
    var nLe, nGt int
    comb(len(all), len(tr), func(c []int) {
        if sd(c) > sdObs {
            nGt++
        } else {
            nLe++
        }
    })

    // print results as percentage
    pc := 100 / float64(nLe+nGt)
    fmt.Printf("differences <= observed: %f%%\n", float64(nLe)*pc)
    fmt.Printf("differences  > observed: %f%%\n", float64(nGt)*pc)
}

// combination generator, copied from combination task
func comb(n, m int, emit func([]int)) {
    s := make([]int, m)
    last := m - 1
    var rc func(int, int)
    rc = func(i, next int) {
        for j := next; j < n; j++ {
            s[i] = j
            if i == last {
                emit(s)
            } else {
                rc(i+1, j+1)
            }
        }
        return
    }
    rc(0, 0)
}


#SCALE = 10000
#ARRINT=  2000

Procedure Pi(Digits)
  Protected First=#True, Text$
  Protected Carry, i, j, sum
  Dim Arr(Digits)
  For i=0 To Digits
    Arr(i)=#ARRINT
  Next
  i=Digits
  While i>0
    sum=0
    j=i
    While j>0
      sum*j+#SCALE*arr(j)
      Arr(j)=sum%(j*2-1)
      sum/(j*2-1)
      j-1
    Wend
    Text$ = RSet(Str(Carry+sum/#SCALE),4,"0")
    If First
      Text$ = ReplaceString(Text$,"3","3.")
      First = #False
    EndIf
    Print(Text$)
    Carry=sum%#SCALE
    i-14
  Wend
EndProcedure

If OpenConsole()
  SetConsoleCtrlHandler_(?Ctrl,#True)
  Pi(24*1024*1024)
EndIf
End

Ctrl:
PrintN(#CRLF$+"Ctrl-C was pressed")
End


binomial n m = (f !! n) `div` (f !! m) `div` (f !! (n - m))
	where f = scanl (*) 1 [1..]

permtest treat ctrl = (fromIntegral less) / (fromIntegral total) * 100
	where
	total = binomial (length avail) (length treat)
	less  = combos (sum treat) (length treat) avail
	avail = ctrl ++ treat
	combos total n a@(x:xs)
		| total < 0	= binomial (length a) n
		| n == 0	= 0
		| n > length a	= 0
		| n == length a = fromEnum (total < sum a)
		| otherwise	= combos (total - x) (n - 1) xs
				+ combos total n xs

main =	let	r = permtest
			[85, 88, 75, 66, 25, 29, 83, 39, 97]
			[68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
	in do	putStr "> : "; print r
		putStr "<=: "; print $ 100 - r


def calcPi():
    q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
    while True:
        if 4*q+r-t < n*t:
            yield n
            nr = 10*(r-n*t)
            n  = ((10*(3*q+r))//t)-10*n
            q  *= 10
            r  = nr
        else:
            nr = (2*q+r)*l
            nn = (q*(7*k)+2+(r*l))//(t*l)
            q  *= k
            t  *= l
            l  += 2
            k += 1
            n  = nn
            r  = nr

import sys
pi_digits = calcPi()
i = 0
for d in pi_digits:
    sys.stdout.write(str(d))
    i += 1
    if i == 40: print(""); i = 0


  [ immovable
    ]this[ share ]done[ ] is value     (   --> x )

  [ ]'[ replace ]         is to        ( x -->   )

  [ value 1 ]             is Q         (   --> x )
  [ value 0 ]             is R         (   --> x )
  [ value 1 ]             is T         (   --> x )
  [ value 1 ]             is K         (   --> x )
  [ value 3 ]             is N         (   --> x )
  [ value 3 ]             is L         (   --> x )

  [ value 0 ]             is chcount   (   --> x )

  [ echo
    chcount dup 79 =
    if cr
    1+ 80 mod to chcount ] is printch

  [ 4 Q *  R  + T - N T * < iff
      [ N printch
        R N T * - 10 *
        3 Q * R + 10 * T / N 10 * - to N to R
        Q 10 * to Q ]
    else
      [ 2 Q  * R + L *
        7 K * Q * 2 + R L * + T L * / to N to R
        K Q * to Q
        T L * to T
        L 2 + to L
        K 1+  to K ]
    chcount again ]


suppressMessages(library(gmp))
ONE <- as.bigz("1")
TWO <- as.bigz("2")
THREE <- as.bigz("3")
FOUR <- as.bigz("4")
SEVEN <- as.bigz("7")
TEN <- as.bigz("10")

q <- as.bigz("1")
r <- as.bigz("0")
t <- as.bigz("1")
k <- as.bigz("1")
n <- as.bigz("3")
l <- as.bigz("3")

char_printed <- 0

how_many <- 1000

first <- TRUE
while (how_many > 0) {
  if ((FOUR * q + r - t) < (n * t)) {
    if (char_printed == 80) {
      cat("\n")
      char_printed <- 0
    }
    how_many <- how_many - 1
    char_printed <- char_printed + 1
    cat(as.integer(n))
    if (first) {
      cat(".")
      first <- FALSE
      char_printed <- char_printed + 1
    }
    nr <- as.bigz(TEN * (r - n * t))
    n <- as.bigz(((TEN * (THREE * q + r)) %/% t) - (TEN * n))
    q <- as.bigz(q * TEN)
    r <- as.bigz(nr)
  } else {
    nr <- as.bigz((TWO * q + r) * l)
    nn <- as.bigz((q * (SEVEN * k + TWO) + r * l) %/% (t * l))
    q <- as.bigz(q * k)
    t <- as.bigz(t * l)
    l <- as.bigz(l + TWO)
    k <- as.bigz(k + ONE)
    n <- as.bigz(nn)
    r <- as.bigz(nr)
  }
}
cat("\n")


public class PermutationTest {
    private static final int[] data = new int[]{
        85, 88, 75, 66, 25, 29, 83, 39, 97,
        68, 41, 10, 49, 16, 65, 32, 92, 28, 98
    };

    private static int pick(int at, int remain, int accu, int treat) {
        if (remain == 0) return (accu > treat) ? 1 : 0;
        return pick(at - 1, remain - 1, accu + data[at - 1], treat)
            + ((at > remain) ? pick(at - 1, remain, accu, treat) : 0);
    }

    public static void main(String[] args) {
        int treat = 0;
        double total = 1.0;
        for (int i = 0; i <= 8; ++i) {
            treat += data[i];
        }
        for (int i = 19; i >= 11; --i) {
            total *= i;
        }
        for (int i = 9; i >= 1; --i) {
            total /= i;
        }
        int gt = pick(19, 9, 0, treat);
        int le = (int) (total - gt);
        System.out.printf("<= : %f%%  %d\n", 100.0 * le / total, le);
        System.out.printf(" > : %f%%  %d\n", 100.0 * gt / total, gt);
    }
}


# combination(r) generates a stream of combinations of r items from the input array.
def combination(r):
  if r > length or r < 0 then empty
  elif r == length then .
  else  ( [.[0]] + (.[1:]|combination(r-1))),
        ( .[1:]|combination(r))
  end;


#lang racket
(require racket/generator)

(define pidig
  (generator ()
    (let loop ([q 1] [r 0] [t 1] [k 1] [n 3] [l 3])
      (if (< (- (+ r (* 4 q)) t) (* n t))
        (begin (yield n)
               (loop (* q 10) (* 10 (- r (* n t))) t k
                     (- (quotient (* 10 (+ (* 3 q) r)) t) (* 10 n))
                     l))
        (loop (* q k) (* (+ (* 2 q) r) l) (* t l) (+ 1 k)
              (quotient (+ (* (+ 2 (* 7 k)) q) (* r l)) (* t l))
              (+ l 2))))))

(for ([i (in-naturals)])
  (display (pidig))
  (when (zero? i) (display "." ))
  (when (zero? (modulo i 80)) (newline)))


using Combinatorics

meandiff(a::Vector{T}, b::Vector{T}) where T <: Real = mean(a) - mean(b)

function bifurcate(a::AbstractVector, sel::Vector{T}) where T <: Integer
    x         = a[sel]
    asel      = trues(length(a))
    asel[sel] = false
    y         = a[asel]
    return x, y
end

function permutation_test(treated::Vector{T}, control::Vector{T}) where T <: Real
    effect0 = meandiff(treated, control)
    pool    = vcat(treated, control)
    tlen    = length(treated)
    plen    = length(pool)
    better = worse = 0
    for subset in combinations(1:plen, tlen)
        t, c = bifurcate(pool, subset)
        if effect0 < meandiff(t, c)
            better += 1
        else
            worse += 1
        end
    end
    return better, worse
end


// version 1.1.2

val data = intArrayOf(
    85, 88, 75, 66, 25, 29, 83, 39, 97,
    68, 41, 10, 49, 16, 65, 32, 92, 28, 98
)

fun pick(at: Int, remain: Int, accu: Int, treat: Int): Int {
    if (remain == 0) return if (accu > treat) 1 else 0
    return pick(at - 1, remain - 1, accu + data[at - 1], treat) +
           if (at > remain) pick(at - 1, remain, accu, treat) else 0
}

fun main(args: Array<String>) {
    var treat = 0
    var total = 1.0
    for (i in 0..8) treat += data[i]
    for (i in 19 downTo 11) total *= i
    for (i in 9 downTo 1) total /= i
    val gt = pick(19, 9, 0, treat)
    val le = (total - gt).toInt()
    System.out.printf("<= : %f%%  %d\n", 100.0 * le / total, le)
    System.out.printf(" > : %f%%  %d\n", 100.0 * gt / total, gt)
}


Module Checkit {
      Global data(), treat=0
      data()=(85, 88, 75, 66, 25, 29, 83, 39, 97,68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
      Function pick(at, remain, accu) {
            If remain Else =If(accu>treat->1,0):Exit
            =pick(at-1,remain-1,accu+data(at-1))+If(at>remain->pick(at-1, remain, accu),0)
      }
      total=1
      For i=0 to 8 {treat+=data(i)}
      For i=19 to 11 {total*=i}
      For i=9 to 1 {total/=i}
      gt=pick(19,9,0)
      le=total-gt
      Print Format$("<= : {0:1}% {1}", 100*le/total, le)
      Print Format$(" > : {0:1}% {1}", 100*gt/total, gt)
}
Checkit


                    ┌─   ─┐                ┌─     ─┐
  π                 │  1  │                │   1   │           John
 ───  =   4 ∙ arctan│ ─── │     -    arctan│ ───── │             Machin's
  4                 │  5  │                │  239  │               formula
                    └─   ─┘                └─     ─┘

 which expands into:

     ┌─                                                                      ─┐
     │    1         1          1          1          1           1            │
4 ∙  │   ───  -  ──────  +  ──────  -  ──────  +  ──────  -  ────────  +  ... │
     │     1         3          5          7          9           11          │
     │  1∙5       3∙5        5∙5        7∙5        9∙5        11∙5            │
     └─                                                                      ─┘

     ┌─                                                                      ─┐
     │    1         1          1          1          1           1            │
 -   │   ───  -  ──────  +  ──────  -  ──────  +  ──────  -  ────────  +  ... │
     │      1         3          5          7          9           11         │
     │ 1∙239     3∙239      5∙239      7∙239      9∙239      11∙239           │
     └─                                                                      ─┘


pi_digits = Enumerator.new do |y|
  q, r, t, k, n, l = 1, 0, 1, 1, 3, 3
  loop do
    if 4*q+r-t < n*t
      y << n
      nr = 10*(r-n*t)
      n = ((10*(3*q+r)) / t) - 10*n
      q *= 10
      r = nr
    else
      nr = (2*q+r) * l
      nn = (q*(7*k+2)+r*l) / (t*l)
      q *= k
      t *= l
      l += 2
      k += 1
      n = nn
      r = nr
    end
  end
end

print pi_digits.next, "."
loop { print pi_digits.next }


import strformat

const data = [85, 88, 75, 66, 25,
              29, 83, 39, 97, 68,
              41, 10, 49, 16, 65,
              32, 92, 28, 98]

func pick(at, remain, accu, treat: int): int =
  if remain == 0:
    return if accu > treat: 1 else: 0
  return pick(at - 1, remain - 1, accu + data[at - 1], treat) +
    (if at > remain: pick(at - 1, remain, accu, treat) else: 0)

var treat = 0
var le, gt = 0
var total = 1.0
for i in countup(0, 8):
  treat += data[i]
for i in countdown(19, 11):
  total *= float(i)
for i in countdown(9, 1):
  total /= float(i)

gt = pick(19, 9, 0, treat)
le = int(total - float(gt))
echo fmt"<= : {100.0 * float(le) / total:.6f}% {le}"
echo fmt" > : {100.0 * float(gt) / total:.6f}% {gt}"


#!/usr/bin/perl
use warnings;
use strict;

use List::Util qw{ sum };

sub means {
    my @groups = @_;
    return map sum(@$_) / @$_, @groups;
}

sub following {
    my $pattern    = shift;
    my $orig_count = grep $_, @$pattern;
    my $count;
    do {
        my $i = $#{$pattern};
        until (0 > $i) {
            $pattern->[$i] = $pattern->[$i] ? 0 : 1;
            last if $pattern->[$i];
            --$i;
        }
        $count = grep $_, @$pattern;
    } until $count == $orig_count or not $count;
    undef @$pattern unless $count;
}

my @groups;
my $i = 0;
while (<DATA>) {
    chomp;
    $i++, next if /^$/;
    push @{ $groups[$i] }, $_;
}

my @orig_means = means(@groups);
my $orig_cmp   = $orig_means[0] - $orig_means[1];

my $pattern = [ (0) x @{ $groups[0] },
                (1) x @{ $groups[1] }
              ];

my @cmp = (0) x 3;
while (@$pattern) {
    my @perms = map { my $g = $_;
                      [ (@{ $groups[0] }, @{ $groups[1] } ) [ grep $pattern->[$_] == $g, 0 .. $#{$pattern} ] ];
                  } 0, 1;
    my @means = means(@perms);
    $cmp[ ($means[0] - $means[1]) <=> $orig_cmp ]++;
} continue {
    following($pattern);
}
my $all    = sum(@cmp);
my $length = length $all;
for (0, -1, 1) {
    printf "%-7s %${length}d %6.3f%%\n",
        (qw(equal greater less))[$_], $cmp[$_], 100 * $cmp[$_] / $all;
}

__DATA__
85
88
75
66
25
29
83
39
97

68
41
10
49
16
65
32
92
28
98


use num_bigint::BigInt;

fn main() {
    calc_pi();
}

fn calc_pi() {
    let mut q = BigInt::from(1);
    let mut r = BigInt::from(0);
    let mut t = BigInt::from(1);
    let mut k = BigInt::from(1);
    let mut n = BigInt::from(3);
    let mut l = BigInt::from(3);
    let mut first = true;
    loop {
        if &q * 4 + &r - &t < &n * &t {
            print!("{}", n);
            if first {
                print!(".");
                first = false;
            }
            let nr = (&r - &n * &t) * 10;
            n = (&q * 3 + &r) * 10 / &t - &n * 10;
            q *= 10;
            r = nr;
        } else {
            let nr = (&q * 2 + &r) * &l;
            let nn = (&q * &k * 7 + 2 + &r * &l) / (&t * &l);
            q *= &k;
            t *= &l;
            l += 2;
            k += 1;
            n = nn;
            r = nr;
        }
    }
}


object Pi {
  class PiIterator extends Iterable[BigInt] {
    var r: BigInt = 0
    var q, t, k: BigInt = 1
    var n, l: BigInt = 3

    def iterator: Iterator[BigInt] = new Iterator[BigInt] {
      def hasNext = true

      def next(): BigInt = {
        while ((4 * q + r - t) >= (n * t)) {
          val nr = (2 * q + r) * l
          val nn = (q * (7 * k) + 2 + (r * l)) / (t * l)
          q = q * k
          t = t * l
          l = l + 2
          k = k + 1
          n = nn
          r = nr
        }
        val ret = n
        val nr = 10 * (r - n * t)
        n = ((10 * (3 * q + r)) / t) - (10 * n)
        q = q * 10
        r = nr
        ret
      }
    }
  }

  def main(args: Array[String]): Unit = {
    val it = new PiIterator
    println("" + (it.head) + "." + (it.take(300).mkString))
  }

}


constant data = {85, 88, 75, 66, 25, 29, 83, 39, 97,
                 68, 41, 10, 49, 16, 65, 32, 92, 28, 98 }

function pick(int at, int remain, int accu, int treat)
    if remain=0 then return iff(accu>treat?1:0) end if
    return pick(at-1, remain-1, accu+data[at], treat) +
           iff(at>remain?pick(at-1, remain, accu, treat):0)
end function

int treat = 0, le, gt
atom total = 1;
for i=1 to 9 do treat += data[i] end for
for i=19 to 11 by -1 do total *= i end for
for i=9 to 1 by -1 do total /= i end for

gt = pick(19, 9, 0, treat)
le = total - gt;

printf(1,"<= : %f%%  %d\n > : %f%%  %d\n",
       {100*le/total, le, 100*gt/total, gt})


$ include "seed7_05.s7i";
  include "bigint.s7i";

const proc: main is func
  local
    var bigInteger: q is 1_;
    var bigInteger: r is 0_;
    var bigInteger: t is 1_;
    var bigInteger: k is 1_;
    var bigInteger: n is 3_;
    var bigInteger: l is 3_;
    var bigInteger: nn is 0_;
    var bigInteger: nr is 0_;
    var boolean: first is TRUE;
  begin
    while TRUE do
      if 4_ * q + r - t < n * t then
        write(n);
        if first then
          write(".");
          first := FALSE;
        end if;
        nr := 10_ * (r - n * t);
        n := 10_ * (3_ * q + r) div t - 10_ * n;
        q *:= 10_;
        r := nr;
        flush(OUT);
      else
        nr := (2_ * q + r) * l;
        nn := (q * (7_ * k + 2_) + r * l) div (t * l);
        q *:= k;
        t *:= l;
        l +:= 2_;
        incr(k);
        n := nn;
        r := nr;
      end if;
    end while;
  end func;


(load "@lib/simul.l")  # For 'subsets'

(scl 2)

(de _stat (A)
   (let (LenA (length A)  SumA (apply + A))
      (-
         (*/ SumA LenA)
         (*/ (- SumAB SumA) (- LenAB LenA)) ) ) )

(de permutationTest (A B)
   (let
      (AB (append A B)
         SumAB (apply + AB)
         LenAB (length AB)
         Tobs (_stat A)
         Count 0 )
      (*/
         (sum
            '((Perm)
               (inc 'Count)
               (and (>= Tobs (_stat Perm)) 1) )
            (subsets (length A) AB) )
         100.0
         Count ) ) )

(setq
   *TreatmentGroup (0.85 0.88 0.75 0.66 0.25 0.29 0.83 0.39 0.97)
   *ControlGroup   (0.68 0.41 0.10 0.49 0.16 0.65 0.32 0.92 0.28 0.98) )

(let N (permutationTest *TreatmentGroup *ControlGroup)
   (prinl "under = " (round N) "%, over = " (round (- 100.0 N)) "%") )


Define.f meanTreated,meanControl,diffInMeans
Define.f actualmeanTreated,actualmeanControl,actualdiffInMeans

Dim poolA(19)

poolA(1) =85 ; first 9 the treated
poolA(2) =88
poolA(3) =75
poolA(4) =66
poolA(5) =25
poolA(6) =29
poolA(7) =83
poolA(8) =39
poolA(9) =97

poolA(10) =68 ; last 10 the control
poolA(11) =41
poolA(12) =10
poolA(13) =49
poolA(14) =16
poolA(15) =65
poolA(16) =32
poolA(17) =92
poolA(18) =28
poolA(19) =98

Procedure.i IsValidBitString(x,pool,treated)
Protected c,i
For i=1 to pool
mask=1<<(i-1)
If mask&x:c+1:EndIf
Next
If c=treated :ProcedureReturn x
Else         :ProcedureReturn 0
EndIf
EndProcedure

treated=9
control=10

pool   =treated+control

; actual Experimentally observed difference in means

For i=1 to Treated
sumTreated+poolA(i)
Next
For i=Treated+1 to Treated+Control
sumControl+poolA(i)
Next

actualmeanTreated=sumTreated /Treated
actualmeanControl=sumControl /Control
actualdiffInMeans=actualmeanTreated-actualmeanControl

; exhaust the possibilites
For x=1 to 1<<pool

; Valid? i.e. are there 9 "1's" ?
If IsValidBitString(x,pool,treated)
TotalComBinations+1:sumTreated=0:sumControl=0

; separate the groups
For i=pool to 1 Step -1
mask=1<<(i-1):idx=pool-i+1
If mask&x
sumTreated+poolA(idx)
Else
sumControl+poolA(idx)
EndIf
Next

meanTreated=sumTreated /Treated
meanControl=sumControl /Control
diffInMeans=meanTreated-meanControl
; gather the statistics
If (diffInMeans)<=(actualdiffInMeans)
diffLessOrEqual+1
Else
diffGreater+1
EndIf

EndIf
Next
; show our results
; cw(StrF(100*diffLessOrEqual/TotalComBinations,2)+" "+Str(diffLessOrEqual))
; cw(StrF(100*diffGreater    /TotalComBinations,2)+" "+Str(diffGreater))

Debug StrF(100*diffLessOrEqual/TotalComBinations,2)+" "+Str(diffLessOrEqual)
Debug StrF(100*diffGreater    /TotalComBinations,2)+" "+Str(diffGreater)


func pi(callback) {
    var (q, r, t, k, n, l) = (1, 0, 1, 1, 3, 3)
    loop {
        if ((4*q + r - t) < n*t) {
            callback(n)
            static _dot = callback('.')
            var nr = 10*(r - n*t)
            n = ((10*(3*q + r)) // t - 10*n)
            q *= 10
            r = nr
        }
        else {
            var nr = ((2*q + r) * l)
            var nn = ((q*(7*k + 2) + r*l) // (t*l))
            q *= k
            t *= l
            l += 2
            k += 1
            n = nn
            r = nr
        }
    }
}

STDOUT.autoflush(true)
pi(func(digit){ print digit })


CLASS BIGNUM;
BEGIN

    BOOLEAN PROCEDURE TISZERO(T); TEXT T;
        TISZERO := T = "0";

    TEXT PROCEDURE TSHL(T); TEXT T;
        TSHL :- IF TISZERO(T) THEN T ELSE T & "0";

    TEXT PROCEDURE TSHR(T); TEXT T;
        TSHR :- IF T.LENGTH = 1 THEN "0" ELSE T.SUB(1, T.LENGTH - 1);

    INTEGER PROCEDURE TSIGN(T); TEXT T;
        TSIGN := IF TISZERO(T) THEN 0
            ELSE IF T.SUB(1, 1) = "-" THEN -1
            ELSE 1;

    TEXT PROCEDURE TABS(T); TEXT T;
        TABS :- IF TSIGN(T) < 0 THEN T.SUB(2, T.LENGTH - 1) ELSE T;

    TEXT PROCEDURE TNEGATE(T); TEXT T;
        TNEGATE :- IF TSIGN(T) <= 0 THEN TABS(T) ELSE ("-" & T);

    TEXT PROCEDURE TREVERSE(T); TEXT T;
    BEGIN
        INTEGER I, J;
        I := 1; J := T.LENGTH;
        WHILE I < J DO
        BEGIN CHARACTER C1, C2;
            T.SETPOS(I); C1 := T.GETCHAR;
            T.SETPOS(J); C2 := T.GETCHAR;
            T.SETPOS(I); T.PUTCHAR(C2);
            T.SETPOS(J); T.PUTCHAR(C1);
            I := I + 1;
            J := J - 1;
        END;
        TREVERSE :- T;
    END TREVERSE;

    INTEGER PROCEDURE TCMPUNSIGNED(A, B); TEXT A, B;
    BEGIN
        INTEGER ALEN, BLEN, RESULT;
        ALEN := A.LENGTH; BLEN := B.LENGTH;
        IF ALEN < BLEN THEN
            RESULT := -1
        ELSE IF ALEN > BLEN THEN
            RESULT := 1
        ELSE BEGIN
            INTEGER CMP, I; BOOLEAN DONE;
            A.SETPOS(1);
            B.SETPOS(1);
            I := 1;
            WHILE I <= ALEN AND NOT DONE DO
            BEGIN
                I := I + 1;
                CMP := RANK(A.GETCHAR) - RANK(B.GETCHAR);
                IF NOT (CMP = 0) THEN
                    DONE := TRUE;
            END;
            RESULT := CMP;
        END;
        TCMPUNSIGNED := RESULT;
    END TCMPUNSIGNED;

    INTEGER PROCEDURE TCMP(A, B); TEXT A, B;
    BEGIN
        BOOLEAN ANEG, BNEG;
        ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
        IF ANEG AND BNEG THEN
           TCMP := -TCMPUNSIGNED(TABS(A), TABS(B))
        ELSE IF NOT ANEG AND BNEG THEN
           TCMP := 1
        ELSE IF ANEG AND NOT BNEG THEN
           TCMP := -1
        ELSE
           TCMP := TCMPUNSIGNED(A, B);
    END TCMP;

    TEXT PROCEDURE TADDUNSIGNED(A, B); TEXT A, B;
    BEGIN
        INTEGER CARRY, I, J;
        TEXT BF;
        I := A.LENGTH;
        J := B.LENGTH;
        BF :- BLANKS(MAX(I, J) + 1);
        WHILE I >= 1 OR J >= 1 DO BEGIN
            INTEGER X, Y, Z;
            IF I >= 1 THEN BEGIN
                A.SETPOS(I); I := I - 1; X := RANK(A.GETCHAR) - RANK('0');
            END;
            IF J >= 1 THEN BEGIN
                B.SETPOS(J); J := J - 1; Y := RANK(B.GETCHAR) - RANK('0');
            END;
            Z := X + Y + CARRY;
            IF Z < 10 THEN
            BEGIN BF.PUTCHAR(CHAR(Z + RANK('0'))); CARRY := 0;
            END ELSE
            BEGIN BF.PUTCHAR(CHAR(MOD(Z, 10) + RANK('0'))); CARRY := 1;
            END;
        END;
        IF CARRY > 0 THEN
            BF.PUTCHAR(CHAR(CARRY + RANK('0')));
        BF :- TREVERSE(BF.STRIP);
        TADDUNSIGNED :- BF;
    END TADDUNSIGNED;

    TEXT PROCEDURE TADD(A, B); TEXT A, B;
    BEGIN
        BOOLEAN ANEG, BNEG;
        ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
        IF NOT ANEG AND BNEG THEN          ! (+7)+(-5) =  (7-5) =   2 ;
            TADD :- TSUBUNSIGNED(A, TABS(B))
        ELSE IF ANEG AND NOT BNEG THEN     ! (-7)+(+5) =  (5-7) =  -2 ;
            TADD :- TSUBUNSIGNED(B, TABS(A))
        ELSE IF ANEG AND BNEG THEN         ! (-7)+(-5) = -(7+5) = -12 ;
            TADD :- TNEGATE(TADDUNSIGNED(TABS(A), TABS(B)))
        ELSE                               ! (+7)+(+5) =  (7+5) =  12 ;
            TADD :- TADDUNSIGNED(A, B);
    END TADD;

    TEXT PROCEDURE TSUBUNSIGNED(A, B); TEXT A, B;
    BEGIN
        INTEGER I, J, CARRY;
        I := A.LENGTH; J := B.LENGTH;
        IF I < J OR I = J AND A < B THEN
            TSUBUNSIGNED :- TNEGATE(TSUBUNSIGNED(B, A)) ELSE
        BEGIN
            TEXT BF;
            BF :- BLANKS(MAX(I, J) + 1);
            WHILE I >= 1 OR J >= 1 DO
            BEGIN
                INTEGER X, Y, Z;
                IF I >= 1 THEN
                BEGIN A.SETPOS(I); I := I - 1;
                    X := RANK(A.GETCHAR) - RANK('0');
                END;
                IF J >= 1 THEN
                BEGIN B.SETPOS(J); J := J - 1;
                    Y := RANK(B.GETCHAR) - RANK('0');
                END;
                Z := X - Y - CARRY;
                IF Z >= 0 THEN
                BEGIN
                    BF.PUTCHAR(CHAR(RANK('0') + Z));
                    CARRY := 0;
                END ELSE
                BEGIN
                    BF.PUTCHAR(CHAR(RANK('0') + MOD(10 + Z, 10)));
                    CARRY := 1; ! (Z / 10);
                END;
            END;
            BF :- BF.STRIP;
            BF :- TREVERSE(BF);
            BF.SETPOS(1);
            WHILE BF.LENGTH > 1 AND THEN BF.GETCHAR = '0' DO
            BEGIN
                BF :- BF.SUB(2, BF.LENGTH - 1);
                BF.SETPOS(1);
            END;
            TSUBUNSIGNED :- BF;
        END;
    END TSUBUNSIGNED;

    TEXT PROCEDURE TSUB(A, B); TEXT A, B;
    BEGIN
        BOOLEAN ANEG, BNEG;
        ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
        IF ANEG AND BNEG THEN              ! (-7)-(-5) = -(7-5) =  -2 ;
            TSUB :- TNEGATE(TSUBUNSIGNED(TABS(A), TABS(B)))
        ELSE IF NOT ANEG AND BNEG THEN     ! (+7)-(-5) =  (7+5) =  12 ;
            TSUB :- TADDUNSIGNED(A, TABS(B))
        ELSE IF ANEG AND NOT BNEG THEN     ! (-7)-(+5) = -(7+5) = -12 ;
            TSUB :- TNEGATE(TADDUNSIGNED(TABS(A), B))
        ELSE                               ! (+7)-(+5) =  (7-5) =   2 ;
            TSUB :- TSUBUNSIGNED(A, B);
    END TSUB;

    TEXT PROCEDURE TMULUNSIGNED(A, B); TEXT A, B;
    BEGIN
        INTEGER ALEN, BLEN;
        ALEN := A.LENGTH; BLEN := B.LENGTH;
        IF ALEN < BLEN THEN
            TMULUNSIGNED :- TMULUNSIGNED(B, A)
        ELSE BEGIN
            TEXT PRODUCT; INTEGER J;
            PRODUCT :- "0";
            FOR J := 1 STEP 1 UNTIL BLEN DO BEGIN
                TEXT PART; INTEGER I, Y, CARRY;
                B.SETPOS(J); Y := RANK(B.GETCHAR) - RANK('0');
                PART :- BLANKS(ALEN + BLEN + 1); PART.SETPOS(1);
                FOR I := ALEN STEP -1 UNTIL 1 DO BEGIN
                    INTEGER X, Z;
                    A.SETPOS(I); X := RANK(A.GETCHAR) - RANK('0');
                    Z := X * Y + CARRY;
                    IF Z < 10 THEN BEGIN
                        PART.PUTCHAR(CHAR(RANK('0') + Z));
                        CARRY := 0;
                    END ELSE BEGIN
                        PART.PUTCHAR(CHAR(RANK('0') + MOD(Z, 10)));
                        CARRY := Z // 10;
                    END;
                END;
                IF CARRY > 0 THEN
                    PART.PUTCHAR(CHAR(RANK('0') + CARRY));
                PART :- PART.SUB(1, PART.POS - 1);
                PART :- TREVERSE(PART);
                PART.SETPOS(1);
                WHILE PART.LENGTH > 1 AND THEN PART.GETCHAR = '0' DO
                BEGIN
                    PART :- PART.SUB(2, PART.LENGTH - 1);
                    PART.SETPOS(1);
                END;
                PRODUCT :- TADDUNSIGNED(TSHL(PRODUCT), PART);
            END;
            TMULUNSIGNED :- PRODUCT;
        END;
    END TMULUNSIGNED;

    TEXT PROCEDURE TMUL(A, B); TEXT A, B;
    BEGIN
        BOOLEAN ANEG, BNEG;
        ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
        IF ANEG AND BNEG THEN              ! (-7)*(-5) =  (7*5) =>  35 ;
           TMUL :- TMULUNSIGNED(TABS(A), TABS(B))
        ELSE IF NOT ANEG AND BNEG THEN     ! (+7)*(-5) = -(7*5) => -35 ;
           TMUL :- TNEGATE(TMULUNSIGNED(A, TABS(B)))
        ELSE IF ANEG AND NOT BNEG THEN     ! (-7)*(+5) = -(7*5) => -35 ;
           TMUL :- TNEGATE(TMULUNSIGNED(TABS(A), B))
        ELSE                               ! (+7)*(+5) =  (7*5) =>  35 ;
           TMUL :- TMULUNSIGNED(A, B);
    END TMUL;

    CLASS DIVMOD(DIV,MOD); TEXT DIV,MOD;;

    REF(DIVMOD) PROCEDURE TDIVMODUNSIGNED(A, B); TEXT A, B;
    BEGIN
        INTEGER CC;
        REF(DIVMOD) RESULT;
        IF TISZERO(B) THEN
            ERROR("DIVISION BY ZERO");
        CC := TCMPUNSIGNED(A, B);
        IF CC < 0 THEN
            RESULT :- NEW DIVMOD("0", A)
        ELSE IF CC = 0 THEN
            RESULT :- NEW DIVMOD("1", "0")
        ELSE BEGIN
            INTEGER ALEN, BLEN, AIDX;
            TEXT Q, R;
            ALEN := A.LENGTH; BLEN := B.LENGTH;
            Q :- BLANKS(ALEN); Q.SETPOS(1);
            R :- BLANKS(ALEN); R.SETPOS(1);
            R := A.SUB(1, BLEN - 1); R.SETPOS(BLEN);
            FOR AIDX := BLEN STEP 1 UNTIL ALEN DO
            BEGIN
                INTEGER COUNT; BOOLEAN DONE;
                IF TISZERO(R.STRIP) THEN
                    R.SETPOS(1);
                A.SETPOS(AIDX); R.PUTCHAR(A.GETCHAR);
                WHILE NOT DONE DO
                BEGIN
                    TEXT DIFF;
                    DIFF :- TSUBUNSIGNED(R.STRIP, B);
                    IF TSIGN(DIFF) < 0 THEN
                        DONE := TRUE
                    ELSE BEGIN
                        R := DIFF; R.SETPOS(DIFF.LENGTH + 1);
                        COUNT := COUNT + 1;
                    END;
                END;
                IF (NOT (COUNT = 0)) OR (NOT (Q.POS = 1)) THEN
                    Q.PUTCHAR(CHAR(COUNT + RANK('0')));
            END;
            RESULT :- NEW DIVMOD(Q.STRIP, R.STRIP);
        END;
        TDIVMODUNSIGNED :- RESULT;
    END TDIVMODUNSIGNED;

    REF(DIVMOD) PROCEDURE TDIVMOD(A, B); TEXT A, B;
    BEGIN
        BOOLEAN ANEG, BNEG; REF(DIVMOD) RESULT;
        ANEG := TSIGN(A) < 0; BNEG := TSIGN(B) < 0;
        IF ANEG AND BNEG THEN
            BEGIN
                RESULT :- TDIVMOD(TABS(A), TABS(B));
                RESULT.MOD :- TNEGATE(RESULT.MOD);
            END
        ELSE IF NOT ANEG AND BNEG THEN
            BEGIN
                RESULT :- TDIVMOD(A, TABS(B));
                RESULT.DIV :- TNEGATE(RESULT.DIV);
            END
        ELSE IF ANEG AND NOT BNEG THEN
            BEGIN
                RESULT :- TDIVMOD(TABS(A), B);
                RESULT.DIV :- TNEGATE(RESULT.DIV);
                RESULT.MOD :- TNEGATE(RESULT.MOD);
            END
        ELSE
            RESULT :- TDIVMODUNSIGNED(A, B);
        TDIVMOD :- RESULT;
    END TDIVMOD;

    TEXT PROCEDURE TDIV(A, B); TEXT A, B;
        TDIV :- TDIVMOD(A, B).DIV;

    TEXT PROCEDURE TMOD(A, B); TEXT A, B;
        TMOD :- TDIVMOD(A, B).MOD;

END BIGNUM;


from itertools import combinations as comb

def statistic(ab, a):
    sumab, suma = sum(ab), sum(a)
    return ( suma / len(a) -
             (sumab -suma) / (len(ab) - len(a)) )

def permutationTest(a, b):
    ab = a + b
    Tobs = statistic(ab, a)
    under = 0
    for count, perm in enumerate(comb(ab, len(a)), 1):
        if statistic(ab, perm) <= Tobs:
            under += 1
    return under * 100. / count

treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97]
controlGroup   = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
print("under=%.2f%%, over=%.2f%%" % (under, 100. - under))


permutation.test <- function(treatment, control) {
  perms <- combinations(length(treatment)+length(control),
                        length(treatment),
                        c(treatment, control),
                        set=FALSE)
  p <- mean(rowMeans(perms) <= mean(treatment))
  c(under=p, over=(1-p))
}


#lang racket/base

(define-syntax-rule (inc! x)
  (set! x (add1 x)))

(define (permutation-test control-gr treatment-gr)
  (let ([both-gr (append control-gr treatment-gr)]
        [threshold (apply + control-gr)]
        [more 0]
        [leq 0])
    (let loop ([data both-gr] [sum 0] [needed (length control-gr)] [available (length both-gr)])
      (cond [(zero? needed) (if (>= sum threshold)
                                (inc! more)
                                (inc! leq))]
            [(>= available needed) (loop (cdr data) sum needed (sub1 available))
                                   (loop (cdr data) (+ sum (car data)) (sub1 needed) (sub1 available))]
            [else (void)]))
    (values more leq)))

(let-values ([(more leq) (permutation-test '(68 41 10 49 16 65 32 92 28 98)
                                           '(85 88 75 66 25 29 83 39 97))])
  (let ([sum (+ more leq)])
    (printf "<=: ~a ~a%~n>:  ~a ~a%~n"
            more (real->decimal-string (* 100. (/ more sum)) 2)
            leq (real->decimal-string (* 100. (/ leq sum)) 2))))


use 'java:java.math' stand-alone

def zero: 0 -> math/BigInteger::valueOf;
def one: 1 -> math/BigInteger::valueOf;
def two: 2 -> math/BigInteger::valueOf;
def three: 3 -> math/BigInteger::valueOf;
def four: 4 -> math/BigInteger::valueOf;
def seven: 7 -> math/BigInteger::valueOf;
def ten: 10 -> math/BigInteger::valueOf;

templates g&{q:, r:, t:, k:, n:, l:}
  def u: $four -> q::multiply -> r::add;
  def nt: $n -> t::multiply;
  $ -> #
  when <?($t -> u::subtract <..~$nt>)> do
    $n -> !OUT::write
    $ -> \(<=1> $!\) -> '.' -> !OUT::write
    def v: $three -> q::multiply -> r::add -> ten::multiply;
    def quot: $t -> v::divide;
    0 -> g&{q: $ten -> q::multiply,
      r: $nt -> r::subtract -> ten::multiply,
      t: $t,
      k: $k,
      n: $ten -> n::multiply -> quot::subtract,
      l: $l } !
  otherwise
    def tl: $t -> l::multiply;
    def rl: $r -> l::multiply;
    def term: $q -> seven::multiply -> k::multiply -> two::add -> rl::add;
    $ -> g&{q: $q -> k::multiply,
      r: $two -> q::multiply -> r::add -> l::multiply,
      t: $tl,
      k: $k -> one::add,
      n: $tl -> term::divide,
      l: $l -> two::add} !
end g

1 -> g&{q:$one, r:$zero, t:$one, k:$one, n:$three, l:$three} -> !VOID


package require Tcl 8.6

# http://www.cut-the-knot.org/Curriculum/Algorithms/SpigotForPi.shtml
# http://www.mathpropress.com/stan/bibliography/spigot.pdf
proc piDigitsBySpigot n {
    yield [info coroutine]
    set A [lrepeat [expr {int(floor(10*$n/3.)+1)}] 2]
    set Alen [llength $A]
    set predigits {}
    while 1 {
	set carry 0
	for {set i $Alen} {[incr i -1] > 0} {} {
	    lset A $i [expr {
		[set val [expr {[lindex $A $i] * 10 + $carry}]]
		% [set modulo [expr {2*$i + 1}]]
	    }]
	    set carry [expr {$val / $modulo * $i}]
	}
	lset A 0 [expr {[set val [expr {[lindex $A 0]*10 + $carry}]] % 10}]
	set predigit [expr {$val / 10}]
	if {$predigit < 9} {
	    foreach p $predigits {yield $p}
	    set predigits [list $predigit]
	} elseif {$predigit == 9} {
	    lappend predigits $predigit
	} else {
	    foreach p $predigits {yield [incr p]}
	    set predigits [list 0]
	}
    }
}


sub stats ( @test, @all ) {
    ([+] @test / [email protected]) - ([+] flat @all, (@test X* -1)) / @all - @test
}

my int @treated = <85 88 75 66 25 29 83 39 97>;
my int @control = <68 41 10 49 16 65 32 92 28 98>;
my int @all = flat @treated, @control;

my $base = stats( @treated, @all );

my atomicint @trials[3] = 0, 0, 0;

@all.combinations(+@treated).race.map: { @trials[ 1 + ( stats( $_, @all ) <=> $base ) ]⚛++ }

say 'Counts: <, =, > ', @trials;
say 'Less than    : %', 100 * @trials[0] / [+] @trials;
say 'Equal to     : %', 100 * @trials[1] / [+] @trials;
say 'Greater than : %', 100 * @trials[2] / [+] @trials;
say 'Less or Equal: %', 100 * ( [+] @trials[0,1] ) / [+] @trials;


/*REXX program  performs a    permutation test   on     N + M   subjects  (volunteers): */
                                                 /*     ↑   ↑                           */
                                                 /*     │   │                           */
                                                 /*     │   └─────control  population.  */
                                                 /*     └────────treatment population.  */
n= 9                                             /*define the number of the control pop.*/
data= 85 88 75 66 25 29 83 39 97         68 41 10 49 16 65 32 92 28 98
w= words(data);      m= w - n                    /*w:  volunteers  +  control population*/
L= length(w)                                     /*L:  used to align some output numbers*/
say '# of volunteers & control population: '             w
say 'volunteer population given treatment: '             right(n, L)
say ' control  population given a placebo: '             right(m, L)
say
say 'treatment population efficacy % (percentages): '    subword(data, 1, n)
say ' control  population placebo  % (percentages): '    subword(data, n+1 )
say
                     do v=  0  for w         ;           #.v= word(data, v+1) ;       end
treat= 0;            do i=  0  to n-1        ;           treat= treat + #.i   ;       end
  tot= 1;            do j=  w  to m+1  by -1 ;           tot= tot * j         ;       end
                     do k=w%2  to  1   by -1 ;           tot= tot / k         ;       end

GT= picker(n+m, n, 0)                            /*compute the GT value from PICKER func*/
LE= tot - GT                                     /*   "     "  LE   "   via subtraction.*/
say "<= "  format(100 * LE / tot, ,3)'%'   LE    /*display number with 3 decimal places.*/
say " > "  format(100 * GT / tot, ,3)'%'   GT    /*   "       "     "  "    "       "   */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
picker:  procedure expose #. treat;        parse arg it,rest,eff    /*get the arguments.*/
         if rest==0  then return   eff > treat                      /*is REST = to zero?*/
         if it>rest  then q= picker(it-1, rest, eff)                /*maybe recurse.    */
                     else q= 0
         itP= it - 1                                                /*set temporary var.*/
         return picker(itP,  rest - 1,  eff + #.itP)  +  q          /*recurse.          */


type AnyWriteableObject={write:((textToOutput:string)=>any)};

function calcPi(pipe:AnyWriteableObject) {
    let q = 1n, r=0n, t=1n, k=1n, n=3n, l=3n;
    while (true) {
        if (q * 4n + r - t < n* t) {
            pipe.write(n.toString());
            let nr = (r - n * t) * 10n;
            n  = (q * 3n + r) * 10n / t - n * 10n ;
            q  = q * 10n;
            r  = nr;
        } else {
            let nr = (q * 2n + r) * l;
            let nn = (q * k * 7n + 2n + r * l) / (t * l);
            q = q * k;
            t = t * l;
            l = l + 2n;
            k = k + 1n;
            n  = nn;
            r  = nr;
        }
    }
}

calcPi(process.stdout);


Option Explicit

Sub Main()
Const VECSIZE As Long = 3350
Const BUFSIZE As Long = 201
Dim buffer(1 To BUFSIZE) As Long
Dim vect(1 To VECSIZE) As Long
Dim more As Long, karray As Long, num As Long, k As Long, l As Long, n As Long

  For n = 1 To VECSIZE
    vect(n) = 2
  Next n
  For n = 1 To BUFSIZE
    karray = 0
    For l = VECSIZE To 1 Step -1
      num = 100000 * vect(l) + karray * l
      karray = num \ (2 * l - 1)
      vect(l) = num - karray * (2 * l - 1)
    Next l
    k = karray \ 100000
    buffer(n) = more + k
    more = karray - k * 100000
  Next n
  Debug.Print CStr(buffer(1));
  Debug.Print "."
  l = 0
  For n = 2 To BUFSIZE
    Debug.Print Format$(buffer(n), "00000");
    l = l + 1
    If l = 10 Then
      l = 0
      Debug.Print 'line feed
    End If
  Next n
End Sub


def statistic(ab, a)
  sumab, suma = ab.inject(:+).to_f, a.inject(:+).to_f
  suma / a.size - (sumab - suma) / (ab.size - a.size)
end

def permutationTest(a, b)
  ab = a + b
  tobs = statistic(ab, a)
  under = count = 0
  ab.combination(a.size) do |perm|
    under += 1 if statistic(ab, perm) <= tobs
    count += 1
  end
  under * 100.0 / count
end

treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97]
controlGroup   = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
under = permutationTest(treatmentGroup, controlGroup)
puts "under=%.2f%%, over=%.2f%%" % [under, 100 - under]


fn main() {
    let treatment = vec![85, 88, 75, 66, 25, 29, 83, 39, 97];
    let control = vec![68, 41, 10, 49, 16, 65, 32, 92, 28, 98];

    let mut data_set = control.clone();
    data_set.extend_from_slice(&treatment);

    let greater = combinations(treatment.iter().sum(), treatment.len() as i64, &data_set) as f64;
    let lesser = combinations(control.iter().sum(), control.len() as i64, &data_set) as f64;
    let total = binomial(data_set.len() as i64, treatment.len() as i64) as f64;

    println!("<= : {}%", (lesser / total * 100.0));
    println!(" > : {}%", (greater / total * 100.0));
}

fn factorial(x: i64) -> i64 {
    let mut product = 1;
    for a in 1..(x + 1) {
        product *= a;
    }
    product
}

fn binomial(n: i64, k: i64) -> i64 {
    let numerator = factorial(n);
    let denominator = factorial(k) * factorial(n - k);
    numerator / denominator
}

fn combinations(total: i64, number: i64, data: &[i64]) -> i64 {
    if total < 0 {
        return binomial(data.len() as i64, number);
    }

    if number == 0 {
        return 0;
    }

    if number > data.len() as i64 {
        return 0;
    }

    if number == data.len() as i64 {
        if total < data.iter().sum() {
            return 1;
        } else {
            return 0;
        }
    }

    let tail = &data[1..];
    combinations(total - data[0], number - 1, &tail) + combinations(total, number, &tail)
}


object PermutationTest extends App {
  private val data =
    Array(85, 88, 75, 66, 25, 29, 83, 39, 97, 68, 41, 10, 49, 16, 65, 32, 92, 28, 98)
  private var (total, treat) = (1.0, 0)

  private def pick(at: Int, remain: Int, accu: Int, treat: Int): Int = {
    if (remain == 0) return if (accu > treat) 1 else 0

    pick(at - 1, remain - 1, accu + data(at - 1), treat) +
      (if (at > remain) pick(at - 1, remain, accu, treat) else 0)
  }

  for (i <- 0 to 8) treat += data(i)
  for (j <- 19 to 11 by -1) total *= j
  for (g <- 9 to 1 by -1) total /= g

  private val gt = pick(19, 9, 0, treat)
  private val le = (total - gt).toInt

  println(f"<= : ${100.0 * le / total}%f%%  ${le}%d")
  println(f" > : ${100.0 * gt / total}%f%%  ${gt}%d")

}


Imports System
Imports System.Numerics

Public Module Module1
	Public Sub Main()
        Dim two, three, four, seven, ten, k, q, t, l, n, r, nn, nr As BigInteger,
            first As Boolean = True
        two = New BigInteger(2) : three = New BigInteger(3) : four = two + two
        seven = three + four : ten = three + seven : k = BigInteger.One
        q = k : t = k : l = three : n = three : r = BigInteger.Zero
        While True
            If four * q + r - t < n * t Then
                Console.Write(n) : If first Then Console.Write(".") : first = False
                nr = ten * (r - n * t) : n = ten * (three * q + r) / t - ten * n
                q *= ten
            Else
                nr = (two * q + r) * l : nn = (q * seven * k + two + r * l) / (t * l)
                q *= k : t *= l : l += two : k += BigInteger.One : n = nn
            End If
            r = nr
        End While
    End Sub

End Module


import "/big" for BigInt
import "io" for Stdout

var calcPi = Fn.new {
    var nn = BigInt.zero
    var nr = BigInt.zero
    var q  = BigInt.one
    var r  = BigInt.zero
    var t  = BigInt.one
    var k  = BigInt.one
    var n  = BigInt.three
    var l  = BigInt.three
    var first = true
    while (true) {
        if (q * BigInt.four + r - t < n * t) {
            System.write(n)
            if (first) {
                System.write(".")
                first = false
            }
            Stdout.flush()
            nr = (r - n * t) * BigInt.ten
            n = (q * BigInt.three + r) * BigInt.ten / t  - n * BigInt.ten
            q =  q * BigInt.ten
            r = nr
        } else {
            nr = (q * BigInt.two + r) * l
            nn = (q * BigInt.new(7) * k + BigInt.two + r * l) / (t * l)
            q  = q * k
            t  = t * l
            l  = l + BigInt.two
            k  = k + BigInt.one
            n = nn.copy()
            r = nr
        }
    }
}

calcPi.call()


$ include "seed7_05.s7i";
  include "float.s7i";

const array integer: treatmentGroup is [] (85, 88, 75, 66, 25, 29, 83, 39, 97);
const array integer: controlGroup  is [] (68, 41, 10, 49, 16, 65, 32, 92, 28, 98);
const array integer: both is treatmentGroup & controlGroup;

const func integer: pick (in integer: at, in integer: remain, in integer: accu, in integer: treat) is func
  result
    var integer: picked is 0;
  begin
    if remain = 0 then
      picked := ord(accu > treat);
    else
      picked := pick(at - 1, remain - 1, accu + both[at], treat);
      if at > remain then
        picked +:= pick(at - 1, remain, accu, treat);
      end if;
    end if;
  end func;

const proc: main is func
  local
    var integer: experimentalResult is 0;
    var integer: treat is 0;
    var integer: total is 1;
    var integer: le is 0;
    var integer: gt is 0;
    var integer: i is 0;
  begin
    for experimentalResult range treatmentGroup do
      treat +:= experimentalResult;
    end for;
    total := 19 ! 10;  # Binomial coefficient
    gt := pick(19, 9, 0, treat);
    le := total - gt;
    writeln("<= : " <& 100.0 * flt(le) / flt(total) digits 6 <& "%  " <& le);
    writeln(" > : " <& 100.0 * flt(gt) / flt(total) digits 6 <& "%  " <& gt);
  end func;


func statistic(ab, a) {
    var(sumab, suma) = (ab.sum, a.sum)
    suma/a.size - ((sumab-suma) / (ab.size-a.size))
}

func permutationTest(a, b) {
    var ab = (a + b)
    var tobs = statistic(ab, a)
    var under = (var count = 0)
    ab.combinations(a.len, {|*perm|
        statistic(ab, perm) <= tobs && (under += 1)
        count += 1
    })
    under * 100 / count
}

var treatmentGroup = [85, 88, 75, 66, 25, 29, 83, 39, 97]
var controlGroup   = [68, 41, 10, 49, 16, 65, 32, 92, 28, 98]
var under = permutationTest(treatmentGroup, controlGroup)
say ("under=%.2f%%, over=%.2f%%" % (under, 100 - under))


package require Tcl 8.5

# Difference of means; note that the first list must be the concatenation of
# the two lists (because this is cheaper to work with).
proc statistic {AB A} {
    set sumAB [tcl::mathop::+ {*}$AB]
    set sumA [tcl::mathop::+ {*}$A]
    expr {
	$sumA / double([llength $A]) -
	($sumAB - $sumA) / double([llength $AB] - [llength $A])
    }
}

# Selects all k-sized combinations from a list.
proc selectCombinationsFrom {k l} {
    if {$k == 0} {return {}} elseif {$k == [llength $l]} {return [list $l]}
    set all {}
    set n [expr {[llength $l] - [incr k -1]}]
    for {set i 0} {$i < $n} {} {
        set first [lindex $l $i]
	incr i
        if {$k == 0} {
            lappend all $first
	} else {
	    foreach s [selectCombinationsFrom $k [lrange $l $i end]] {
		lappend all [list $first {*}$s]
	    }
        }
    }
    return $all
}

# Compute the permutation test value and its complement.
proc permutationTest {A B} {
    set whole [concat $A $B]
    set Tobs [statistic $whole $A]
    set undercount 0
    set overcount 0
    set count 0
    foreach perm [selectCombinationsFrom [llength $A] $whole] {
	set t [statistic $whole $perm]
	incr count
	if {$t <= $Tobs} {incr undercount} else {incr overcount}
    }
    set count [tcl::mathfunc::double $count]
    list [expr {$overcount / $count}] [expr {$undercount / $count}]
}


n = 1000
long = 10 * int(n / 4)
needdecimal = 1 //true
dim a(long)
nines = 0
predigit = 0  // {First predigit is a 0}

for j = 1 to long
  a(j-1) = 2  // {Start with 2s}
next j

for j = 1 to n
  q = 0
  for i = long to 1 step -1
    //  {Work backwards}
    x   = 10*a(i-1) + q*i
    a(i-1) = mod(x, (2*i - 1))
    q  = int(x / (2*i - 1))
  next i
  a(0) = mod(q, 10)
  q = int(q / 10)
  if q = 9 then
    nines = nines + 1
  else
    if q = 10 then
      d = predigit+1
      gosub outputd
      if nines > 0 then
        for k = 1 to nines
          d =  0
          gosub outputd
        next k
      end if
      predigit = 0
      nines = 0
    else
      d = predigit
      gosub outputd
      predigit = q
      if nines <> 0 then
        for k = 1 to nines
          d =  9
          gosub outputd
        next k
        nines = 0
      end if
    end if
  end if
next j
print predigit
end

label outputd
if needdecimal then
  if d = 0 then return : fi
  print d;
  print ".";
  needdecimal = 0 //false
else
  print "", d;
endif
return


var [const] BN=Import("zklBigNum"),
   one=BN(1), two=BN(2), three=BN(3), four=BN(4), seven=BN(7), ten=BN(10);

fcn calcPiDigits{
   reg q=BN(1), r=BN(0), t=BN(1), k=BN(1), n=BN(3), l=BN(3);
   first:=True; N:=0;
   while(True){ if((N+=1)==1000){ GarbageMan.collect(); N=0; } // take a deep breath ...
      if(four*q + r - t < n*t){
         n.print(); if(first){ print("."); first=False; }
	 nr:=(r - n*t).mul(ten);	// 10 * (r - n * t);
	 n=(three*q).add(r).mul(ten)	// ((10*(3*q + r))/t) - 10*n;
	   .div(t).sub(ten*n);
	 q.mul(ten);			// q *= 10;
	 r=nr;
      }else{
	 nr:=(two*q).add(r).mul(l);	// (2*q + r)*l;
	 nn:=(q*seven).mul(k).add(two)	// (q*(7*k + 2) + r*l)/(t*l);
	     .add(r*l).div(t*l);
	 q.mul(k);   t.mul(l);		// q*=k; t*=l;
	 l.add(two); k.add(one);	// l+=2; k++;
	 n=nn; r=nr;
      }
   }
}();


#import std
#import nat
#import flo

treatment_group = <85,88,75,66,25,29,83,39,97>
control_group   = <68,41,10,49,16,65,32,92,28,98>

f = # returns the fractions of alternative mean differences above and below the actual

float~*; -+
   vid^~G(plus,~&)+ (not [email protected])*|@htX; ~~ float+ length,
   minus*+ mean^~*C/~& ^DrlrjXS(~&l,choices)^/-- [email protected]+-

#show+

t = --* *-'%'@lrNCC printf/$'%0.2f' times/$100. f(treatment_group,control_group)


import "/fmt" for Fmt

var data = [85, 88, 75, 66, 25, 29, 83, 39, 97, 68, 41, 10, 49, 16, 65, 32, 92, 28, 98]

var pick // recursive
pick = Fn.new { |at, remain, accu, treat|
    if (remain == 0) return (accu > treat) ? 1 : 0
    return pick.call(at-1, remain-1, accu + data[at-1], treat) +
           ((at > remain) ? pick.call(at-1, remain, accu, treat) : 0)
}

var treat = 0
var total = 1
for (i in 0..8)   treat = treat + data[i]
for (i in 19..11) total = total * i
for (i in 9..1)   total = total / i
var gt = pick.call(19, 9, 0, treat)
var le = (total - gt).truncate
Fmt.print("<= : $f\%  $d", 100 * le / total, le)
Fmt.print(" > : $f\%  $d", 100 * gt / total, gt)


fcn permutationTest(a,b){
   ab    := a.extend(b);
   tObs  := a.sum(0);
   combs := Utils.Helpers.pickNFrom(a.len(),ab);  // 92,378
   under := combs.reduce('wrap(sum,perm){ sum+(perm.sum(0) <= tObs) },0);
   100.0 * under / combs.len();
}

treatmentGroup := T(85, 88, 75, 66, 25, 29, 83, 39, 97);
controlGroup   := T(68, 41, 10, 49, 16, 65, 32, 92, 28, 98);
under          := permutationTest(treatmentGroup, controlGroup);
println("Under =%6.2f%%\nOver  =%6.2f%%".fmt(under, 100.0 - under));


F φ(n)
   R sum((1..n).filter(k -> gcd(@n, k) == 1).map(k -> 1))

F perfect_totient(cnt)
   [Int] r

   L(n0) 1..
      V parts = 0
      V n = n0
      L n != 1
         n = φ(n)
         parts += n
      I parts == n0
         r [+]= n0
         I r.len == cnt
            R r

print(perfect_totient(20))


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program totientPerfect64.s   */

/************************************/
/* Constantes                       */
/************************************/
.include "../includeConstantesARM64.inc"
.equ MAXI,      20

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessNumber:       .asciz " @ "
szCarriageReturn:   .asciz "\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:           .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:
    mov x4,#2                   // start number
    mov x6,#0                   // line counter
    mov x7,#0                   // result counter
1:
    mov x0,x4
    mov x5,#0                   // totient sum
2:
    bl totient                  // compute totient
    add x5,x5,x0                // add totient
    cmp x0,#1
    beq 3f
    b 2b
3:
    cmp x5,x4                   // compare number and totient sum
    bne 4f
    mov x0,x4                   // display result if equals
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    ldr x0,qAdrszMessNumber
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess            // display message
    add x7,x7,#1
    add x6,x6,#1                // increment indice line display
    cmp x6,#5                   // if = 5  new line
    bne 4f
    mov x6,#0
    ldr x0,qAdrszCarriageReturn
    bl affichageMess
4:
    add x4,x4,#1                 // increment number
    cmp x7,#MAXI                 // maxi ?
    blt 1b                       // and loop

    ldr x0,qAdrszCarriageReturn
    bl affichageMess

100:                            // standard end of the program
    mov x0, #0                  // return code
    mov x8,EXIT
    svc #0                      // perform the system call
qAdrszCarriageReturn:    .quad szCarriageReturn
qAdrsZoneConv:           .quad sZoneConv
qAdrszMessNumber:        .quad szMessNumber
/******************************************************************/
/*     compute totient of number                                  */
/******************************************************************/
/* x0 contains number  */
totient:
    stp x1,lr,[sp,-16]!       // save  registers
    stp x2,x3,[sp,-16]!       // save  registers
    stp x4,x5,[sp,-16]!       // save  registers
    mov x4,x0                 // totient
    mov x5,x0                 // save number
    mov x1,#0                 // for first divisor
1:                            // begin loop
    mul x3,x1,x1              // compute square
    cmp x3,x5                 // compare number
    bgt 4f                    // end
    add x1,x1,#2              // next divisor
    udiv x2,x5,x1
    msub x3,x1,x2,x5          // compute remainder
    cmp x3,#0                 // remainder null ?
    bne 3f
2:                            // begin loop 2
    udiv x2,x5,x1
    msub x3,x1,x2,x5          // compute remainder
    cmp x3,#0
    csel x5,x2,x5,eq          // new value = quotient
    beq 2b

    udiv x2,x4,x1             // divide totient
    sub x4,x4,x2              // compute new totient
3:
    cmp x1,#2                 // first divisor ?
    mov x0,1
    csel x1,x0,x1,eq          // divisor = 1
    b 1b                      // and loop
4:
    cmp x5,#1                 // final value > 1
    ble 5f
    mov x0,x4                 // totient
    mov x1,x5                 // divide by value
    udiv x2,x4,x5             // totient divide by value
    sub x4,x4,x2              // compute new totient
5:

    mov x0,x4
100:
    ldp x4,x5,[sp],16         // restaur  registers
    ldp x2,x3,[sp],16         // restaur  registers
    ldp x1,lr,[sp],16         // restaur  registers
    ret

/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../includeARM64.inc"


BEGIN # find the first 20 perfect totient numbers #
    # returns the number of integers k where 1 <= k <= n that are mutually prime to n #
    PROC totient = ( INT n )INT: # algorithm from the second Go sample #
        IF   n < 3 THEN 1
        ELIF n = 3 THEN 2
        ELSE
            INT result := n;
            INT v      := n;
            INT i      := 2;
            WHILE i * i <= v DO
                IF v MOD i = 0 THEN
                    WHILE v MOD i = 0 DO v OVERAB i OD;
                    result -:= result OVER i
                FI;
                IF i = 2 THEN
                   i := 1
                FI;
                i +:= 2
            OD;
            IF v > 1 THEN result -:= result OVER v FI;
            result
         FI # totient # ;
    # find the first 20 perfect totient numbers #
    INT p count := 0;
    FOR i FROM 2 WHILE p count < 20 DO
        INT t   := totient( i );
        INT sum := t;
        WHILE t /= 1 DO
            t    := totient( t );
            sum +:= t
        OD;
        IF sum = i THEN
            # have a perfect totient #
            p count +:= 1;
            print( ( " ", whole( i, 0 ) ) )
        FI
    OD;
    print( ( newline ) )
END


/* ARM assembly Raspberry PI or android with termux */
/*  program totientPerfect.s   */

 /* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"
.equ MAXI,      20

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessNumber:       .asciz " @ "
szCarriageReturn:   .asciz "\n"

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:           .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:
    mov r4,#2                   @ start number
    mov r6,#0                   @ line counter
    mov r7,#0                   @ result counter
1:
    mov r0,r4
    mov r5,#0                   @ totient sum
2:
    bl totient                  @ compute totient
    add r5,r5,r0                @ add totient
    cmp r0,#1
    beq 3f
    b 2b
3:
    cmp r5,r4                   @ compare number and totient sum
    bne 4f
    mov r0,r4                   @ display result if equals
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    ldr r0,iAdrszMessNumber
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess            @ display message
    add r7,r7,#1
    add r6,r6,#1                @ increment indice line display
    cmp r6,#5                   @ if = 5  new line
    bne 4f
    mov r6,#0
    ldr r0,iAdrszCarriageReturn
    bl affichageMess
4:
    add r4,r4,#1                 @ increment number
    cmp r7,#MAXI                 @ maxi ?
    blt 1b                       @ and loop

    ldr r0,iAdrszCarriageReturn
    bl affichageMess

100:                            @ standard end of the program
    mov r0, #0                  @ return code
    mov r7, #EXIT               @ request to exit program
    svc #0                      @ perform the system call
iAdrszCarriageReturn:    .int szCarriageReturn
iAdrsZoneConv:           .int sZoneConv
iAdrszMessNumber:        .int szMessNumber
/******************************************************************/
/*     compute totient of number                                  */
/******************************************************************/
/* r0 contains number  */
totient:
    push {r1-r5,lr}           @ save  registers
    mov r4,r0                 @ totient
    mov r5,r0                 @ save number
    mov r1,#0                 @ for first divisor
1:                            @ begin loop
    mul r3,r1,r1              @ compute square
    cmp r3,r5                 @ compare number
    bgt 4f                    @ end
    add r1,r1,#2              @ next divisor
    mov r0,r5
    bl division
    cmp r3,#0                 @ remainder null ?
    bne 3f
2:                            @ begin loop 2
    mov r0,r5
    bl division
    cmp r3,#0
    moveq r5,r2               @ new value = quotient
    beq 2b

    mov r0,r4                 @ totient
    bl division
    sub r4,r4,r2              @ compute new totient
3:
    cmp r1,#2                 @ first divisor ?
    moveq r1,#1               @ divisor = 1
    b 1b                      @ and loop
4:
    cmp r5,#1                 @ final value > 1
    ble 5f
    mov r0,r4                 @ totient
    mov r1,r5                 @ divide by value
    bl division
    sub r4,r4,r2              @ compute new totient
5:
    mov r0,r4
100:
    pop {r1-r5,pc}             @ restaur registers

/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"


totient: function [n][
    tt: new n
    nn: new n
    i: new 2

    while [nn >= i ^ 2][
        if zero? nn % i [
            while [zero? nn % i]->
                'nn / i
            'tt - tt/i
        ]
        if i = 2 ->
            i: new 1

        'i + 2
    ]
    if nn > 1 ->
        'tt - tt/nn

    return tt
]

x: new 1
num: new 0

while [num < 20][
    tot: new x
    s: new 0

    while [tot <> 1][
        tot: totient tot
        's + tot
    ]
    if s = x [
        prints ~"|x| "
        inc 'num
    ]
    'x + 2
]
print ""


MsgBox, 262144, , % result := perfect_totient(20)

perfect_totient(n){
    count := sum := tot := 0, str:= "", m := 1
    while (count < n) {
        tot := m, sum := 0
        while (tot != 1) {
            tot := totient(tot)
            sum += tot
        }
        if (sum = m) {
            str .= m ", "
            count++
        }
        m++
    }
    return Trim(str, ", ")
}

totient(n) {
    tot := n,     i := 2
    while (i*i <= n) {
        if !Mod(n, i) {
            while !Mod(n, i)
                n /= i
            tot -= tot / i
        }
        if (i = 2)
            i := 1
        i+=2
    }
    if (n > 1)
        tot -= tot / n
    return tot
}


# syntax: GAWK -f PERFECT_TOTIENT_NUMBERS.AWK
BEGIN {
    i = 20
    printf("The first %d perfect totient numbers:\n%s\n",i,perfect_totient(i))
    exit(0)
}
function perfect_totient(n,  count,m,str,sum,tot) {
    for (m=1; count<n; m++) {
      tot = m
      sum = 0
      while (tot != 1) {
        tot = totient(tot)
        sum += tot
      }
      if (sum == m) {
        str = str m " "
        count++
      }
    }
    return(str)
}
function totient(n,  i,tot) {
    tot = n
    for (i=2; i*i<=n; i+=2) {
      if (n % i == 0) {
        while (n % i == 0) {
          n /= i
        }
        tot -= tot / i
      }
      if (i == 2) {
        i = 1
      }
    }
    if (n > 1) {
      tot -= tot / n
    }
    return(tot)
}