\ Array of doors; init to empty; accessing a non-extant member will return
\ 'null', which is treated as 'false', so we don't need to initialize it:
[] var, doors

\ given a door number, get the value and toggle it:
: toggle-door \ n --
	doors @ over a:@
	not rot swap a:! drop ;

\ print which doors are open:
: .doors
	(
		doors @ over a:@ nip
		if . space else drop then
	) 1 100 loop ;

\ iterate over the doors, skipping 'n':
: main-pass \ n --
	0
	true
	repeat
		drop
		dup toggle-door
		over n:+
		dup 101 <
	while 2drop drop ;

\ calculate the first 100 doors:
' main-pass 1 100 loop
\ print the results:
.doors cr bye


open System

let gamma z =
    let lanczosCoefficients = [76.18009172947146;-86.50532032941677;24.01409824083091;-1.231739572450155;0.1208650973866179e-2;-0.5395239384953e-5]
    let rec sumCoefficients acc i coefficients =
        match coefficients with
        | []   -> acc
        | h::t -> sumCoefficients (acc + (h/i)) (i+1.0) t
    let gamma = 5.0
    let x = z - 1.0
    Math.Pow(x + gamma + 0.5, x + 0.5) * Math.Exp( -(x + gamma + 0.5) ) * Math.Sqrt( 2.0 * Math.PI ) * sumCoefficients 1.000000000190015 (x + 1.0) lanczosCoefficients

let factorial n = gamma ((float n) + 1.)

let expected n =
    seq {for i in 1 .. n do yield (factorial n) / System.Math.Pow((float n), (float i)) / (factorial (n - i)) }
    |> Seq.sum

let r = System.Random()

let trial n =
    let count = ref 0
    let x = ref 1
    let bits = ref 0
    while (!bits &&& !x) = 0 do
        count := !count + 1
        bits := !bits ||| !x
        x := 1 <<< r.Next(n)
    !count

let tested n times = (float (Seq.sum (seq { for i in 1 .. times do yield (trial n) }))) / (float times)

let results = seq {
    for n in 1 .. 20 do
        let avg = tested n 1000000
        let theory = expected n
        yield n, avg, theory
    }

[<EntryPoint>]
let main argv =
    printfn " N     average   analytical   (error)"
    printfn "------------------------------------"
    results
    |> Seq.iter (fun (n, avg, theory) ->
        printfn "%2i    %2.6f    %2.6f    %+2.3f%%" n avg theory ((avg / theory - 1.) * 100.))
    0


attractive?: function [x] -> prime? size factors.prime x

print select 1..120 => attractive?


# syntax: GAWK -f ATTRACTIVE_NUMBERS.AWK
# converted from C
BEGIN {
    limit = 120
    printf("attractive numbers from 1-%d:\n",limit)
    for (i=1; i<=limit; i++) {
      n = count_prime_factors(i)
      if (is_prime(n)) {
        printf("%d ",i)
      }
    }
    printf("\n")
    exit(0)
}
function count_prime_factors(n,  count,f) {
    f = 2
    if (n == 1) { return(0) }
    if (is_prime(n)) { return(1) }
    while (1) {
      if (!(n % f)) {
        count++
        n /= f
        if (n == 1) { return(count) }
        if (is_prime(n)) { f = n }
      }
      else if (f >= 3) { f += 2 }
      else { f = 3 }
    }
}
function is_prime(x,  i) {
    if (x <= 1) {
      return(0)
    }
    for (i=2; i<=int(sqrt(x)); i++) {
      if (x % i == 0) {
        return(0)
      }
    }
    return(1)
}


#[ AVL tree adapted from Julienne Walker's presentation at
   http://eternallyconfuzzled.com/tuts/datastructures/jsw_tut_avl.aspx.

   Uses bounded recursive versions for insertion and deletion.
]#

type

  # Objects strored in the tree must be comparable.
  Comparable = concept x, y
    (x == y) is bool
    (x < y) is bool

  # Direction used to select a child.
  Direction = enum Left, Right

  # Description of the tree node.
  Node[T: Comparable] = ref object
    data: T                             # Payload.
    balance: range[-2..2]               # Balance factor (bounded).
    links: array[Direction, Node[T]]    # Children.

  # Description of a tree.
  AvlTree[T: Comparable] = object
    root: Node[T]

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

func opp(dir: Direction): Direction {.inline.} =
  ## Return the opposite of a direction.
  Direction(1 - ord(dir))

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

func single(root: Node; dir: Direction): Node =
  ## Single rotation.

  result = root.links[opp(dir)]
  root.links[opp(dir)] = result.links[dir]
  result.links[dir] = root

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

func double(root: Node; dir: Direction): Node =
  ## Double rotation.

  let save = root.links[opp(dir)].links[dir]

  root.links[opp(dir)].links[dir] = save.links[opp(dir)]
  save.links[opp(dir)] = root.links[opp(dir)]
  root.links[opp(dir)] = save

  result = root.links[opp(dir)]
  root.links[opp(dir)] = result.links[dir]
  result.links[dir] = root

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

func adjustBalance(root: Node; dir: Direction; balance: int) =
  ## Adjust balance factors after double rotation.

  let node1 = root.links[dir]
  let node2 = node1.links[opp(dir)]

  if node2.balance == 0:
    root.balance = 0
    node1.balance = 0

  elif node2.balance == balance:
    root.balance = -balance
    node1.balance = 0

  else:
    root.balance = 0
    node1.balance = balance

  node2.balance = 0

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

func insertBalance(root: Node; dir: Direction): Node =
  ## Rebalancing after an insertion.

  let node = root.links[dir]
  let balance = 2 * ord(dir) - 1

  if node.balance == balance:
    root.balance = 0
    node.balance = 0
    result = root.single(opp(dir))

  else:
    root.adjustBalance(dir, balance)
    result = root.double(opp(dir))

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

func insertR(root: Node; data: root.T): tuple[node: Node, done: bool] =
  ## Insert data (recursive way).

  if root.isNil:
    return (Node(data: data), false)

  let dir = if root.data < data: Right else: Left
  var done: bool
  (root.links[dir], done) = root.links[dir].insertR(data)
  if done:
    return (root, true)

  inc root.balance, 2 * ord(dir) - 1
  result = case root.balance
           of 0: (root, true)
           of -1, 1: (root, false)
           else: (root.insertBalance(dir), true)

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

func removeBalance(root: Node; dir: Direction): tuple[node: Node, done: bool] =
  ## Rebalancing after a deletion.

  let node = root.links[opp(dir)]
  let balance = 2 * ord(dir) - 1
  if node.balance == -balance:
    root.balance = 0
    node.balance = 0
    result = (root.single(dir), false)
  elif node.balance == balance:
    root.adjustBalance(opp(dir), -balance)
    result = (root.double(dir), false)
  else:
    root.balance = -balance
    node.balance = balance
    result = (root.single(dir), true)

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

func removeR(root: Node; data: root.T): tuple[node: Node, done: bool] =
  ## Remove data (recursive way).

  if root.isNil:
    return (nil, false)

  var data = data
  if root.data == data:
    if root.links[Left].isNil:
      return (root.links[Right], false)
    if root.links[Right].isNil:
      return (root.links[Left], false)
    var heir = root.links[Left]
    while not heir.links[Right].isNil:
      heir = heir.links[Right]
    root.data = heir.data
    data = heir.data

  let dir = if root.data < data: Right else: Left
  var done: bool
  (root.links[dir], done) = root.links[dir].removeR(data)
  if done:
    return (root, true)
  dec root.balance, 2 * ord(dir) - 1
  result = case root.balance
           of -1, 1: (root, true)
           of 0: (root, false)
           else: root.removeBalance(dir)

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

func insert(tree: var AvlTree; data: tree.T) =
  ## Insert data in an AVL tree.
  tree.root = tree.root.insertR(data).node

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

func remove(tree: var AvlTree; data: tree.T) =
  ## Remove data from an AVL tree.
  tree.root = tree.root.removeR(data).node

#———————————————————————————————————————————————————————————————————————————————————————————————————

import json

var tree: AvlTree[int]
echo pretty(%tree)

echo "Insert test:"
tree.insert(3)
tree.insert(1)
tree.insert(4)
tree.insert(1)
tree.insert(5)
echo pretty(%tree)

echo ""
echo "Remove test:"
tree.remove(3)
tree.remove(1)
echo pretty(%tree)


USING: formatting fry io kernel locals math math.factorials
math.functions math.ranges random sequences ;

: (analytical) ( m n -- x )
    [ drop factorial ] [ ^ /f ] [ - factorial / ] 2tri ;

: analytical ( n -- x )
    dup [1,b] [ (analytical) ] with map-sum ;

: loop-length ( n -- x )
    [ 0 0 1 [ 2dup bitand zero? ] ] dip
    '[ [ 1 + ] 2dip bitor 1 _ random shift ] while 2drop ;

:: average-loop-length ( n #tests -- x )
     0 #tests [ n loop-length + ] times #tests / ;

: stats ( n -- avg exp )
    [ 1,000,000 average-loop-length ] [ analytical ] bi ;

: .line ( n -- )
    dup stats 2dup / 1 - 100 *
    "%2d %8.4f %8.4f %6.3f%%\n" printf ;

" n\tavg\texp.\tdiff\n-------------------------------" print
20 [1,b] [ .line ] each


Const max_N = 20, max_ciclos = 1000000

Function Factorial(Byval N As Integer) As Double
    Dim As Double d: d = 1
    If N = 0 Then Factorial = 1: Exit Function
    While (N > 1)
        d *= N
        N -= 1
    Wend
    Factorial = d
End Function

Function Analytical(N As Integer) As Double
    Dim As Double i, sum = 0
    For i = 1 To N
        sum += Factorial(N) / N^i / Factorial(N-i)
    Next i
    Return sum
End Function

Function Average(N As Integer, ciclos As Double) As Double
    Dim As Integer i, x, bits, sum = 0
    For i = 0 To ciclos - 1
        x = 1 : bits = 0
        While (bits And x) = 0
            sum += 1
            bits Or= x
            x = 1 Shl (Rnd * (N - 1))
        Wend
    Next i
    Return sum / ciclos
End Function

Randomize Timer
Print " N    promedio   analitico    (error)"
Print "--- ---------- ----------- ----------"
For N As Integer = 1 To max_N
    Dim As Double avg = Average(N, max_ciclos)
    Dim As Double ana = Analytical(N)
    Dim As Double diff = abs(avg-ana) / ana * 100
    Print Using " ## #####.###0  #####.###0    ###.#0%"; N; avg; ana; diff
Next N
Sleep


package main

import (
    "fmt"
    "math"
    "math/rand"
)

const nmax = 20

func main() {
    fmt.Println(" N    average    analytical    (error)")
    fmt.Println("===  =========  ============  =========")
    for n := 1; n <= nmax; n++ {
        a := avg(n)
        b := ana(n)
        fmt.Printf("%3d  %9.4f  %12.4f  (%6.2f%%)\n",
            n, a, b, math.Abs(a-b)/b*100)
    }
}

func avg(n int) float64 {
    const tests = 1e4
    sum := 0
    for t := 0; t < tests; t++ {
        var v [nmax]bool
        for x := 0; !v[x]; x = rand.Intn(n) {
            v[x] = true
            sum++
        }
    }
    return float64(sum) / tests
}

func ana(n int) float64 {
    nn := float64(n)
    term := 1.
    sum := 1.
    for i := nn - 1; i >= 1; i-- {
        term *= i / nn
        sum += term
    }
    return sum
}


10 DEFINT A-Z
20 M=120
30 DIM C(M): C(0)=-1: C(1)=-1
40 FOR I=2 TO SQR(M)
50 IF NOT C(I) THEN FOR J=I+I TO M STEP I: C(J)=-1: NEXT
60 NEXT
70 FOR I=2 TO M
80 N=I: C=0
90 FOR J=2 TO M
100 IF NOT C(J) THEN IF N MOD J=0 THEN N=N\J: C=C+1: GOTO 100
110 NEXT
120 IF NOT C(C) THEN PRINT I,
130 NEXT


get "libhdr"
manifest $( MAXIMUM = 120 $)

let sieve(prime, max) be
$(  for i=0 to max do i!prime := i>=2
    for i=2 to max>>1 if i!prime
    $(  let j = i<<1
        while j <= max do
        $(  j!prime := false
            j := j+i
        $)
    $)
$)

let factors(n, prime, max) = valof
$(  let count = 0
    for i=2 to max if i!prime
        until n rem i
        $(  count := count + 1
            n := n / i
        $)
    resultis count
$)

let start() be
$(  let n = 0 and prime = vec MAXIMUM
    sieve(prime, MAXIMUM)
    for i=2 to MAXIMUM
        if factors(i, prime, MAXIMUM)!prime
        $(  writed(i, 4)
            n := n + 1
            unless n rem 18 do wrch('*N')
        $)
    wrch('*N')
$)


#include <stdio.h>

#define TRUE 1
#define FALSE 0
#define MAX 120

typedef int bool;

bool is_prime(int n) {
    int d = 5;
    if (n < 2) return FALSE;
    if (!(n % 2)) return n == 2;
    if (!(n % 3)) return n == 3;
    while (d *d <= n) {
        if (!(n % d)) return FALSE;
        d += 2;
        if (!(n % d)) return FALSE;
        d += 4;
    }
    return TRUE;
}

int count_prime_factors(int n) {
    int count = 0, f = 2;
    if (n == 1) return 0;
    if (is_prime(n)) return 1;
    while (TRUE) {
        if (!(n % f)) {
            count++;
            n /= f;
            if (n == 1) return count;
            if (is_prime(n)) f = n;
        }
        else if (f >= 3) f += 2;
        else f = 3;
    }
}

int main() {
    int i, n, count = 0;
    printf("The attractive numbers up to and including %d are:\n", MAX);
    for (i = 1; i <= MAX; ++i) {
        n = count_prime_factors(i);
        if (is_prime(n)) {
            printf("%4d", i);
            if (!(++count % 20)) printf("\n");
        }
    }
    printf("\n");
    return 0;
}


class AVLNode {
  @key : Int;
  @balance : Int;
  @height : Int;
  @left : AVLNode;
  @right : AVLNode;
  @above : AVLNode;

  New(key : Int, above : AVLNode) {
    @key := key;
    @above := above;
  }

  method : public : GetKey() ~ Int {
    return @key;
  }

  method : public : GetLeft() ~ AVLNode {
    return @left;
  }

  method : public : GetRight() ~ AVLNode {
    return @right;
  }

  method : public : GetAbove() ~ AVLNode {
    return @above;
  }

  method : public : GetBalance() ~ Int {
    return @balance;
  }

  method : public : GetHeight() ~ Int {
    return @height;
  }

  method : public : SetBalance(balance : Int) ~ Nil {
    @balance := balance;
  }

  method : public : SetHeight(height : Int) ~ Nil {
    @height := height;
  }

  method : public : SetAbove(above : AVLNode) ~ Nil {
    @above := above;
  }

  method : public : SetLeft(left : AVLNode) ~ Nil {
    @left := left;
  }

  method : public : SetRight(right : AVLNode) ~ Nil {
    @right := right;
  }

  method : public : SetKey(key : Int) ~ Nil {
    @key := key;
  }
}

class AVLTree {
  @root : AVLNode;

  New() {}

  method : public : Insert(key : Int) ~ Bool {
    if(@root = Nil) {
      @root := AVLNode->New( key, Nil);
      return true;
    };

    n := @root;
    while(true) {
      if(n->GetKey() = key) {
        return false;
      };

      parent := n;
      goLeft := n->GetKey() > key;
      n := goLeft ? n->GetLeft() : n->GetRight();

      if(n = Nil) {
        if(goLeft) {
          parent->SetLeft(AVLNode->New( key, parent));
        } else {
          parent->SetRight(AVLNode->New( key, parent));
        };
        Rebalance(parent);
        break;
      };
    };

    return true;
  }

  method : Delete(node : AVLNode) ~ Nil {
    if (node->GetLeft() = Nil & node->GetRight() = Nil) {
      if (node ->GetAbove() = Nil) {
        @root := Nil;
      } else {
        parent := node ->GetAbove();
        if (parent->GetLeft() = node) {
          parent->SetLeft(Nil);
        } else {
          parent->SetRight(Nil);
        };
        Rebalance(parent);
      };
      return;
    };

    if (node->GetLeft() <> Nil) {
      child := node->GetLeft();
      while (child->GetRight() <> Nil) {
        child := child->GetRight();
      };
      node->SetKey(child->GetKey());
      Delete(child);
    } else {
      child := node->GetRight();
      while (child->GetLeft() <> Nil) {
        child := child->GetLeft();
      };
      node->SetKey(child->GetKey());
      Delete(child);
    };
  }

  method : public : Delete(delKey : Int) ~ Nil {
    if (@root = Nil) {
      return;
    };

    child := @root;
    while (child <> Nil) {
      node := child;
      child := delKey >= node->GetKey() ? node->GetRight() : node->GetLeft();
      if (delKey = node->GetKey()) {
        Delete(node);
        return;
      };
    };
  }

  method : Rebalance(n : AVLNode) ~ Nil {
    SetBalance(n);

    if (n->GetBalance() = -2) {
      if (Height(n->GetLeft()->GetLeft()) >= Height(n->GetLeft()->GetRight())) {
        n := RotateRight(n);
      }
      else {
        n := RotateLeftThenRight(n);
      };

    } else if (n->GetBalance() = 2) {
      if(Height(n->GetRight()->GetRight()) >= Height(n->GetRight()->GetLeft())) {
        n := RotateLeft(n);
      }
      else {
        n := RotateRightThenLeft(n);
      };
    };

    if(n->GetAbove() <> Nil) {
      Rebalance(n->GetAbove());
    } else {
      @root := n;
    };
  }

  method : RotateLeft(a : AVLNode) ~ AVLNode {
    b := a->GetRight();
    b->SetAbove(a->GetAbove());

    a->SetRight(b->GetLeft());

    if(a->GetRight() <> Nil) {
      a->GetRight()->SetAbove(a);
    };

    b->SetLeft(a);
    a->SetAbove(b);

    if (b->GetAbove() <> Nil) {
      if (b->GetAbove()->GetRight() = a) {
        b->GetAbove()->SetRight(b);
      } else {
        b->GetAbove()->SetLeft(b);
      };
    };

    SetBalance(a);
    SetBalance(b);

    return b;
  }

  method : RotateRight(a : AVLNode) ~ AVLNode {
    b := a->GetLeft();
    b->SetAbove(a->GetAbove());

    a->SetLeft(b->GetRight());

    if (a->GetLeft() <> Nil) {
      a->GetLeft()->SetAbove(a);
    };

    b->SetRight(a);
    a->SetAbove(b);

    if (b->GetAbove() <> Nil) {
      if (b->GetAbove()->GetRight() = a) {
        b->GetAbove()->SetRight(b);
      } else {
        b->GetAbove()->SetLeft(b);
      };
    };

    SetBalance(a);
    SetBalance(b);

    return b;
  }

  method : RotateLeftThenRight(n : AVLNode) ~ AVLNode {
    n->SetLeft(RotateLeft(n->GetLeft()));
    return RotateRight(n);
  }

  method : RotateRightThenLeft(n : AVLNode) ~ AVLNode {
    n->SetRight(RotateRight(n->GetRight()));
    return RotateLeft(n);
  }

  method : SetBalance(n : AVLNode) ~ Nil {
    Reheight(n);
    n->SetBalance(Height(n->GetRight()) - Height(n->GetLeft()));
  }

  method : Reheight(node : AVLNode) ~ Nil {
    if(node <> Nil) {
      node->SetHeight(1 + Int->Max(Height(node->GetLeft()), Height(node->GetRight())));
    };
  }

  method : Height(n : AVLNode) ~ Int {
    if(n = Nil) {
      return -1;
    };

    return n->GetHeight();
  }

  method : public : PrintBalance() ~ Nil {
    PrintBalance(@root);
  }

  method : PrintBalance(n : AVLNode) ~ Nil {
    if (n <> Nil) {
      PrintBalance(n->GetLeft());
      balance := n->GetBalance();
      "{$balance} "->Print();
      PrintBalance(n->GetRight());
    };
  }
}

class Test {
  function : Main(args : String[]) ~ Nil {
    tree := AVLTree->New();

    "Inserting values 1 to 10"->PrintLine();
    for(i := 1; i < 10; i+=1;) {
      tree->Insert(i);
    };

    "Printing balance: "->Print();
    tree->PrintBalance();
  }
}


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

/*******************************************/
/* Constantes file                         */
/*******************************************/
/* for this file see task include a file in language AArch64 assembly*/
.include "../includeConstantesARM64.inc"

.equ NBDOORS,   100
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:       .asciz "The door @ is open.\n"

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
stTableDoors:    .skip   8 * NBDOORS
sZoneConv:       .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                             // entry of program
    // display first line
    ldr x3,qAdrstTableDoors       // table address
    mov x5,1
1:
    mov x4,x5
2:                               // begin loop
    ldr x2,[x3,x4,lsl #3]        // read doors index x4
    cmp x2,#0
    cset x2,eq
    //moveq x2,#1                // if x2 = 0   1 -> x2
    //movne x2,#0                // if x2 = 1   0 -> x2
    str x2,[x3,x4,lsl #3]        // store value of doors
    add x4,x4,x5                 // increment x4 with  x5 value
    cmp x4,NBDOORS               // number of doors ?
    ble 2b                       // no -> loop
    add x5,x5,#1                 // increment the increment !!
    cmp x5,NBDOORS               // number of doors ?
    ble 1b                       // no -> loop

                                 // loop display state doors
    mov x4,#0
3:
    ldr x2,[x3,x4,lsl #3]        // read state doors x4 index
    cmp x2,#0
    beq 4f
    mov x0,x4                    // open -> display message
    ldr x1,qAdrsZoneConv          // display value index
    bl conversion10              // call function
    ldr x0,qAdrsMessResult
    ldr x1,qAdrsZoneConv
    bl strInsertAtCharInc        // insert result at first @ character
    bl affichageMess             // display message
4:
    add x4,x4,1
    cmp x4,NBDOORS
    ble 3b                       // loop

100:                             // standard end of the program
    mov x0,0                     // return code
    mov x8,EXIT                  // request to exit program
    svc 0                        // perform the system call

qAdrstTableDoors:        .quad stTableDoors
qAdrsMessResult:         .quad sMessResult
qAdrsZoneConv:           .quad sZoneConv
/***********************************************/
/*        File Include fonctions                        */
/********************************************************/
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"


import System.Random
import qualified Data.Set as S
import Text.Printf

findRep :: (Random a, Integral a, RandomGen b) => a -> b -> (a, b)
findRep n gen = findRep' (S.singleton 1) 1 gen
    where
      findRep' seen len gen'
          | S.member fx seen = (len, gen'')
          | otherwise        = findRep' (S.insert fx seen) (len + 1) gen''
          where
            (fx, gen'') = randomR (1, n) gen'

statistical :: (Integral a, Random b, Integral b, RandomGen c, Fractional d) =>
               a -> b -> c -> (d, c)
statistical samples size gen =
    let (total, gen') = sar samples gen 0
    in ((fromIntegral total) / (fromIntegral samples), gen')
    where
      sar 0        gen' acc = (acc, gen')
      sar samples' gen' acc =
          let (len, gen'') = findRep size gen'
          in sar (samples' - 1) gen'' (acc + len)

factorial :: (Integral a) => a -> a
factorial n = foldl (*) 1 [1..n]

analytical :: (Integral a, Fractional b) => a -> b
analytical n = sum [fromIntegral num /
                    fromIntegral (factorial (n - i)) /
                    fromIntegral (n ^ i) |
                    i <- [1..n]]
    where num = factorial n

test :: (Integral a, Random b, Integral b, PrintfArg b, RandomGen c) =>
        a -> [b] -> c -> IO c
test _       []     gen = return gen
test samples (x:xs) gen = do
  let (st, gen') = statistical samples x gen
      an         = analytical x
      err        = abs (st - an) / st * 100.0
      str        = printf "%3d  %9.4f  %12.4f  (%6.2f%%)\n"
                   x (st :: Float) (an :: Float) (err :: Float)
  putStr str
  test samples xs gen'

main :: IO ()
main = do
  putStrLn " N    average    analytical    (error)"
  putStrLn "===  =========  ============  ========="
  let samples = 10000 :: Integer
      range   = [1..20] :: [Integer]
  _ <- test samples range $ mkStdGen 0
  return ()


using System;

namespace AttractiveNumbers {
    class Program {
        const int MAX = 120;

        static bool IsPrime(int n) {
            if (n < 2) return false;
            if (n % 2 == 0) return n == 2;
            if (n % 3 == 0) return n == 3;
            int d = 5;
            while (d * d <= n) {
                if (n % d == 0) return false;
                d += 2;
                if (n % d == 0) return false;
                d += 4;
            }
            return true;
        }

        static int PrimeFactorCount(int n) {
            if (n == 1) return 0;
            if (IsPrime(n)) return 1;
            int count = 0;
            int f = 2;
            while (true) {
                if (n % f == 0) {
                    count++;
                    n /= f;
                    if (n == 1) return count;
                    if (IsPrime(n)) f = n;
                } else if (f >= 3) {
                    f += 2;
                } else {
                    f = 3;
                }
            }
        }

        static void Main(string[] args) {
            Console.WriteLine("The attractive numbers up to and including {0} are:", MAX);
            int i = 1;
            int count = 0;
            while (i <= MAX) {
                int n = PrimeFactorCount(i);
                if (IsPrime(n)) {
                    Console.Write("{0,4}", i);
                    if (++count % 20 == 0) Console.WriteLine();
                }
                ++i;
            }
            Console.WriteLine();
        }
    }
}


@implementation AVLTree

-(BOOL)insertWithKey:(NSInteger)key {

    if (self.root == nil) {
        self.root = [[AVLTreeNode alloc]initWithKey:key andParent:nil];
    } else {

        AVLTreeNode *n = self.root;
        AVLTreeNode *parent;

        while (true) {

            if (n.key == key) {
                return false;
            }

            parent = n;

            BOOL goLeft = n.key > key;
            n = goLeft ? n.left : n.right;

            if (n == nil) {

                if (goLeft) {
                    parent.left = [[AVLTreeNode alloc]initWithKey:key andParent:parent];
                } else {
                    parent.right = [[AVLTreeNode alloc]initWithKey:key andParent:parent];
                }
                [self rebalanceStartingAtNode:parent];
                break;
            }
        }
    }

    return true;
}

-(void)rebalanceStartingAtNode:(AVLTreeNode*)n {

    [self setBalance:@[n]];

    if (n.balance == -2) {
        if ([self height:(n.left.left)] >= [self height:n.left.right]) {
            n = [self rotateRight:n];
        } else {
            n = [self rotateLeftThenRight:n];
        }
    } else if (n.balance == 2) {
        if ([self height:n.right.right] >= [self height:n.right.left]) {
            n = [self rotateLeft:n];
        } else {
            n = [self rotateRightThenLeft:n];
        }
    }

    if (n.parent != nil) {
        [self rebalanceStartingAtNode:n.parent];
    } else {
        self.root = n;
    }
}

-(AVLTreeNode*)rotateRight:(AVLTreeNode*)a {

    AVLTreeNode *b = a.left;
    b.parent = a.parent;

    a.left = b.right;

    if (a.left != nil) {
        a.left.parent = a;
    }

    b.right = a;
    a.parent = b;

    if (b.parent != nil) {
        if (b.parent.right == a) {
            b.parent.right = b;
        } else {
            b.parent.left = b;
        }
    }

    [self setBalance:@[a,b]];
    return b;

}

-(AVLTreeNode*)rotateLeftThenRight:(AVLTreeNode*)n {

    n.left = [self rotateLeft:n.left];
    return [self rotateRight:n];

}

-(AVLTreeNode*)rotateRightThenLeft:(AVLTreeNode*)n {

    n.right = [self rotateRight:n.right];
    return [self rotateLeft:n];
}

-(AVLTreeNode*)rotateLeft:(AVLTreeNode*)a {

    //set a's right node as b
    AVLTreeNode* b = a.right;
    //set b's parent as a's parent (which could be nil)
    b.parent = a.parent;
    //in case b had a left child transfer it to a
    a.right = b.left;

    // after changing a's reference to the right child, make sure the parent is set too
    if (a.right != nil) {
        a.right.parent = a;
    }

    // switch a over to the left to be b's left child
    b.left = a;
    a.parent = b;

    if (b.parent != nil) {
        if (b.parent.right == a) {
            b.parent.right = b;
        } else {
            b.parent.right = b;
        }
    }

    [self setBalance:@[a,b]];

    return b;

}

-(void) setBalance:(NSArray*)nodesArray {

    for (AVLTreeNode* n in nodesArray) {

        n.balance = [self height:n.right] - [self height:n.left];
    }

}

-(int)height:(AVLTreeNode*)n {

    if (n == nil) {
        return -1;
    }

    return 1 + MAX([self height:n.left], [self height:n.right]);
}

-(void)printKey:(AVLTreeNode*)n {
    if (n != nil) {
        [self printKey:n.left];
        NSLog(@"%ld", n.key);
        [self printKey:n.right];
    }
}

-(void)printBalance:(AVLTreeNode*)n {
    if (n != nil) {
        [self printBalance:n.left];
        NSLog(@"%ld", n.balance);
        [self printBalance:n.right];
    }
}
@end
-- test

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

        AVLTree *tree = [AVLTree new];
        NSLog(@"inserting values 1 to 6");
        [tree insertWithKey:1];
        [tree insertWithKey:2];
        [tree insertWithKey:3];
        [tree insertWithKey:4];
        [tree insertWithKey:5];
        [tree insertWithKey:6];

        NSLog(@"printing balance: ");
        [tree printBalance:tree.root];

        NSLog(@"printing key: ");
        [tree printKey:tree.root];
    }
    return 0;
}


form open_doors_unopt.
  data: lv_door  type i,
        lv_count type i value 1.
  data: lt_doors type standard table of c initial size 100.
  field-symbols: <wa_door> type c.
  do 100 times.
    append initial line to lt_doors assigning <wa_door>.
    <wa_door> = 'X'.
  enddo.

  while lv_count < 100.
    lv_count = lv_count + 1.
    lv_door = lv_count.
    while lv_door < 100.
      read table lt_doors index lv_door assigning <wa_door>.
      if <wa_door> = ' '.
        <wa_door> = 'X'.
      else.
        <wa_door> = ' '.
      endif.
      add lv_count to lv_door.
    endwhile.
  endwhile.

  loop at lt_doors assigning <wa_door>.
    if <wa_door> = 'X'.
      write : / 'Door', (4) sy-tabix right-justified, 'is open' no-gap.
    endif.
  endloop.
endform.


import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class AverageLoopLength {

    private static final int N = 100000;

    //analytical(n) = sum_(i=1)^n (n!/(n-i)!/n**i)
    private static double analytical(int n) {
        double[] factorial = new double[n + 1];
        double[] powers = new double[n + 1];
        powers[0] = 1.0;
        factorial[0] = 1.0;
        for (int i = 1; i <= n; i++) {
            factorial[i] = factorial[i - 1] * i;
            powers[i] = powers[i - 1] * n;
        }
        double sum = 0;
        //memoized factorial and powers
        for (int i = 1; i <= n; i++) {
            sum += factorial[n] / factorial[n - i] / powers[i];
        }
        return sum;
    }

    private static double average(int n) {
        Random rnd = new Random();
        double sum = 0.0;
        for (int a = 0; a < N; a++) {
            int[] random = new int[n];
            for (int i = 0; i < n; i++) {
                random[i] = rnd.nextInt(n);
            }
            Set<Integer> seen = new HashSet<>(n);
            int current = 0;
            int length = 0;
            while (seen.add(current)) {
                length++;
                current = random[current];
            }
            sum += length;
        }
        return sum / N;
    }

    public static void main(String[] args) {
        System.out.println(" N    average    analytical    (error)");
        System.out.println("===  =========  ============  =========");
        for (int i = 1; i <= 20; i++) {
            double avg = average(i);
            double ana = analytical(i);
            System.out.println(String.format("%3d  %9.4f  %12.4f  (%6.2f%%)", i, avg, ana, ((ana - avg) / ana * 100)));
        }
    }
}


#include <iostream>
#include <iomanip>

#define MAX 120

using namespace std;

bool is_prime(int n) {
    if (n < 2) return false;
    if (!(n % 2)) return n == 2;
    if (!(n % 3)) return n == 3;
    int d = 5;
    while (d *d <= n) {
        if (!(n % d)) return false;
        d += 2;
        if (!(n % d)) return false;
        d += 4;
    }
    return true;
}

int count_prime_factors(int n) {
    if (n == 1) return 0;
    if (is_prime(n)) return 1;
    int count = 0, f = 2;
    while (true) {
        if (!(n % f)) {
            count++;
            n /= f;
            if (n == 1) return count;
            if (is_prime(n)) f = n;
        }
        else if (f >= 3) f += 2;
        else f = 3;
    }
}

int main() {
    cout << "The attractive numbers up to and including " << MAX << " are:" << endl;
    for (int i = 1, count = 0; i <= MAX; ++i) {
        int n = count_prime_factors(i);
        if (is_prime(n)) {
            cout << setw(4) << i;
            if (!(++count % 20)) cout << endl;
        }
    }
    cout << endl;
    return 0;
}


with javascript_semantics
enum KEY = 0,
     LEFT,
     HEIGHT,    -- (NB +/-1 gives LEFT or RIGHT)
     RIGHT

sequence tree = {}
integer freelist = 0

function newNode(object key)
integer node
    if freelist=0 then
        node = length(tree)+1
        tree &= {key,NULL,1,NULL}
    else
        node = freelist
        freelist = tree[freelist]
        tree[node+KEY..node+RIGHT] = {key,NULL,1,NULL}
    end if
    return node
end function

function height(integer node)
    return iff(node=NULL?0:tree[node+HEIGHT])
end function

procedure setHeight(integer node)
    tree[node+HEIGHT] = max(height(tree[node+LEFT]), height(tree[node+RIGHT]))+1
end procedure

function rotate(integer node, integer direction)
integer idirection = LEFT+RIGHT-direction
integer pivot = tree[node+idirection]
    {tree[pivot+direction],tree[node+idirection]} = {node,tree[pivot+direction]}
    setHeight(node)
    setHeight(pivot)
    return pivot
end function

function getBalance(integer N)
    return iff(N==NULL ? 0 : height(tree[N+LEFT])-height(tree[N+RIGHT]))
end function

function insertNode(integer node, object key)
    if node==NULL then
        return newNode(key)
    end if
    integer c = compare(key,tree[node+KEY])
    if c!=0 then
        integer direction = HEIGHT+c    -- LEFT or RIGHT
-- note this crashes under p2js... (easy to fix, not so easy to find)
--      tree[node+direction] = insertNode(tree[node+direction], key)
        atom tnd = insertNode(tree[node+direction], key)
        tree[node+direction] = tnd
        setHeight(node)
        integer balance = trunc(getBalance(node)/2) -- +/-1 (or 0)
        if balance then
            direction = HEIGHT-balance  -- LEFT or RIGHT
            c = compare(key,tree[tree[node+direction]+KEY])
            if c=balance then
                tree[node+direction] = rotate(tree[node+direction],direction)
            end if
            if c!=0 then
                node = rotate(node,LEFT+RIGHT-direction)
            end if
        end if
    end if
    return node
end function

function minValueNode(integer node)
    while 1 do
        integer next = tree[node+LEFT]
        if next=NULL then exit end if
        node = next
    end while
    return node
end function

function deleteNode(integer root, object key)
integer c
    if root=NULL then return root end if
    c = compare(key,tree[root+KEY])
    if c=-1 then
        tree[root+LEFT] = deleteNode(tree[root+LEFT], key)
    elsif c=+1 then
        tree[root+RIGHT] = deleteNode(tree[root+RIGHT], key)
    elsif tree[root+LEFT]==NULL
       or tree[root+RIGHT]==NULL then
        integer temp = iff(tree[root+LEFT] ? tree[root+LEFT] : tree[root+RIGHT])
        if temp==NULL then  -- No child case
            {temp,root} = {root,NULL}
        else                -- One child case
            tree[root+KEY..root+RIGHT] = tree[temp+KEY..temp+RIGHT]
        end if
        tree[temp+KEY] = freelist
        freelist = temp
    else                    -- Two child case
        integer temp = minValueNode(tree[root+RIGHT])
        tree[root+KEY] = tree[temp+KEY]
        tree[root+RIGHT] = deleteNode(tree[root+RIGHT], tree[temp+KEY])
    end if
    if root=NULL then return root end if
    setHeight(root)
    integer balance = trunc(getBalance(root)/2)
    if balance then
        integer direction = HEIGHT-balance
        c = compare(getBalance(tree[root+direction]),0)
        if c=-balance then
            tree[root+direction] = rotate(tree[root+direction],direction)
        end if
        root = rotate(root,LEFT+RIGHT-direction)
    end if
    return root
end function

procedure inOrder(integer node)
    if node!=NULL then
        inOrder(tree[node+LEFT])
        printf(1, "%d ", tree[node+KEY])
        inOrder(tree[node+RIGHT])
    end if
end procedure

integer root = NULL
sequence test = shuffle(tagset(50003))
for i=1 to length(test) do
    root = insertNode(root,test[i])
end for
test = shuffle(tagset(50000))
for i=1 to length(test) do
    root = deleteNode(root,test[i])
end for
inOrder(root)


(defun rep (n x)
   (if (zp n)
       nil
       (cons x
             (rep (- n 1) x))))

(defun toggle-every-r (n i bs)
   (if (endp bs)
       nil
       (cons (if (zp i)
                 (not (first bs))
                 (first bs))
             (toggle-every-r n (mod (1- i) n) (rest bs)))))

(defun toggle-every (n bs)
   (toggle-every-r n (1- n) bs))

(defun 100-doors (i doors)
   (if (zp i)
       doors
       (100-doors (1- i) (toggle-every i doors))))


using Printf

analytical(n::Integer) = sum(factorial(n) / big(n) ^ i / factorial(n - i) for i = 1:n)

function test(n::Integer, times::Integer = 1000000)
    c = 0
    for i = range(0, times)
        x, bits = 1, 0
        while (bits & x) == 0
            c += 1
            bits |= x
            x = 1 << rand(0:(n - 1))
        end
    end
    return c / times
end

function main(n::Integer)
    println(" n\tavg\texp.\tdiff\n-------------------------------")
    for n in 1:n
        avg = test(n)
        theory = analytical(n)
        diff = (avg / theory - 1) * 100
        @printf(STDOUT, "%2d %8.4f %8.4f %6.3f%%\n", n, avg, theory, diff)
    end
end

main(20)


const val NMAX  = 20
const val TESTS = 1000000
val rand = java.util.Random()

fun avg(n: Int): Double {
    var sum = 0
    for (t in 0 until TESTS) {
        val v = BooleanArray(NMAX)
        var x = 0
        while (!v[x]) {
            v[x] = true
            sum++
            x = rand.nextInt(n)
        }
    }
    return sum.toDouble() / TESTS
}

fun ana(n: Int): Double {
    val nn = n.toDouble()
    var term = 1.0
    var sum = 1.0
    for (i in n - 1 downTo 1) {
        term *= i / nn
        sum += term
    }
    return sum
}

fun main(args: Array<String>) {
    println(" N    average    analytical    (error)")
    println("===  =========  ============  =========")
    for (n in 1..NMAX) {
        val a = avg(n)
        val b = ana(n)
        println(String.format("%3d   %6.4f   %10.4f      (%4.2f%%)", n, a, b, Math.abs(a - b) / b * 100.0))
    }
}


sieve = proc (max: int) returns (array[bool])
    prime: array[bool] := array[bool]$fill(1,max,true)
    prime[1] := false
    for p: int in int$from_to(2, max/2) do
        if prime[p] then
            for c: int in int$from_to_by(p*p, max, p) do
                prime[c] := false
            end
        end
    end
    return(prime)
end sieve

n_factors = proc (n: int, prime: array[bool]) returns (int)
    count: int := 0
    i: int := 2
    while i<=n do
        if prime[i] then
            while n//i=0 do
                count := count + 1
                n := n/i
            end
        end
        i := i + 1
    end
    return(count)
end n_factors

start_up = proc ()
    MAX = 120
    po: stream := stream$primary_output()
    prime: array[bool] := sieve(MAX)
    col: int := 0
    for i: int in int$from_to(2, MAX) do
        if prime[n_factors(i,prime)] then
            stream$putright(po, int$unparse(i), 4)
            col := col + 1
            if col//15 = 0 then stream$putl(po, "") end
        end
    end
end start_up


       IDENTIFICATION DIVISION.
       PROGRAM-ID. ATTRACTIVE-NUMBERS.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       77 MAXIMUM         PIC 999 VALUE 120.
       01 SIEVE-DATA      VALUE SPACES.
          03 MARKER       PIC X OCCURS 120 TIMES.
             88 PRIME     VALUE SPACE.
          03 SIEVE-MAX    PIC 999.
          03 COMPOSITE    PIC 999.
          03 CANDIDATE    PIC 999.

       01 FACTORIZE-DATA.
          03 FACTOR-NUM   PIC 999.
          03 FACTORS      PIC 999.
          03 FACTOR       PIC 999.
          03 QUOTIENT     PIC 999V999.
          03 FILLER       REDEFINES QUOTIENT.
             05 FILLER    PIC 999.
             05 DECIMAL   PIC 999.

       01 OUTPUT-FORMAT.
          03 OUT-NUM      PIC ZZZ9.
          03 OUT-LINE     PIC X(72) VALUE SPACES.
          03 COL-PTR      PIC 99 VALUE 1.

       PROCEDURE DIVISION.
       BEGIN.
           PERFORM SIEVE.
           PERFORM CHECK-ATTRACTIVE
               VARYING CANDIDATE FROM 2 BY 1
               UNTIL CANDIDATE IS GREATER THAN MAXIMUM.
           PERFORM WRITE-LINE.
           STOP RUN.

       CHECK-ATTRACTIVE.
           MOVE CANDIDATE TO FACTOR-NUM.
           PERFORM FACTORIZE.
           IF PRIME(FACTORS), PERFORM ADD-TO-OUTPUT.

       ADD-TO-OUTPUT.
           MOVE CANDIDATE TO OUT-NUM.
           STRING OUT-NUM DELIMITED BY SIZE INTO OUT-LINE
               WITH POINTER COL-PTR.
           IF COL-PTR IS EQUAL TO 73, PERFORM WRITE-LINE.

       WRITE-LINE.
           DISPLAY OUT-LINE.
           MOVE SPACES TO OUT-LINE.
           MOVE 1 TO COL-PTR.

       FACTORIZE SECTION.
       BEGIN.
           MOVE ZERO TO FACTORS.
           PERFORM DIVIDE-PRIME
               VARYING FACTOR FROM 2 BY 1
               UNTIL FACTOR IS GREATER THAN MAXIMUM.
           GO TO DONE.

       DIVIDE-PRIME.
           IF PRIME(FACTOR),
               DIVIDE FACTOR-NUM BY FACTOR GIVING QUOTIENT,
               IF DECIMAL IS EQUAL TO ZERO,
                   ADD 1 TO FACTORS,
                   MOVE QUOTIENT TO FACTOR-NUM,
                   GO TO DIVIDE-PRIME.
       DONE.
           EXIT.

       SIEVE SECTION.
       BEGIN.
           MOVE 'X' TO MARKER(1).
           DIVIDE MAXIMUM BY 2 GIVING SIEVE-MAX.
           PERFORM SET-COMPOSITES THRU SET-COMPOSITES-LOOP
               VARYING CANDIDATE FROM 2 BY 1
               UNTIL CANDIDATE IS GREATER THAN SIEVE-MAX.
           GO TO DONE.

       SET-COMPOSITES.
           MULTIPLY CANDIDATE BY 2 GIVING COMPOSITE.
       SET-COMPOSITES-LOOP.
           IF COMPOSITE IS NOT GREATER THAN MAXIMUM,
               MOVE 'X' TO MARKER(COMPOSITE),
               ADD CANDIDATE TO COMPOSITE,
               GO TO SET-COMPOSITES-LOOP.
       DONE.
           EXIT.


main =>
    T = nil,
    foreach (X in 1..10)
        T := insert(X,T)
    end,
    output(T,0).

insert(X, nil) = {1,nil,X,nil}.
insert(X, [email protected]{H,L,V,R}) = Res =>
    if X < V then
        Res = rotate({H, insert(X,L) ,V,R})
    elseif X > V then
        Res = rotate({H,L,V, insert(X,R)})
    else
        Res = T
    end.

rotate(nil) = nil.
rotate({H, {LH,LL,LV,LR}, V, R}) = Res,
    LH - height(R) > 1,
    height(LL) - height(LR) > 0
=>      % Left Left.
    Res = {LH,LL,LV, {depth(R,LR), LR,V,R}}.
rotate({H,L,V, {RH,RL,RV,RR}}) = Res,
    RH - height(L) > 1,
    height(RR) - height(RL) > 0
=>      % Right Right.
    Res = {RH, {depth(L,RL),L,V,RL}, RV,RR}.
rotate({H, {LH,LL,LV, {RH,RL,RV,RR}, V,R}}) = Res,
    LH - height(R) > 1
=>      % Left Right.
    Res = {H, {RH + 1, {LH - 1, LL, LV, RL}, RV, RR}, V, R}.
rotate({H,L,V, {RH, {LH,LL,LV,LR},RV,RR}}) = Res,
    RH - height(L) > 1
=>      % Right Left.
    Res = {H,L,V, {LH+1, LL, LV, {RH-1, LR, RV, RR}}}.
rotate({H,L,V,R}) = Res =>   % Re-weighting.
    L1 = rotate(L),
    R1 = rotate(R),
    Res = {depth(L1,R1), L1,V,R1}.

height(nil) = -1.
height({H,_,_,_}) = H.

depth(A,B) = max(height(A), height(B)) + 1.

output(nil,Indent) => printf("%*w\n",Indent,nil).
output({_,L,V,R},Indent) =>
    output(L,Indent+6),
    printf("%*w\n",Indent,V),
    output(R,Indent+6).


DEFINE COUNT="100"

PROC Main()
  BYTE ARRAY doors(COUNT+1)
  BYTE door,pass

  FOR door=1 TO COUNT
  DO
    doors(door)=0
  OD

  PrintE("Following doors are open:")
  FOR pass=1 TO COUNT
  DO
    FOR door=pass TO COUNT STEP pass
    DO
      doors(door)==!$FF
    OD
    IF doors(pass)=$FF THEN
      PrintB(pass) Put(32)
    FI
  OD
RETURN


MAXN = 20
TIMES = 10000'00

't0=time$("ms")
FOR n = 1 TO MAXN
    avg = FNtest(n, TIMES)
    theory = FNanalytical(n)
    diff = (avg / theory - 1) * 100
    PRINT n, avg, theory, using("##.####",diff); "%"
NEXT
't1=time$("ms")
'print t1-t0; " ms"
END

function FNanalytical(n)
    FOR i = 1 TO n
        s = s+ FNfactorial(n) / n^i / FNfactorial(n-i)
    NEXT
    FNanalytical = s
end function

function FNtest(n, times)
    FOR i = 1 TO times
        x = 1 : b = 0
        WHILE (b AND x) = 0
            c = c + 1
            b = b OR x
            x = 2^int(n*RND(1))
        WEND
    NEXT
    FNtest = c / times
end function

function FNfactorial(n)
    IF n=1 OR n=0 THEN FNfactorial=1 ELSE FNfactorial= n * FNfactorial(n-1)
end function


function average(n, reps)
  local count = 0
  for r = 1, reps do
    local f = {}
    for i = 1, n do f[i] = math.random(n) end
    local seen, x = {}, 1
    while not seen[x] do
      seen[x], x, count = true, f[x], count+1
    end
  end
  return count / reps
end

function analytical(n)
  local s, t = 1, 1
  for i = n-1, 1, -1 do t=t*i/n s=s+t end
  return s
end

print(" N    average    analytical    (error)")
print("===  =========  ============  =========")
for n = 1, 20 do
  local avg, ana = average(n, 1e6), analytical(n)
  local err = (avg-ana) / ana * 100
  print(string.format("%3d  %9.4f  %12.4f  (%6.3f%%)", n, avg, ana, err))
end


0010 FUNC factors#(n#) CLOSED
0020   count#:=0
0030   WHILE n# MOD 2=0 DO n#:=n# DIV 2;count#:+1
0040   fac#:=3
0050   WHILE fac#<=n# DO
0060     WHILE n# MOD fac#=0 DO n#:=n# DIV fac#;count#:+1
0070     fac#:+2
0080   ENDWHILE
0090   RETURN count#
0100 ENDFUNC factors#
0110 //
0120 ZONE 4
0130 seen#:=0
0140 FOR i#:=2 TO 120 DO
0150   IF factors#(factors#(i#))=1 THEN
0160     PRINT i#,
0170     seen#:+1
0180     IF seen# MOD 18=0 THEN PRINT
0190   ENDIF
0200 ENDFOR i#
0210 PRINT
0220 END


(defun attractivep (n)
  (primep (length (factors n))) )

; For primality testing we can use different methods, but since we have to define factors that's what we'll use
(defun primep (n)
  (= (length (factors n)) 1) )

(defun factors (n)
  "Return a list of factors of N."
  (when (> n 1)
    (loop with max-d = (isqrt n)
      for d = 2 then (if (evenp d) (+ d 1) (+ d 2)) do
      (cond ((> d max-d) (return (list n))) ; n is prime
        ((zerop (rem n d)) (return (cons d (factors (truncate n d)))))))))


include "cowgol.coh";
const MAXIMUM := 120;

typedef N is int(0, MAXIMUM + 1);
var prime: uint8[MAXIMUM + 1];

sub Sieve() is
    MemSet(&prime[0], 1, @bytesof prime);
    prime[0] := 0;
    prime[1] := 0;

    var cand: N := 2;
    while cand <= MAXIMUM >> 1 loop
        if prime[cand] != 0 then
            var comp := cand + cand;
            while comp <= MAXIMUM loop
                prime[comp] := 0;
                comp := comp + cand;
            end loop;
        end if;
        cand := cand + 1;
    end loop;
end sub;

sub Factors(n: N): (count: N) is
    count := 0;
    var p: N := 2;
    while p <= MAXIMUM loop
        if prime[p] != 0 then
            while n % p == 0 loop
                count := count + 1;
                n := n / p;
            end loop;
        end if;
        p := p + 1;
    end loop;
end sub;

sub Padding(n: N) is
    if n < 10 then print("   ");
    elseif n < 100 then print("  ");
    else print(" ");
    end if;
end sub;

var cand: N := 2;
var col: uint8 := 0;
Sieve();
while cand <= MAXIMUM loop
    if prime[Factors(cand)] != 0 then
        Padding(cand);
        print_i32(cand as uint32);
        col := col + 1;
        if col % 18 == 0 then
            print_nl();
        end if;
    end if;
    cand := cand + 1;
end loop;
print_nl();


# Module: calculus.py

import enum

class entry_not_found(Exception):
   """Raised when an entry is not found in a collection"""
   pass

class entry_already_exists(Exception):
   """Raised when an entry already exists in a collection"""
   pass

class state(enum.Enum):
   header = 0
   left_high = 1
   right_high = 2
   balanced = 3

class direction(enum.Enum):
   from_left = 0
   from_right = 1

from abc import ABC, abstractmethod

class comparer(ABC):

    @abstractmethod
    def compare(self,t):
        pass

class node(comparer):

    def __init__(self):
        self.parent = None
        self.left = self
        self.right = self
        self.balance = state.header

    def compare(self,t):
        if self.key < t:
             return -1
        elif t < self.key:
             return 1
        else:
             return 0

    def is_header(self):
        return self.balance == state.header

    def length(self):
        if self != None:
           if self.left != None:
              left = self.left.length()
           else:
              left = 0
           if self.right != None:
              right = self.right.length()
           else:
              right = 0

           return left + right + 1
        else:
           return 0

    def rotate_left(self):
         _parent = self.parent
         x = self.right
         self.parent = x
         x.parent = _parent
         if x.left is not None:
             x.left.parent = self
         self.right = x.left
         x.left = self
         return x

    def rotate_right(self):
        _parent = self.parent
        x = self.left
        self.parent = x
        x.parent = _parent;
        if x.right is not None:
            x.right.parent = self
        self.left = x.right
        x.right = self
        return x

    def balance_left(self):

       _left = self.left

       if _left is None:
          return self;

       if _left.balance == state.left_high:
                self.balance = state.balanced
                _left.balance = state.balanced
                self = self.rotate_right()
       elif _left.balance == state.right_high:
                subright = _left.right
                if subright.balance == state.balanced:
                        self.balance = state.balanced
                        _left.balance = state.balanced
                elif subright.balance == state.right_high:
                        self.balance = state.balanced
                        _left.balance = state.left_high
                elif subright.balance == left_high:
                        root.balance = state.right_high
                        _left.balance = state.balanced
                subright.balance = state.balanced
                _left = _left.rotate_left()
                self.left = _left
                self = self.rotate_right()
       elif _left.balance == state.balanced:
               self.balance = state.left_high
               _left.balance = state.right_high
               self = self.rotate_right()
       return self;

    def balance_right(self):

       _right = self.right

       if _right is None:
          return self;

       if _right.balance == state.right_high:
                self.balance = state.balanced
                _right.balance = state.balanced
                self = self.rotate_left()
       elif _right.balance == state.left_high:
                subleft = _right.left;
                if subleft.balance == state.balanced:
                        self.balance = state.balanced
                        _right.balance = state.balanced
                elif subleft.balance == state.left_high:
                        self.balance = state.balanced
                        _right.balance = state.right_high
                elif subleft.balance == state.right_high:
                        self.balance = state.left_high
                        _right.balance = state.balanced
                subleft.balance = state.balanced
                _right = _right.rotate_right()
                self.right = _right
                self = self.rotate_left()
       elif _right.balance == state.balanced:
                self.balance = state.right_high
                _right.balance = state.left_high
                self = self.rotate_left()
       return self

    def balance_tree(self, direct):
        taller = True
        while taller:
            _parent = self.parent;
            if _parent.left == self:
                next_from =  direction.from_left
            else:
                next_from = direction.from_right;

            if direct == direction.from_left:
                if self.balance == state.left_high:
                        if _parent.is_header():
                            _parent.parent = _parent.parent.balance_left()
                        elif _parent.left == self:
                            _parent.left = _parent.left.balance_left()
                        else:
                            _parent.right = _parent.right.balance_left()
                        taller = False

                elif self.balance == state.balanced:
                        self.balance = state.left_high
                        taller = True

                elif self.balance == state.right_high:
                        self.balance = state.balanced
                        taller = False
            else:
              if self.balance == state.left_high:
                        self.balance = state.balanced
                        taller = False

              elif self.balance ==  state.balanced:
                        self.balance = state.right_high
                        taller = True

              elif self.balance ==  state.right_high:
                        if _parent.is_header():
                            _parent.parent = _parent.parent.balance_right()
                        elif _parent.left == self:
                            _parent.left = _parent.left.balance_right()
                        else:
                            _parent.right = _parent.right.balance_right()
                        taller = False

            if taller:
                if _parent.is_header():
                    taller = False
                else:
                    self = _parent
                    direct = next_from

    def balance_tree_remove(self, _from):

        if self.is_header():
            return;

        shorter = True;

        while shorter:
            _parent = self.parent;
            if _parent.left == self:
                next_from = direction.from_left
            else:
                next_from = direction.from_right

            if _from == direction.from_left:
                if self.balance == state.left_high:
                        shorter = True

                elif self.balance == state.balanced:
                        self.balance = state.right_high;
                        shorter = False

                elif self.balance == state.right_high:
                        if self.right is not None:
                            if self.right.balance == state.balanced:
                                shorter = False
                            else:
                                shorter = True
                        else:
                            shorter = False;

                        if _parent.is_header():
                            _parent.parent = _parent.parent.balance_right()
                        elif _parent.left == self:
                            _parent.left = _parent.left.balance_right();
                        else:
                            _parent.right = _parent.right.balance_right()

            else:
                if self.balance == state.right_high:
                        self.balance = state.balanced
                        shorter = True

                elif self.balance == state.balanced:
                        self.balance = state.left_high
                        shorter = False

                elif self.balance == state.left_high:

                        if self.left is not None:
                            if self.left.balance == state.balanced:
                                shorter = False
                            else:
                                shorter = True
                        else:
                           short = False;

                        if _parent.is_header():
                            _parent.parent = _parent.parent.balance_left();
                        elif _parent.left == self:
                            _parent.left = _parent.left.balance_left();
                        else:
                            _parent.right = _parent.right.balance_left();

            if shorter:
               if _parent.is_header():
                    shorter = False
               else:
                    _from = next_from
                    self = _parent

    def previous(self):
        if self.is_header():
            return self.right

        if self.left is not None:
            y = self.left
            while y.right is not None:
                y = y.right
            return y

        else:
            y = self.parent;
            if y.is_header():
                return y

            x = self
            while x == y.left:
                x = y
                y = y.parent

            return y

    def next(self):
        if self.is_header():
            return self.left

        if self.right is not None:
            y = self.right
            while y.left is not None:
                y = y.left
            return y;

        else:
            y = self.parent
            if y.is_header():
                return y

            x = self;
            while x == y.right:
                x = y
                y = y.parent;

            return y

    def swap_nodes(a, b):

        if b == a.left:
            if b.left is not None:
                b.left.parent = a

            if b.right is not None:
                b.right.parent = a

            if a.right is not None:
                a.right.parent = b

            if not a.parent.is_header():
                if a.parent.left == a:
                    a.parent.left = b
                else:
                    a.parent.right = b;
            else:
                a.parent.parent = b

            b.parent = a.parent
            a.parent = b

            a.left = b.left
            b.left = a

            temp = a.right
            a.right = b.right
            b.right = temp
        elif b == a.right:
            if b.right is not None:
                b.right.parent = a

            if b.left is not None:
               b.left.parent = a

            if a.left is not None:
               a.left.parent = b

            if not a.parent.is_header():
                if a.parent.left == a:
                    a.parent.left = b
                else:
                    a.parent.right = b
            else:
               a.parent.parent = b

            b.parent = a.parent
            a.parent = b

            a.right = b.right
            b.right = a

            temp = a.left
            a.left = b.left
            b.left = temp
        elif a == b.left:
            if a.left is not None:
                a.left.parent = b

            if a.right is not None:
                a.right.parent = b

            if b.right is not None:
                b.right.parent = a

            if not parent.is_header():
                if b.parent.left == b:
                    b.parent.left = a
                else:
                    b.parent.right = a
            else:
                b.parent.parent = a

            a.parent = b.parent
            b.parent = a

            b.left = a.left
            a.left = b

            temp = a.right
            a.right = b.right
            b.right = temp
        elif a == b.right:
            if a.right is not None:
                a.right.parent = b
            if a.left is not None:
               a.left.parent = b

            if b.left is not None:
               b.left.parent = a

            if not b.parent.is_header():
                if b.parent.left == b:
                    b.parent.left = a
                else:
                    b.parent.right = a
            else:
                b.parent.parent = a

            a.parent = b.parent
            b.parent = a

            b.right = a.right
            a.right = b

            temp = a.left
            a.left = b.left
            b.left = temp
        else:
            if a.parent == b.parent:
                temp = a.parent.left
                a.parent.left = a.parent.right
                a.parent.right = temp
            else:
                if not a.parent.is_header():
                    if a.parent.left == a:
                        a.parent.left = b
                    else:
                        a.parent.right = b
                else:
                    a.parent.parent = b

                if not b.parent.is_header():
                    if b.parent.left == b:
                        b.parent.left = a
                    else:
                        b.parent.right = a
                else:
                    b.parent.parent = a

            if b.left is not None:
                b.left.parent = a

            if b.right is not None:
                b.right.parent = a

            if a.left is not None:
                a.left.parent = b

            if a.right is not None:
                a.right.parent = b

            temp1 = a.left
            a.left = b.left
            b.left = temp1

            temp2 = a.right
            a.right = b.right
            b.right = temp2

            temp3 = a.parent
            a.parent = b.parent
            b.parent = temp3

        balance = a.balance
        a.balance = b.balance
        b.balance = balance

class parent_node(node):

    def __init__(self, parent):
        self.parent = parent
        self.left = None
        self.right = None
        self.balance = state.balanced

class set_node(node):

    def __init__(self, parent, key):
        self.parent = parent
        self.left = None
        self.right = None
        self.balance = state.balanced
        self.key = key

class ordered_set:

    def __init__(self):
        self.header = node()

    def __iter__(self):
        self.node = self.header
        return self

    def __next__(self):
        self.node = self.node.next()
        if self.node.is_header():
            raise StopIteration
        return self.node.key

    def __delitem__(self, key):
          self.remove(key)

    def __lt__(self, other):
        first1 = self.header.left
        last1 = self.header
        first2 = other.header.left
        last2 = other.header

        while (first1 != last1) and (first2 != last2):
           l =  first1.key < first2.key
           if not l:
              first1 = first1.next();
              first2 = first2.next();
           else:
              return True;

        a = self.__len__()
        b = other.__len__()
        return a < b

    def __hash__(self):
        h = 0
        for i in self:
            h = h + i.__hash__()
        return h

    def __eq__(self, other):
       if self < other:
          return False
       if other < self:
          return False
       return True

    def __ne__(self, other):
       if self < other:
          return True
       if other < self:
          return True
       return False

    def __len__(self):
        return self.header.parent.length()

    def __getitem__(self, key):
          return self.contains(key)

    def __str__(self):
       l = self.header.right
       s = "{"
       i = self.header.left
       h = self.header
       while i != h:
           s = s + i.key.__str__()
           if i != l:
               s = s + ","
           i = i.next()

       s = s + "}"
       return s

    def __or__(self, other):
       r = ordered_set()

       first1 = self.header.left
       last1 = self.header
       first2 = other.header.left
       last2 = other.header

       while first1 != last1 and first2 != last2:
          les = first1.key < first2.key
          graater = first2.key < first1.key

          if les:
             r.add(first1.key)
             first1 = first1.next()
          elif graater:
             r.add(first2.key)
             first2 = first2.next()
          else:
             r.add(first1.key)
             first1 = first1.next()
             first2 = first2.next()

       while first1 != last1:
          r.add(first1.key)
          first1 = first1.next()

       while first2 != last2:
          r.add(first2.key)
          first2 = first2.next()

       return r

    def __and__(self, other):
       r = ordered_set()

       first1 = self.header.left
       last1 = self.header
       first2 = other.header.left
       last2 = other.header

       while first1 != last1 and first2 != last2:
          les = first1.key < first2.key
          graater = first2.key < first1.key

          if les:
             first1 = first1.next()
          elif graater:
             first2 = first2.next()
          else:
             r.add(first1.key)
             first1 = first1.next()
             first2 = first2.next()

       return r

    def __xor__(self, other):
       r = ordered_set()

       first1 = self.header.left
       last1 = self.header
       first2 = other.header.left
       last2 = other.header

       while first1 != last1 and first2 != last2:
          les = first1.key < first2.key
          graater = first2.key < first1.key

          if les:
             r.add(first1.key)
             first1 = first1.next()
          elif graater:
             r.add(first2.key)
             first2 = first2.next()
          else:
             first1 = first1.next()
             first2 = first2.next()

       while first1 != last1:
          r.add(first1.key)
          first1 = first1.next()

       while first2 != last2:
          r.add(first2.key)
          first2 = first2.next()

       return r

    def __sub__(self, other):
       r = ordered_set()

       first1 = self.header.left
       last1 = self.header
       first2 = other.header.left
       last2 = other.header

       while first1 != last1 and first2 != last2:
          les = first1.key < first2.key
          graater = first2.key < first1.key

          if les:
             r.add(first1.key)
             first1 = first1.next()
          elif graater:
             r.add(first2.key)
             first2 = first2.next()
          else:
             first1 = first1.next()
             first2 = first2.next()

       while first1 != last1:
          r.add(first1.key)
          first1 = first1.next()

       return r

    def __lshift__(self, data):
       self.add(data)
       return self

    def __rshift__(self, data):
       self.remove(data)
       return self

    def is_subset(self, other):
       first1 = self.header.left
       last1 = self.header
       first2 = other.header.left
       last2 = other.header

       is_subet = True

       while first1 != last1 and first2 != last2:
          if first1.key < first2.key:
              is_subset = False
              break
          elif first2.key < first1.key:
             first2 = first2.next()
          else:
             first1 = first1.next()
             first2 = first2.next()

          if is_subet:
             if first1 != last1:
                is_subet = False

       return is_subet

    def is_superset(self,other):
       return other.is_subset(self)

    def add(self, data):
            if self.header.parent is None:
                self.header.parent = set_node(self.header,data)
                self.header.left = self.header.parent
                self.header.right = self.header.parent
            else:

                root = self.header.parent

                while True:
                    c = root.compare(data)
                    if c >= 0:
                        if root.left is not None:
                            root = root.left
                        else:
                            new_node = set_node(root,data)
                            root.left = new_node

                            if self.header.left == root:
                                 self.header.left = new_node
                            root.balance_tree(direction.from_left)
                            return

                    else:
                        if root.right is not None:
                            root = root.right
                        else:
                            new_node = set_node(root, data)
                            root.right = new_node
                            if self.header.right == root:
                                  self.header.right = new_node
                            root.balance_tree(direction.from_right)
                            return

    def remove(self,data):
        root = self.header.parent;

        while True:
            if root is None:
                raise entry_not_found("Entry not found in collection")

            c  = root.compare(data)

            if c < 0:
               root = root.left;

            elif c > 0:
               root = root.right;

            else:

                 if root.left is not None:
                     if root.right is not None:
                         replace = root.left
                         while replace.right is not None:
                             replace = replace.right
                         root.swap_nodes(replace)

                 _parent = root.parent

                 if _parent.left == root:
                     _from = direction.from_left
                 else:
                     _from = direction.from_right

                 if self.header.left == root:

                     n = root.next();

                     if n.is_header():
                         self.header.left = self.header
                         self.header.right = self.header
                     else:
                        self.header.left = n
                 elif self.header.right == root:

                     p = root.previous();

                     if p.is_header():
                          self.header.left = self.header
                          self.header.right = self.header
                     else:
                          self.header.right = p

                 if root.left is None:
                     if _parent == self.header:
                         self.header.parent = root.right
                     elif _parent.left == root:
                         _parent.left = root.right
                     else:
                         _parent.right = root.right

                     if root.right is not None:
                          root.right.parent = _parent

                 else:
                     if _parent == self.header:
                          self.header.parent = root.left
                     elif _parent.left == root:
                         _parent.left = root.left
                     else:
                         _parent.right = root.left

                     if root.left is not None:
                         root.left.parent = _parent;

                 _parent.balance_tree_remove(_from)
                 return

    def contains(self,data):
        root = self.header.parent;

        while True:
            if root == None:
                return False

            c  = root.compare(data);

            if c > 0:
               root = root.left;

            elif c < 0:
               root = root.right;

            else:

                 return True

    def find(self,data):
        root = self.header.parent;

        while True:
            if root == None:
                raise entry_not_found("An entry is not found in a collection")

            c  = root.compare(data);

            if c > 0:
               root = root.left;

            elif c < 0:
               root = root.right;

            else:

                 return root.key;

class key_value(comparer):

    def __init__(self, key, value):
        self.key = key
        self.value = value

    def compare(self,kv):
        if self.key < kv.key:
             return -1
        elif kv.key < self.key:
             return 1
        else:
             return 0

    def __lt__(self, other):
        return self.key < other.key

    def __str__(self):
        return '(' + self.key.__str__() + ',' + self.value.__str__() + ')'

    def __eq__(self, other):
       return self.key == other.key

    def __hash__(self):
        return hash(self.key)

class dictionary:

    def __init__(self):
        self.set = ordered_set()
        return None

    def __lt__(self, other):
       if self.keys() < other.keys():
          return true

       if other.keys() < self.keys():
          return false

       first1 = self.set.header.left
       last1 = self.set.header
       first2 = other.set.header.left
       last2 = other.set.header

       while (first1 != last1) and (first2 != last2):
          l =  first1.key.value < first2.key.value
          if not l:
             first1 = first1.next();
             first2 = first2.next();
          else:
             return True;

       a = self.__len__()
       b = other.__len__()
       return a < b

    def add(self, key, value):
       try:
           self.set.remove(key_value(key,None))
       except entry_not_found:
            pass
       self.set.add(key_value(key,value))
       return

    def remove(self, key):
       self.set.remove(key_value(key,None))
       return

    def clear(self):
       self.set.header = node()

    def sort(self):

      sort_bag = bag()
      for e in self:
        sort_bag.add(e.value)
      keys_set = self.keys()
      self.clear()
      i = sort_bag.__iter__()
      i = sort_bag.__next__()
      try:
        for e in keys_set:
          self.add(e,i)
          i = sort_bag.__next__()
      except:
         return

    def keys(self):
         keys_set = ordered_set()
         for e in self:
             keys_set.add(e.key)
         return keys_set

    def __len__(self):
        return self.set.header.parent.length()

    def __str__(self):
       l = self.set.header.right;
       s = "{"
       i = self.set.header.left;
       h = self.set.header;
       while i != h:
           s = s + "("
           s = s + i.key.key.__str__()
           s = s + ","
           s = s + i.key.value.__str__()
           s = s + ")"
           if i != l:
               s = s + ","
           i = i.next()

       s = s + "}"
       return s;

    def __iter__(self):

        self.set.node = self.set.header
        return self

    def __next__(self):
        self.set.node = self.set.node.next()
        if self.set.node.is_header():
            raise StopIteration
        return key_value(self.set.node.key.key,self.set.node.key.value)

    def __getitem__(self, key):
          kv = self.set.find(key_value(key,None))
          return kv.value

    def __setitem__(self, key, value):
          self.add(key,value)
          return

    def __delitem__(self, key):
          self.set.remove(key_value(key,None))

class array:

    def __init__(self):
        self.dictionary = dictionary()
        return None

    def __len__(self):
        return self.dictionary.__len__()

    def push(self, value):
       k = self.dictionary.set.header.right
       if k == self.dictionary.set.header:
           self.dictionary.add(0,value)
       else:
           self.dictionary.add(k.key.key+1,value)
       return

    def pop(self):
       if self.dictionary.set.header.parent != None:
          data = self.dictionary.set.header.right.key.value
          self.remove(self.dictionary.set.header.right.key.key)
          return data

    def add(self, key, value):
       try:
          self.dictionary.remove(key)
       except entry_not_found:
          pass
       self.dictionary.add(key,value)
       return

    def remove(self, key):
       self.dictionary.remove(key)
       return

    def sort(self):
       self.dictionary.sort()

    def clear(self):
      self.dictionary.header = node();

    def __iter__(self):
        self.dictionary.node = self.dictionary.set.header
        return self

    def __next__(self):
        self.dictionary.node = self.dictionary.node.next()
        if self.dictionary.node.is_header():
            raise StopIteration
        return self.dictionary.node.key.value

    def __getitem__(self, key):
          kv = self.dictionary.set.find(key_value(key,None))
          return kv.value

    def __setitem__(self, key, value):
          self.add(key,value)
          return

    def __delitem__(self, key):
          self.dictionary.remove(key)

    def __lshift__(self, data):
         self.push(data)
         return self

    def __lt__(self, other):
       return self.dictionary < other.dictionary

    def __str__(self):
       l = self.dictionary.set.header.right;
       s = "{"
       i = self.dictionary.set.header.left;
       h = self.dictionary.set.header;
       while i != h:
           s = s + i.key.value.__str__()
           if i != l:
               s = s + ","
           i = i.next()

       s = s + "}"
       return s;

class bag:

    def __init__(self):
        self.header = node()

    def __iter__(self):
        self.node = self.header
        return self

    def __delitem__(self, key):
          self.remove(key)

    def __next__(self):
        self.node = self.node.next()
        if self.node.is_header():
            raise StopIteration
        return self.node.key

    def __str__(self):
       l = self.header.right;
       s = "("
       i = self.header.left;
       h = self.header;
       while i != h:
           s = s + i.key.__str__()
           if i != l:
               s = s + ","
           i = i.next()

       s = s + ")"
       return s;

    def __len__(self):
        return self.header.parent.length()

    def __lshift__(self, data):
       self.add(data)
       return self

    def add(self, data):
            if self.header.parent is None:
                self.header.parent = set_node(self.header,data)
                self.header.left = self.header.parent
                self.header.right = self.header.parent
            else:

                root = self.header.parent

                while True:
                    c = root.compare(data)
                    if c >= 0:
                        if root.left is not None:
                            root = root.left
                        else:
                            new_node = set_node(root,data)
                            root.left = new_node

                            if self.header.left == root:
                                 self.header.left = new_node

                            root.balance_tree(direction.from_left)
                            return

                    else:
                        if root.right is not None:
                            root = root.right
                        else:
                            new_node = set_node(root, data)
                            root.right = new_node

                            if self.header.right == root:
                                  self.header.right = new_node

                            root.balance_tree(direction.from_right)
                            return

    def remove_first(self,data):

        root = self.header.parent;

        while True:
            if root is None:
                return False;

            c  = root.compare(data);

            if c > 0:
               root = root.left;

            elif c < 0:
               root = root.right;

            else:

                 if root.left is not None:
                     if root.right is not None:
                         replace = root.left;
                         while replace.right is not None:
                             replace = replace.right;
                         root.swap_nodes(replace);

                 _parent = root.parent

                 if _parent.left == root:
                     _from = direction.from_left
                 else:
                     _from = direction.from_right

                 if self.header.left == root:

                     n = root.next();

                     if n.is_header():
                         self.header.left = self.header
                         self.header.right = self.header
                     else:
                        self.header.left = n;
                 elif self.header.right == root:

                     p = root.previous();

                     if p.is_header():
                          self.header.left = self.header
                          self.header.right = self.header
                     else:
                          self.header.right = p

                 if root.left is None:
                     if _parent == self.header:
                         self.header.parent = root.right
                     elif _parent.left == root:
                         _parent.left = root.right
                     else:
                         _parent.right = root.right

                     if root.right is not None:
                          root.right.parent = _parent

                 else:
                     if _parent == self.header:
                          self.header.parent = root.left
                     elif _parent.left == root:
                         _parent.left = root.left
                     else:
                         _parent.right = root.left

                     if root.left is not None:
                         root.left.parent = _parent;

                 _parent.balance_tree_remove(_from)
                 return True;

    def remove(self,data):
       success = self.remove_first(data)
       while success:
          success = self.remove_first(data)

    def remove_node(self, root):

        if root.left != None and root.right != None:
            replace = root.left
            while replace.right != None:
               replace = replace.right
            root.swap_nodes(replace)

        parent = root.parent;

        if parent.left == root:
           next_from = direction.from_left
        else:
           next_from = direction.from_right

        if self.header.left == root:
            n = root.next()

            if n.is_header():
                self.header.left = self.header;
                self.header.right = self.header
            else:
                self.header.left = n
        elif self.header.right == root:
             p = root.previous()

             if p.is_header():
                root.header.left = root.header
                root.header.right = header
             else:
                self.header.right = p

        if root.left == None:
            if parent == self.header:
                self.header.parent = root.right
            elif parent.left == root:
                parent.left = root.right
            else:
                parent.right = root.right

            if root.right != None:
               root.right.parent = parent
        else:
            if parent == self.header:
                self.header.parent = root.left
            elif parent.left == root:
                parent.left = root.left
            else:
                parent.right = root.left

            if root.left != None:
               root.left.parent = parent;

        parent.balance_tree_remove(next_from)

    def remove_at(self, data, ophset):

            p = self.search(data);

            if p == None:
                return
            else:
                lower = p
                after = after(data)

            s = 0
            while True:
                if ophset == s:
                    remove_node(lower);
                    return;
                lower = lower.next_node()
                if after == lower:
                   break
                s = s+1

            return

    def search(self, key):
        s = before(key)
        s.next()
        if s.is_header():
           return None
        c = s.compare(s.key)
        if c != 0:
           return None
        return s

    def before(self, data):
        y = self.header;
        x = self.header.parent;

        while x != None:
            if x.compare(data) >= 0:
                x = x.left;
            else:
                y = x;
                x = x.right;
        return y

    def after(self, data):
        y = self.header;
        x = self.header.parent;

        while x != None:
            if x.compare(data) > 0:
                y = x
                x = x.left
            else:
                x = x.right

        return y;

    def find(self,data):
        root = self.header.parent;

        results = array()

        while True:
            if root is None:
                break;

            p = self.before(data)
            p = p.next()
            if not p.is_header():
               i = p
               l = self.after(data)
               while i != l:
                  results.push(i.key)
                  i = i.next()

               return results
            else:
               break;

        return results

class bag_dictionary:

    def __init__(self):
        self.bag = bag()
        return None

    def add(self, key, value):
       self.bag.add(key_value(key,value))
       return

    def remove(self, key):
       self.bag.remove(key_value(key,None))
       return

    def remove_at(self, key, index):
       self.bag.remove_at(key_value(key,None), index)
       return

    def clear(self):
       self.bag.header = node()

    def __len__(self):
        return self.bag.header.parent.length()

    def __str__(self):
       l = self.bag.header.right;
       s = "{"
       i = self.bag.header.left;
       h = self.bag.header;
       while i != h:
           s = s + "("
           s = s + i.key.key.__str__()
           s = s + ","
           s = s + i.key.value.__str__()
           s = s + ")"
           if i != l:
               s = s + ","
           i = i.next()

       s = s + "}"
       return s;

    def __iter__(self):

        self.bag.node = self.bag.header
        return self

    def __next__(self):
        self.bag.node = self.bag.node.next()
        if self.bag.node.is_header():
            raise StopIteration
        return key_value(self.bag.node.key.key,self.bag.node.key.value)

    def __getitem__(self, key):
          kv_array = self.bag.find(key_value(key,None))
          return kv_array

    def __setitem__(self, key, value):
          self.add(key,value)
          return

    def __delitem__(self, key):
          self.bag.remove(key_value(key,None))

class unordered_set:

    def __init__(self):
        self.bag_dictionary = bag_dictionary()

    def __len__(self):
        return self.bag_dictionary.__len__()

    def __hash__(self):
        h = 0
        for i in self:
            h = h + i.__hash__()
        return h

    def __eq__(self, other):
        for t in self:
           if not other.contains(t):
              return False
        for u in other:
           if self.contains(u):
              return False
        return true;

    def __ne__(self, other):
        return not self == other

    def __or__(self, other):
       r = unordered_set()

       for t in self:
          r.add(t);

       for u in other:
          if not self.contains(u):
             r.add(u);

       return r

    def __and__(self, other):
       r = unordered_set()

       for t in self:
          if other.contains(t):
              r.add(t)

       for u in other:
              if self.contains(u) and not r.contains(u):
                  r.add(u);

       return r

    def __xor__(self, other):
       r = unordered_set()

       for t in self:
          if not other.contains(t):
             r.add(t)

       for u in other:
          if not self.contains(u) and not r.contains(u):
             r.add(u)

       return r

    def __sub__(self, other):
       r = ordered_set()

       for t in self:
          if not other.contains(t):
             r.add(t);

       return r

    def __lshift__(self, data):
       self.add(data)
       return self

    def __rshift__(self, data):
       self.remove(data)
       return self

    def __getitem__(self, key):
          return self.contains(key)

    def is_subset(self, other):

       is_subet = True

       for t in self:
          if not other.contains(t):
             subset = False
             break

       return is_subet

    def is_superset(self,other):
       return other.is_subset(self)

    def add(self, value):
       if not self.contains(value):
           self.bag_dictionary.add(hash(value),value)
       else:
          raise entry_already_exists("Entry already exists in the unordered set")

    def contains(self, data):
            if self.bag_dictionary.bag.header.parent == None:
                return False;
            else:
                index = hash(data);

                _search = self.bag_dictionary.bag.header.parent;

                search_index =  _search.key.key;

                if index < search_index:
                   _search = _search.left

                elif index > search_index:
                   _search = _search.right

                if _search == None:
                    return False

                while _search != None:
                    search_index =  _search.key.key;

                    if index < search_index:
                       _search = _search.left

                    elif index > search_index:
                       _search = _search.right

                    else:
                       break

                if _search == None:
                   return False

                return self.contains_node(data, _search)

    def contains_node(self,data,_node):

        previous = _node.previous()
        save = _node

        while not previous.is_header() and previous.key.key == _node.key.key:
            save = previous;
            previous = previous.previous()

        c = _node.key.value
        _node = save
        if c == data:
           return True

        next = _node.next()
        while not next.is_header() and next.key.key == _node.key.key:
            _node = next
            c = _node.key.value
            if c == data:
               return True;
            next = _node.next()

        return False;

    def find(self,data,_node):

        previous = _node.previous()
        save = _node

        while not previous.is_header() and previous.key.key == _node.key.key:
            save = previous;
            previous = previous.previous();

        _node = save;
        c = _node.key.value
        if c == data:
           return _node

        next = _node.next()
        while not next.is_header() and next.key.key == _node.key.key:
            _node = next
            c = _node.data.value
            if c == data:
               return _node
            next = _node.next()

        return None

    def search(self, data):
        if self.bag_dictionary.bag.header.parent == None:
            return None
        else:
            index = hash(data)

            _search = self.bag_dictionary.bag.header.parent

            c = _search.key.key

            if index < c:
               _search = _search.left;

            elif index > c:
               _search = _search.right;

            while _search != None:

                if index != c:
                   break

                c = _search.key.key

                if index < c:
                   _search = _search.left;

                elif index > c:
                   _search = _search.right;

                else:
                   break

            if _search == None:
               return None

            return self.find(data, _search)

    def remove(self,data):
       found = self.search(data);
       if found != None:
          self.bag_dictionary.bag.remove_node(found);
       else:
          raise entry_not_found("Entry not found in the unordered set")

    def clear(self):
       self.bag_dictionary.bag.header = node()

    def __str__(self):
       l = self.bag_dictionary.bag.header.right;
       s = "{"
       i = self.bag_dictionary.bag.header.left;
       h = self.bag_dictionary.bag.header;
       while i != h:
           s = s + i.key.value.__str__()
           if i != l:
               s = s + ","
           i = i.next()

       s = s + "}"
       return s;

    def __iter__(self):

        self.bag_dictionary.bag.node = self.bag_dictionary.bag.header
        return self

    def __next__(self):
        self.bag_dictionary.bag.node = self.bag_dictionary.bag.node.next()
        if self.bag_dictionary.bag.node.is_header():
            raise StopIteration
        return self.bag_dictionary.bag.node.key.value

class map:

    def __init__(self):
        self.set = unordered_set()
        return None

    def __len__(self):
        return self.set.__len__()

    def add(self, key, value):
       try:
           self.set.remove(key_value(key,None))
       except entry_not_found:
            pass
       self.set.add(key_value(key,value))
       return

    def remove(self, key):
       self.set.remove(key_value(key,None))
       return

    def clear(self):
       self.set.clear()

    def __str__(self):
       l = self.set.bag_dictionary.bag.header.right;
       s = "{"
       i = self.set.bag_dictionary.bag.header.left;
       h = self.set.bag_dictionary.bag.header;
       while i != h:
           s = s + "("
           s = s + i.key.value.key.__str__()
           s = s + ","
           s = s + i.key.value.value.__str__()
           s = s + ")"
           if i != l:
               s = s + ","
           i = i.next()

       s = s + "}"
       return s;

    def __iter__(self):

        self.set.node = self.set.bag_dictionary.bag.header
        return self

    def __next__(self):
        self.set.node = self.set.node.next()
        if self.set.node.is_header():
            raise StopIteration
        return key_value(self.set.node.key.key,self.set.node.key.value)

    def __getitem__(self, key):
          kv = self.set.find(key_value(key,None))
          return kv.value

    def __setitem__(self, key, value):
          self.add(key,value)
          return

    def __delitem__(self, key):
          self.remove(key)


package {
    import flash.display.Sprite;

    public class Doors extends Sprite {
        public function Doors() {

            // Initialize the array
            var doors:Array = new Array(100);
            for (var i:Number = 0; i < 100; i++) {
                doors[i] = false;

            // Do the work
            for (var pass:Number = 0; pass < 100; pass++) {
                for (var j:Number = pass; j < 100; j += (pass+1)) {
                    doors[j] = !doors[j];
                }
            }
            trace(doors);
        }
    }
}


import random, math, strformat
randomize()

const
  maxN = 20
  times = 1_000_000

proc factorial(n: int): float =
  result = 1
  for i in 1 .. n:
    result *= i.float

proc expected(n: int): float =
  for i in 1 .. n:
    result += factorial(n) / pow(n.float, i.float) / factorial(n - i)

proc test(n, times: int): int =
  for i in 1 .. times:
    var
      x = 1
      bits = 0
    while (bits and x) == 0:
      inc result
      bits = bits or x
      x = 1 shl rand(n - 1)

echo " n\tavg\texp.\tdiff"
echo "-------------------------------"
for n in 1 .. maxN:
  let cnt = test(n, times)
  let avg = cnt.float / times
  let theory = expected(n)
  let diff = (avg / theory - 1) * 100
  echo fmt"{n:2} {avg:8.4f} {theory:8.4f} {diff:6.3f}%"


MODULE AvgLoopLen;
(* Oxford Oberon-2 *)
IMPORT Random, Out;

PROCEDURE Fac(n: INTEGER; f: REAL): REAL;
BEGIN
	IF n = 0 THEN
		RETURN f
	ELSE
		RETURN Fac(n - 1,n*f)
	END
END Fac;

PROCEDURE Power(n,i: INTEGER): REAL;
VAR
	p: REAL;
BEGIN
	p := 1.0;
	WHILE i > 0 DO p := p * n; DEC(i) END;
	RETURN p
END Power;

PROCEDURE Abs(x: REAL): REAL;
BEGIN
	IF x < 0 THEN RETURN -x ELSE RETURN x END
END Abs;

PROCEDURE Analytical(n: INTEGER): REAL;
VAR
	i: INTEGER;
	res: REAL;
BEGIN
	res := 0.0;
	FOR i := 1 TO n DO
		res := res + (Fac(n,1.0) / Power(n,i) / Fac(n - i,1.0));
	END;
	RETURN res
END Analytical;

PROCEDURE Averages(n: INTEGER): REAL;
CONST
	times = 100000;
VAR
	rnds: SET;
	r,count,i: INTEGER;
BEGIN
	count := 0; i := 0;
	WHILE i < times DO
		rnds := {};
		LOOP
			r := Random.Roll(n);
			IF r IN rnds THEN EXIT ELSE INCL(rnds,r); INC(count) END
		END;
		INC(i)
	END;

	RETURN count / times
END Averages;

VAR
	i: INTEGER;
	av,an,df: REAL;
BEGIN
	Random.Randomize;
	Out.String("        Averages  Analytical  Diff%     ");Out.Ln;
	FOR i := 1 TO 20 DO
		Out.Int(i,3); Out.String(": ");
		av := Averages(i);an := Analytical(i);df := Abs(av - an) / an * 100.0;
		Out.Fixed(av,10,4);Out.Fixed(an,11,4);Out.Fixed(df,10,4);Out.Ln
	END
END AvgLoopLen.


import std.stdio;

enum MAX = 120;

bool isPrime(int n) {
    if (n < 2) return false;
    if (n % 2 == 0) return n == 2;
    if (n % 3 == 0) return n == 3;
    int d = 5;
    while (d * d <= n) {
        if (n % d == 0) return false;
        d += 2;
        if (n % d == 0) return false;
        d += 4;
    }
    return true;
}

int primeFactorCount(int n) {
    if (n == 1) return 0;
    if (isPrime(n)) return 1;
    int count;
    int f = 2;
    while (true) {
        if (n % f == 0) {
            count++;
            n /= f;
            if (n == 1) return count;
            if (isPrime(n)) f = n;
        } else if (f >= 3) {
            f += 2;
        } else {
            f = 3;
        }
    }
}

void main() {
    writeln("The attractive numbers up to and including ", MAX, " are:");
    int i = 1;
    int count;
    while (i <= MAX) {
        int n = primeFactorCount(i);
        if (isPrime(n)) {
            writef("%4d", i);
            if (++count % 20 == 0) writeln;
        }
        ++i;
    }
    writeln;
}


/* Sieve of Eratosthenes */
proc nonrec sieve([*] bool prime) void:
    word p, c, max;
    max := (dim(prime,1)-1)>>1;
    prime[0] := false;
    prime[1] := false;
    for p from 2 upto max do prime[p] := true od;
    for p from 2 upto max>>1 do
        if prime[p] then
            for c from p*2 by p upto max do
                prime[c] := false
            od
        fi
    od
corp

/* Count the prime factors of a number */
proc nonrec n_factors(word n; [*] bool prime) word:
    word count, fac;
    fac := 2;
    count := 0;
    while fac <= n do
        if prime[fac] then
            while n % fac = 0 do
                count := count + 1;
                n := n / fac
            od
        fi;
        fac := fac + 1
    od;
    count
corp

/* Find attractive numbers <= 120 */
proc nonrec main() void:
    word MAX = 120;
    [MAX+1] bool prime;
    unsigned MAX i;
    byte col;
    sieve(prime);
    col := 0;
    for i from 2 upto MAX do
        if prime[n_factors(i, prime)] then
            write(i:4);
            col := col + 1;
            if col % 18 = 0 then writeln() fi
        fi
    od
corp