SetWorkingDir %A_ScriptDir%
#NoEnv
Data := "12  127 28  42  39  113 42  18  44  118 44  37  113 124 37  48  127 36  29  31  125 139 131 115 105 132 104 123 35  113 122 42  117 119 58  109 23  105 63  27  44  105 99  41  128 121 116 125 32  61  37  127 29  113 121 58  114 126 53  114 96  25  109 7   31  141 46  13  27  43  117 116 27  7   68  40  31  115 124 42  128 52  71  118 117 38  27  106 33  117 116 111 40  119 47  105 57  122 109 124 115 43  120 43  27  27  18  28  48  125 107 114 34  133 45  120 30  127 31  116  146"
 ; This loop removes the double/multiple spaces encountered when copying+pasting the given data set:
While (Instr(Data,"  "))
    StringReplace, Data, Data,%A_Space%%A_Space%,%A_Space%,All
; Sort the data numerically using a space as the separator:
Sort, Data,ND%A_Space%

OldStem := 0
; Parse the data using a space as the separator, storing each new string as A_LoopField and running the loop once per string:
Loop, parse, Data,%A_Space%
{
    NewStem := SubStr(A_LoopField,1,StrLen(A_LoopField)-1)     ; AutoHotkey doesn't have a Left() function, so this does the trick.
    If ( NewStem <> OldStem  and StrLen(A_LoopField) <> 1)
    {
        While(OldStem+1<>NewStem)                              ; account for all stems which don't appear (in this example, 8) but are between the lowest and highest stems
            OldStem++,ToPrint .= "`n" PadStem(oldStem)
        ToPrint .= "`n" PadStem(NewStem)
        OldStem := NewStem
    }
    Else If ( StrLen(A_LoopField)=1 and !FirstStem)
        ToPrint .= PadStem(0),FirstStem := true
    ToPrint .= SubStr(A_LoopField,strLen(A_LoopField)) " "    ; No Right() function either, so this returns the last character of A_LoopField (the string curently used by the parsing loop)
}
                                                              ; Delete the old stem and leaf file (if any), write our new contents to it, then show it:
FileDelete Stem and leaf.txt
FileAppend %ToPrint%, Stem and Leaf.txt
Run Stem and leaf.txt
return

PadStem(Stem){
    Spaces = 0
    While ( 3 - StrLen(Stem) <> Spaces )                     ; If the stems are more than 2 digits long, increase the number 3 to one more than the stem length.
        ToReturn .= " ",Spaces++
    ToReturn .= Stem
    ToReturn .= " | "
    Return ToReturn
}


(off "Stack")

(de $$ "Prg"
   (let "Stack" (cons (cons (car "Prg") (env)) "Stack")  # Build stack frame
      (set "Stack"
         (delq (asoq '"Stack" (car "Stack"))  # Remove self-created entries
            (delq (asoq '"Prg" (car "Stack"))
               (car "Stack") ) ) )
      (run (cdr "Prg")) ) )  # Run body

(de stackAll (Excl)
   (let *Dbg NIL
      (for "X" (all)
         (or
            (memq "X" Excl)
            (memq "X" '($$ @ @@ @@@))
            (= `(char "*") (char "X"))
            (cond
               ((= `(char "+") (char "X"))
                  (for "Y" (pair (val "X"))
                     (and
                        (pair "Y")
                        (fun? (cdr "Y"))
                        (unless (== '$$ (caaddr "Y"))
                           (con (cdr "Y")
                              (list
                                 (cons '$$ (cons (car "Y" "X") (cddr "Y"))) ) ) ) ) ) )
               ((pair (getd "X"))
                  (let "Y" @
                     (unless (== '$$ (caadr "Y"))
                        (con "Y"
                           (list (cons '$$ "X" (cdr "Y"))) ) ) ) ) ) ) ) ) )

(de dumpStack ()
   (more (reverse (cdr "Stack")))
   T )


/* The SNAP option in the ON statement is sufficient to obtain */
/* a traceback.  The SYSTEM option specifies that standard     */
/* system action is to occur, which resume execution after the */
/* SIGNAL statement.                                           */
on condition(traceback) snap system;
...
signal condition(traceback);


Procedure Three()
  a=7
  ShowCallstack()
  CallDebugger
EndProcedure

Procedure Two()
  a=4
  Three()
EndProcedure

Procedure One()
  a=2
  Two()
EndProcedure

One()


import traceback

def f(): return g()
def g(): traceback.print_stack()

f()


 > quackery

Welcome to Quackery.

Enter "leave" to leave the shell.

Building extensions.

/O>   echoreturn
...
{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 0}
Stack empty.

/O>   [ cr echoreturn
...     cr echostack
...     dup 2 < if done
...     dup 1 - swap 2 -
...     recurse swap recurse + ] is fib
...

Stack empty.

/O>   5 fib echo
...

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 1}
Stack: 5

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 1}
Stack: 4 3

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 4 2 1

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 4 1 2

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 4 1 1 0

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 4 1 0 1

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 4

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 3 2

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 3 1 0

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 3 0 1

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 1 3

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 1 2 1

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 1 1 2

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 15} {recurse 1} {fib 1}
Stack: 2 1 1 1 0

{[...] 0} {quackery 1} {[...] 11} {shell 5} {quackery 1} {[...] 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 17} {recurse 1} {fib 1}
Stack: 2 1 1 0 1
5
Stack empty.

/O>


foo <- function()
{
   bar <- function()
   {
     sys.calls()
   }
   bar()
}

foo()


#lang racket

;; To see these calls we do two things: mutate the binding to prevent
;; Racket from inlining the value; use a (void) call at the end so the
;; calls are not tail calls (which will otherwise not show on the
;; stack).
(define foo #f)
(set! foo (λ() (bar) (void)))
(define bar #f)
(set! bar (λ() (show-stacktrace) (void)))

(define (show-stacktrace)
  (for ([s (continuation-mark-set->context (current-continuation-marks))]
        [i (in-naturals)])
    ;; show just the names, not the full source information
    (when (car s) (printf "~s: ~s\n" i (car s)))))
(foo)


(define (step-up n-steps)
  (cond ((zero? n-steps) 'done)
        ((step) (step-up (- n-steps 1)))
        (else (step-up (+ n-steps 1)))))


const proc: step_up is func
  begin
    while not doStep do
      step_up;
    end while;
  end func;


func step_up() {
    while (!step()) {
        step_up();
    }
}


Smalltalk at: #stepUp put: 0.
stepUp := [ [ step value ] whileFalse: [ stepUp value ] ].


(*
 * val step : unit -> bool
 * This is a stub for a function which returns true if successfully climb a step or false otherwise.
 *)
fun step() = true

(*
 * val step_up : unit -> bool
 *)
fun step_up() = step() orelse (step_up() andalso step_up())


func step_up() {
  while !step() {
    step_up()
  }
}


set level 41
set prob 0.5001
proc step {} {
    global level prob steps
    incr steps
    if {rand() < $prob} {
	incr level 1
	return 1
    } else {
	incr level -1
	return 0
    }
}


sub g { say Backtrace.new.concise }
sub f { g }
sub MAIN { f }


/* call stack */
say 'Call A'
call A '123'
say result
exit 0

A:
say 'Call B'
call B '456'
say result
return ARG(1)

B:
say 'Call C'
call C '789'
say result
return ARG(1)

C:
call callstack
return ARG(1)

callstack: procedure
getcallstack(cs.)
say 'Dump call stack with' cs.0 'items'
do i = 1 to cs.0
    parse var cs.i line func
    say format(line, 3) ':' left(func, 9) ': source "' || sourceline(line) || '"'
end
return cs.0


def outer(a,b,c)
  middle a+b, b+c
end

def middle(d,e)
  inner d+e
end

def inner(f)
  puts caller(0)
  puts "continuing... my arg is #{f}"
end

outer 2,3,5


def callStack = try { error("exception") } catch { case ex => ex.getStackTrace drop 2 }

def printStackTrace = callStack drop 1 /* don't print ourselves! */ foreach println


If rand>.5:Then
0→C
Disp "FALL"
If A=1:Then
D-1→D
Disp D
End
Else
1→C
Disp "CLIMB"
If A=1:Then
D+1→D
Disp D
End
End
If B=1
Pause


import "random" for Random
import "/fmt" for Conv

var rand = Random.new(1268) // generates short repeatable sequence
var position = 0

var step = Fn.new {
    var r = Conv.itob(rand.int(2))
    if (r) {
        position = position + 1
        System.print("Climbed up to %(position)")
    } else {
        position = position - 1
        System.print("Fell down to %(position)")
    }
    return r
}

var stepUp // recursive
stepUp = Fn.new {
    while (!step.call()) stepUp.call()
}

stepUp.call()


proc Step_up;           \Iterative version
int I;
[I:= 0;
while I<1 do
        if Step then I:= I+1
        else I:= I-1;
];

proc Step_up;           \Recursive version
while not Step do Step_up;


fcn step{  } // add code to return Bool
fcn stepUp{ while(not step()){ self.fcn() } }


slate[1]> [email protected](Debugger traits) printCurrentStack &limit: limit &stream: out &showLocation: showLocation
[
  d clone `>> [baseFramePointer: (d interpreter framePointerOf: #printCurrentStack).
               buildFrames.
               printBacktrace &limit: limit &stream: out &showLocation: showLocation ]
].
Defining function 'printCurrentStack' on: 'Debugger traits'
[printCurrentStack &limit: &stream: &showLocation:]


Object subclass: Container [
   Container class >> outer: a and: b and: c [
     self middle: (a+b) and: (b+c)
   ]
   Container class >> middle: x and: y [
     self inner: (x*y)
   ]
   Container class >> inner: k [
     Smalltalk backtrace
   ]
].

Container outer: 2 and: 3 and: 5.

'Anyway, we continue with it' displayNl.


proc printStackTrace {} {
    puts "Stack trace:"
    for {set i 1} {$i < [info level]} {incr i} {
        puts [string repeat "  " $i][info level $i]
    }
}


var func2 = Fn.new {
    Fiber.abort("Forced error.")
}

var func1 = Fn.new {
    func2.call()
}

func1.call()


fcn f{println("F");vm.stackTrace().println()} fcn g{println("G")}
f();g();


(def data
  [12 127 28 42 39 113 42 18 44 118 44 37 113 124 37 48 127 36 29 31 125
   139 131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27
   44 105 99 41 128 121 116 125 32 61 37 127 29 113 121 58 114 126 53 114
   96 25 109 7 31 141 46 13 27 43 117 116 27 7 68 40 31 115 124 42 128 146
   52 71 118 117 38 27 106 33 117 116 111 40 119 47 105 57 122 109 124
   115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116])

(defn calc-stem [number]
  (int (Math/floor (/ number 10))))

(defn calc-leaf [number]
  (mod number 10))

(defn new-plant
  "Returns a leafless plant, with `size` empty branches,
  i.e. a hash-map with integer keys (from 0 to `size` inclusive)
  mapped to empty vectors.

  (new-plant 2) ;=> {0 [] 1 [] 2 []}"
  [size]
  (let [end (inc size)]
    (->> (repeat end [])
         (interleave (range end))
         (apply hash-map))))

(defn sprout-leaves
  [plant [stem leaf]]
  (update plant stem conj leaf))

(defn stem-and-leaf [numbers]
  (let [max-stem   (calc-stem (reduce max numbers))
        baby-plant (new-plant max-stem)
        plant      (->> (map (juxt calc-stem calc-leaf) numbers)
                        (reduce sprout-leaves baby-plant)
                        (sort))]
    (doseq [[stem leaves] plant]
      (print   (format (str "%2s") stem))
      (print   " | ")
      (println (clojure.string/join " " (sort leaves))))))

(stem-and-leaf data)


      SUBROUTINE COMBSORT(A,N)
       INTEGER A(*)	!The array.
       INTEGER N	!The count.
       INTEGER H,T	!Assistants.
       LOGICAL CURSE
        H = N - 1		!Last - First, and not +1.
    1   H = MAX(1,H*10/13)	!The special feature.
        IF (H.EQ.9 .OR. H.EQ.10) H = 11	!A twiddle.
        CURSE = .FALSE.		!So far, so good.
        DO I = N - H,1,-1	!If H = 1, this is a BubbleSort.
          IF (A(I) .GT. A(I + H)) THEN	!One compare.
            T=A(I); A(I)=A(I+H); A(I+H)=T	!One swap.
            CURSE = .TRUE.			!One curse.
          END IF			!One test.
        END DO			!One loop.
        IF (CURSE .OR. H.GT.1) GO TO 1	!Work remains?
      END SUBROUTINE COMBSORT	!Good performance, small code.

      SUBROUTINE TOPIARY(A,N)	!Produces a "stem&leaf" display for the integers in A, damaging A.
       INTEGER A(*)		!An array of integers.
       INTEGER N		!Their number.
       INTEGER CLIP		!Semi-generalisation.
       PARAMETER (CLIP = 10)	!Or at least, annotation.
       INTEGER I1,I2,STEM	!Assistants.
        CALL COMBSORT(A,N)	!Rearrange the array!
        STEM = A(1)/CLIP	!The first stem value.
        I1 = 1			!The first stem's span starts here.
        I2 = I1			!And so far as I know, ends here.
   10   I2 = I2 + 1			!Probe ahead one position.
        IF (I2 .GT. N) GO TO 11		!Off the end? Don't look!
        IF (A(I2)/CLIP .EQ.STEM) GO TO 10	!Still in the same stem? Probe on.
Cast forth a STEM line, corresponding to elements I1:I2 - 1.
   11   WRITE (6,12) STEM,ABS(MOD(A(I1:I2 - 1),CLIP))	!ABS: MOD with negatives can be unexpected.
   12   FORMAT (I4,"|",(100I1))		!Layout. If more than a hundred, starts a new line.
        IF (I2 .GT. N) RETURN		!Are we there yet?
        I1 = I2				!No. This is my new span's start.
Chug along to the next STEM value.
   13   STEM = STEM + 1			!Advance to the next stem.
        IF (A(I2)/CLIP.GT.STEM) GO TO 11!Has the stem reached the impending value?
        GO TO 10			!Yes. Scan its span.
      END SUBROUTINE TOPIARY	!The days of carefully-arranged output.

      PROGRAM TEST
      INTEGER VALUES(121)	!The exact number of values.
      DATA VALUES/		!As in the specified example.
     o  12,127, 28, 42, 39,113, 42, 18, 44,118,	!A regular array
     1  44, 37,113,124, 37, 48,127, 36, 29, 31,	!Makes counting easier.
     2 125,139,131,115,105,132,104,123, 35,113,
     3 122, 42,117,119, 58,109, 23,105, 63, 27,
     4  44,105, 99, 41,128,121,116,125, 32, 61,
     5  37,127, 29,113,121, 58,114,126, 53,114,
     6  96, 25,109,  7, 31,141, 46, 13, 27, 43,
     7 117,116, 27,  7, 68, 40, 31,115,124, 42,
     8 128, 52, 71,118,117, 38, 27,106, 33,117,
     9 116,111, 40,119, 47,105, 57,122,109,124,
     o 115, 43,120, 43, 27, 27, 18, 28, 48,125,
     1 107,114, 34,133, 45,120, 30,127, 31,116,
     2 146/
        CALL TOPIARY(VALUES,121)
      END


' version 22-06-2015
' compile with: fbc -s console
' for boundry checks on array's compile with: fbc -s console -exx
' from the rosetta code FreeBASIC entry
#Define out_of_data 99999999 ' any number that is not in the set will do

Sub shellsort(s() As Integer)
    ' from the FreeBASIC entry at rosetta code
    ' sort from lower bound to the highter bound
    Dim As Integer lb = LBound(s)
    Dim As Integer ub = UBound(s)
    Dim As Integer done, i, inc = ub - lb

    Do
        inc = inc / 2.2
        If inc < 1 Then inc = 1
        Do
            done = 0
            For i = lb To ub - inc
                If s(i) > s(i + inc) Then
                    Swap s(i), s(i + inc)
                    done = 1
                End If
            Next
        Loop Until done = 0
    Loop Until inc = 1

End Sub

' ------=< TASK DATA >=------

Data  12, 127,  28,  42,  39, 113,  42,  18,  44, 118,  44,  37, 113, 124
Data  37,  48, 127,  36,  29,  31, 125, 139, 131, 115, 105, 132, 104, 123
Data  35, 113, 122,  42, 117, 119,  58, 109,  23, 105,  63,  27,  44, 105
Data  99,  41, 128, 121, 116, 125,  32,  61,  37, 127,  29, 113, 121,  58
Data 114, 126,  53, 114,  96,  25, 109,   7,  31, 141,  46,  13,  27,  43
Data 117, 116,  27,   7,  68,  40,  31, 115, 124,  42, 128,  52,  71, 118
Data 117,  38,  27, 106,  33, 117, 116, 111,  40, 119,  47, 105,  57, 122
Data 109, 124, 115,  43, 120,  43,  27,  27,  18,  28,  48, 125, 107, 114
Data  34, 133,  45, 120,  30, 127,  31, 116, 146
Data out_of_data

' ------=< MAIN >=------

Dim As String read_in
Dim As Integer i, x, y, count = -1 ' to let the index start on 0
Dim As Integer d()
ReDim d(300)                       ' big enough to hold data index start at 0

Do
    Read i
    If i = out_of_data Then Exit Do
    count = count + 1
    d(count) = i
Loop

ReDim Preserve d(count)            ' trim the data array
shellsort(d())                     ' sort data array

i = 0
For y =  d(0) \ 10 To d(UBound(d)) \ 10
    Print Using "#### |"; y;
    Do
        x = d(i) \ 10              ' \ = integer division
        If y = x Then
            Print Using "##"; d(i) Mod 10;
            i = i + 1
        Else
            Exit Do
        End If
    Loop While i <= UBound(d)
    Print                          ' force linefeed
Next

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End


package main

import (
    "fmt"
    "sort"
    "strconv"
    "strings"
)

var data = `12 127 28 42` //...omitted...127 31 116 146`

func main() {
    // load data into map
    m := make(map[int][]string)
    for _, s := range strings.Fields(data) {
        if len(s) == 1 {
            m[0] = append(m[0], s)
        } else if i, err := strconv.Atoi(s[:len(s)-1]); err == nil {
            m[i] = append(m[i], s[len(s)-1:])
        } else {
            panic("non numeric data")
        }
    }
    // sort stem
    s := make([]int, len(m))
    var i int
    for k := range m {
        s[i] = k
        i++
    }
    sort.Ints(s)
    // print
    for k := s[0]; ; k++ {
        v := m[k]
        sort.Strings(v)
        fmt.Printf("%2d | %s\n", k, strings.Join(v, " "))
        if k == s[len(s)-1] {
            break
        }
    }
}


REAL :: workspace(1000), base=16

DLG(CHeckbox=bitmap, NameEdit=base, DNum, MIn=1, MAx=16) ! 1 <= stem base <= 16
READ(ClipBoard, ItemS=nData) workspace    ! get raw data

ALIAS(workspace,1,  dataset,nData,  stems,nData)
SORT(Vector=dataset, Sorted=dataset)
stems = (dataset - MOD(dataset,base)) / base
dataset = dataset - base*stems
max_stem = MAX(stems)

IF( bitmap ) AXIS()
printed = 0
DO stem = 0, max_stem
  last = INDEX(stems, stem, 4) ! option 4: search backward
  IF( last > printed ) THEN
      nLeaves = last - printed
      IF(bitmap) THEN
        LINE(PenUp=1,W=8, x=0, y=stem, x=nLeaves, y=stem)
      ELSE
        ALIAS(dataset,printed+1,  leaves,nLeaves)
        WRITE(Format="i3, ':', 100Z2") stem, leaves
      ENDIF
      printed = printed + nLeaves
    ELSE
      WRITE(Format="i3, ':'") stem
    ENDIF
ENDDO


procedure main(A)
    prune := integer(\A[1]) | 10   # Boundary between leaf and stem
    every put(data := [], integer(!&input))
    writes(right(oldStem := 0,5)," |")
    every item := !sort(data) do {
        leaf := item % prune
        stem := item / prune
        while (oldStem < stem) do writes("\n",right(oldStem +:= 1, 5)," |")
        writes(" ",right(leaf,*prune-1,"0"))
        }
    write()
end


stem        =: <[email protected](%&10)
leaf        =: 10&|
stemleaf    =: ([email protected]{. ; leaf)/.~ stem
expandStems =: <./ ([ + [email protected]>:@-~) >./
expandLeaves=: (expandStems e. ])@[ #inv ]

showStemLeaf=: (":@,[email protected]@[ ; ":&>@expandLeaves)&>/@(>@{. ; <@{:)@|:@[email protected]/:~


import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class StemAndLeaf {
	private static int[] data = { 12, 127, 28, 42, 39, 113, 42, 18, 44, 118,
			44, 37, 113, 124, 37, 48, 127, 36, 29, 31, 125, 139, 131, 115, 105,
			132, 104, 123, 35, 113, 122, 42, 117, 119, 58, 109, 23, 105, 63,
			27, 44, 105, 99, 41, 128, 121, 116, 125, 32, 61, 37, 127, 29, 113,
			121, 58, 114, 126, 53, 114, 96, 25, 109, 7, 31, 141, 46, 13, 27,
			43, 117, 116, 27, 7, 68, 40, 31, 115, 124, 42, 128, 52, 71, 118,
			117, 38, 27, 106, 33, 117, 116, 111, 40, 119, 47, 105, 57, 122,
			109, 124, 115, 43, 120, 43, 27, 27, 18, 28, 48, 125, 107, 114, 34,
			133, 45, 120, 30, 127, 31, 116, 146 };

	public static Map<Integer, List<Integer>> createPlot(int... data){
		Map<Integer, List<Integer>> plot = new TreeMap<Integer, List<Integer>>();
		int highestStem = -1; //for filling in stems with no leaves
		for(int datum:data){
			int leaf = datum % 10;
			int stem = datum / 10; //integer division
			if(stem > highestStem){
				highestStem = stem;
			}
			if(plot.containsKey(stem)){
				plot.get(stem).add(leaf);
			}else{
				LinkedList<Integer> list = new LinkedList<Integer>();
				list.add(leaf);
				plot.put(stem, list);
			}
		}
		if(plot.keySet().size() < highestStem + 1 /*highest stem value and 0*/ ){
			for(int i = 0; i <= highestStem; i++){
				if(!plot.containsKey(i)){
					LinkedList<Integer> list = new LinkedList<Integer>();
					plot.put(i, list);
				}
			}
		}
		return plot;
	}

	public static void printPlot(Map<Integer, List<Integer>> plot){
		for(Map.Entry<Integer, List<Integer>> line : plot.entrySet()){
			Collections.sort(line.getValue());
			System.out.println(line.getKey() + " | " + line.getValue());
		}
	}

	public static void main(String[] args){
		Map<Integer, List<Integer>> plot = createPlot(data);
		printPlot(plot);
	}
}


<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">

<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>stem and leaf plot</title>


def stem_and_leaf:

  # align-right:
  def right: tostring | (4-length) * " " + .;

  sort
  | .[0] as $min
  | .[length-1] as $max
  | "\($min/10|floor|right) | " as $stem
  | reduce .[] as $d
      # state: [ stem, string ]
      ( [ 0, $stem ];
        .[0] as $stem
        | if ($d/10) | floor == $stem
          then [ $stem,     (.[1] +                      "\($d % 10)" )]
          else [ $stem + 1, (.[1] + "\n\($stem+1|right) | \($d % 10)" )]
          end )
  | .[1] ;


function stemleaf{T<:Real}(a::Array{T,1}, leafsize=1)
    ls = 10^int(log10(leafsize))
    (stem, leaf) = divrem(sort(int(a/ls)), 10)
    leaf[sign(stem) .== -1] *= -1
    negzero = leaf .< 0
    if any(negzero)
        leaf[negzero] *= -1
        nz = @sprintf "%10s | " "-0"
        nz *= join(map(string, leaf[negzero]), " ")
        nz *= "\n"
        stem = stem[!negzero]
        leaf = leaf[!negzero]
    else
        nz = ""
    end
    slp = ""
    for i in stem[1]:stem[end]
        i != 0 || (slp *= nz)
        slp *= @sprintf "%10d | " i
        slp *= join(map(string, leaf[stem .== i]), " ")
        slp *= "\n"
    end
    slp *= " Leaf Unit = " * string(convert(T, ls)) * "\n"
    return slp
end


StemPlot := proc( datatable::{rtable,list,algebraic} )
    local i, j, k, tf, LeafStemTable, LeafStemIndices;
    k:=0;

    LeafStemTable := ListTools:-Categorize( (x,y) -> iquo(x, 10) = iquo(y, 10), sort(datatable));

    if LeafStemTable = NULL then
        error "Empty List";
    elif nops( [ LeafStemTable ] ) = 1 or not( type( LeafStemTable[2], list) ) then
	LeafStemTable := [ LeafStemTable ];
    end if;

    LeafStemIndices := { seq( iquo( LeafStemTable[i][1], 10 ), i = 1..nops( [ LeafStemTable ] ) ) };

    for i from min( LeafStemIndices ) to max( LeafStemIndices ) do

        if i in LeafStemIndices then
            k := k + 1;

            if i = 0 then

		if min( datatable ) >=0 then
		    printf( "%-4a%s%-s\n", i,  "  |  ", StringTools:-Remove( "[],", convert( [seq( abs( irem( LeafStemTable[k][j], 10 ) ), j = 1..nops( LeafStemTable[k] ) )], string ) ) );
	        else
	            tf := ListTools:-Occurrences( true, (x->type(x,negative))~(LeafStemTable[k]));
		    printf( "%s%-4a%s%-s\n", "-", i,  " |  ", StringTools:-Remove( "[],", convert( [seq( abs( irem( LeafStemTable[k][j], 10 ) ), j = 1 .. tf )], string ) ) );
	            printf( "%-4a%s%-s\n", i,  "  |  ", StringTools:-Remove( "[],", convert( [seq( abs( irem( LeafStemTable[k][j], 10 ) ), j = tf + 1 .. nops( LeafStemTable[k] ) )], string ) ) );
	        end if;

            else

               	printf( "%-4a%s%-s\n", i,  "  |  ", StringTools:-Remove( "[],", convert( [seq( abs( irem( LeafStemTable[k][j], 10 ) ), j = 1..nops( LeafStemTable[k] ) )], string ) ) );

	    end if;

        else

	    printf( "%-4a%s\n", i, "  |  " );

	end if;

    end do;

    return NULL;
end proc:

Y := [ 12, 127,  28,  42,  39, 113,  42,  18,  44, 118,  44,  37, 113, 124, 37,  48, 127,  36,  29,  31, 125, 139, 131, 115, 105, 132, 104, 123, 35, 113, 122,  42, 117, 119,  58, 109,  23, 105,  63,  27,  44, 105, 99,  41, 128, 121, 116, 125,  32,  61,  37, 127,  29, 113, 121,  58, 114, 126,  53, 114,  96,  25, 109,   7,  31, 141,  46,  13,  27,  43, 117, 116,  27,   7,  68,  40,  31, 115, 124,  42, 128,  52,  71, 118, 117,  38,  27, 106,  33, 117, 116, 111,  40, 119,  47, 105,  57, 122, 109, 124, 115,  43, 120,  43,  27,  27,  18,  28,  48, 125, 107, 114, 34, 133,  45, 120,  30, 127,  31, 116, 146];

StemPlot(Y);


len[n_] := RealDigits[n][[2]]; padding = len[[email protected] Quotient[inputdata, 10]];
For[i = [email protected] Quotient[inputdata, 10],i <= [email protected] Quotient[inputdata, 10], i++,
 (Print[i, If[(padding - len[i]) > 0, (padding - len[i])*" " <> " |", " |"] ,
 StringJoin[(" " <> #) & /@ Map[ToString, #]]])&@
  Select[{Quotient[#, 10], Mod[#, 10]} & /@ Sort[inputdata],Part[#, 1] == i &][[;; , 2]]]


import tables
import math
import strutils
import algorithm

type
  StemLeafPlot = ref object
    leafDigits: int
    multiplier: int
    plot: TableRef[int, seq[int]]

proc `$`(s: seq[int]): string =
  result = ""
  for item in s:
    result &= $item & " "

proc `$`(self: StemLeafPlot): string =
  result = ""
  var keys: seq[int] = @[]
  for stem, _ in self.plot:
    keys.add(stem)
  for printedStem in keys.min..keys.max:
    result &= align($printedStem & " | ", ($keys.max).len + 4)
    if printedStem in keys:
      self.plot[printedStem].sort(system.cmp[int])
      result &= $self.plot[printedStem]
    result &= "\n"

proc parse(self: StemLeafPlot, value: int): tuple[stem, leaf: int] =
  (value div self.multiplier, abs(value mod self.multiplier))

proc init[T](self: StemLeafPlot, leafDigits: int, data: openArray[T]) =
  self.leafDigits = leafDigits
  self.multiplier = 10 ^ leafDigits
  self.plot = newTable[int, seq[int]]()
  for value in data:
    let (stem, leaf) = self.parse(value)
    if stem notin self.plot:
      self.plot[stem] = @[leaf]
    else:
      self.plot[stem].add(leaf)

var taskData = @[12, 127,  28,  42,  39, 113,  42,  18,  44, 118,  44,  37, 113, 124,
                 37,  48, 127,  36,  29,  31, 125, 139, 131, 115, 105, 132, 104, 123,
                 35, 113, 122,  42, 117, 119,  58, 109,  23, 105,  63,  27,  44, 105,
                 99,  41, 128, 121, 116, 125,  32,  61,  37, 127,  29, 113, 121,  58,
                 114, 126,  53, 114,  96,  25, 109,   7,  31, 141,  46,  13,  27,  43,
                 117, 116,  27,   7,  68,  40,  31, 115, 124,  42, 128,  52,  71, 118,
                 117,  38,  27, 106,  33, 117, 116, 111,  40, 119,  47, 105,  57, 122,
                 109, 124, 115,  43, 120,  43,  27,  27,  18,  28,  48, 125, 107, 114,
                 34, 133,  45, 120,  30, 127,  31, 116, 146]

var negativeData = @[-24, -12, -3, 4, 6, 6, 17, 25, 57]

echo "Using the Task's Test Data"
var taskPlot = StemLeafPlot()
taskPlot.init(1, taskData)
echo taskPlot

echo "Test with Negative Stem"
var negativePlot = StemLeafPlot()
negativePlot.init(1, negativeData)
echo negativePlot


let unique li =
  let rec aux acc = function
  | [] -> (List.rev acc)
  | x::xs ->
      if List.mem x acc
      then aux acc xs
      else aux (x::acc) xs
  in
  aux [] li


F sd_mean(numbers)
   V mean = sum(numbers) / numbers.len
   V sd = (sum(numbers.map(n -> (n - @mean) ^ 2)) / numbers.len) ^ 0.5
   R (sd, mean)

F histogram(numbers)
   V h = [0] * 10
   V maxwidth = 50
   L(n) numbers
      h[Int(n * 10)]++
   V mx = max(h)
   print()
   L(i) h
      print(‘#.1: #.’.format(L.index / 10, ‘+’ * (i * maxwidth I/ mx)))
   print()

L(i) (1, 5)
   V n = (0 .< 10 ^ i).map(j -> random:())
   print("\n####\n#### #. numbers\n####".format(10 ^ i))
   V (sd, mean) = sd_mean(n)
   print(‘  sd: #.6, mean: #.6’.format(sd, mean))
   histogram(n)


INCLUDE "H6:REALMATH.ACT"

DEFINE SIZE="10000"
DEFINE HIST_SIZE="10"
BYTE ARRAY data(SIZE)
CARD ARRAY hist(HIST_SIZE)

PROC Generate()
  INT i

  FOR i=0 TO SIZE-1
  DO
    data(i)=Rand(0)
  OD
RETURN

PROC CalcMean(INT count REAL POINTER mean)
  REAL tmp1,tmp2,r255
  INT i

  IntToReal(0,mean)
  IntToReal(255,r255)
  FOR i=0 TO count-1
  DO
    IntToReal(data(i),tmp1)
    RealDiv(tmp1,r255,tmp2)
    RealAdd(mean,tmp2,tmp1)
    RealAssign(tmp1,mean)
  OD
  IntToReal(count,tmp1)
  RealDiv(mean,tmp1,tmp2)
  RealAssign(tmp2,mean)
RETURN

PROC CalcStdDev(INT count REAL POINTER mean,sdev)
  REAL tmp1,tmp2,r255
  INT i

  IntToReal(0,sdev)
  IntToReal(255,r255)
  FOR i=0 TO count-1
  DO
    IntToReal(data(i),tmp1)
    RealDiv(tmp1,r255,tmp2)
    RealSub(tmp2,mean,tmp1)
    RealMult(tmp1,tmp1,tmp2)
    RealAdd(sdev,tmp2,tmp1)
    RealAssign(tmp1,sdev)
  OD
  IntToReal(count,tmp1)
  RealDiv(sdev,tmp1,tmp2)
  Sqrt(tmp2,sdev)
RETURN

PROC ClearHistogram()
  BYTE i

  FOR i=0 TO HIST_SIZE-1
  DO
    hist(i)=0
  OD
RETURN

PROC CalcHistogram(INT count)
  INT i,index

  ClearHistogram()
  FOR i=0 TO count-1
  DO
    index=data(i)*10/256
    hist(index)==+1
  OD
RETURN

PROC PrintHistogram()
  BYTE i,j,n
  INT max
  REAL tmp1,tmp2,rmax,rlen

  max=0
  FOR i=0 TO HIST_SIZE-1
  DO
    IF hist(i)>max THEN
      max=hist(i)
    FI
  OD
  IntToReal(max,rmax)
  IntToReal(25,rlen)

  FOR i=0 TO HIST_SIZE-1
  DO
    PrintF("0.%Bx: ",i)
    IntToReal(hist(i),tmp1)
    RealMult(tmp1,rlen,tmp2)
    RealDiv(tmp2,rmax,tmp1)
    n=RealToInt(tmp1)
    FOR j=0 TO n
    DO
      Put('*)
    OD
    PrintF(" %U",hist(i))
    IF i<HIST_SIZE-1 THEN
      PutE()
    FI
  OD
RETURN

PROC Test(INT count)
  REAL mean,sdev

  PrintI(count)
  CalcMean(count,mean)
  Print(": m=") PrintR(mean)
  CalcStdDev(count,mean,sdev)
  Print(" sd=") PrintRE(sdev)
  CalcHistogram(count)
  PrintHistogram()
RETURN

PROC Main()
  Put(125) PutE() ;clear screen
  MathInit()
  Generate()
  Test(100)
  PutE() PutE()
  Test(10000)
RETURN


with Ada.Text_IO, Ada.Command_Line, Ada.Numerics.Float_Random,
  Ada.Numerics.Generic_Elementary_Functions;

procedure Basic_Stat is

   package FRG renames Ada.Numerics.Float_Random;
   package TIO renames Ada.Text_IO;

   type Counter is range 0 .. 2**31-1;
   type Result_Array is array(Natural range <>) of Counter;

   package FIO is new TIO.Float_IO(Float);

   procedure Put_Histogram(R: Result_Array; Scale, Full: Counter) is
   begin
      for I in R'Range loop
         FIO.Put(Float'Max(0.0, Float(I)/10.0 - 0.05),
                 Fore => 1, Aft => 2, Exp => 0);       TIO.Put("..");
         FIO.Put(Float'Min(1.0, Float(I)/10.0 + 0.05),
                 Fore => 1, Aft => 2, Exp => 0);       TIO.Put(": ");
         for J in 1 .. (R(I)* Scale)/Full loop
            Ada.Text_IO.Put("X");
         end loop;
         Ada.Text_IO.New_Line;
      end loop;
   end Put_Histogram;

   procedure Put_Mean_Et_Al(Sample_Size: Counter;
                            Val_Sum, Square_Sum: Float) is
      Mean: constant Float := Val_Sum / Float(Sample_Size);
      package Math is new Ada.Numerics.Generic_Elementary_Functions(Float);
   begin
      TIO.Put("Mean: ");
      FIO.Put(Mean,  Fore => 1, Aft => 5, Exp => 0);
      TIO.Put(",  Standard Deviation: ");
      FIO.Put(Math.Sqrt(abs(Square_Sum / Float(Sample_Size)
                           - (Mean * Mean))), Fore => 1, Aft => 5, Exp => 0);
      TIO.New_Line;
   end Put_Mean_Et_Al;

   N: Counter := Counter'Value(Ada.Command_Line.Argument(1));
   Gen: FRG.Generator;
   Results: Result_Array(0 .. 10) := (others => 0);
   X: Float;
   Val_Sum, Squ_Sum: Float := 0.0;

begin
   FRG.Reset(Gen);
   for I in 1 .. N loop
      X := FRG.Random(Gen);
      Val_Sum   := Val_Sum + X;
      Squ_Sum := Squ_Sum + X*X;
      declare
         Index: Integer := Integer(X*10.0);
      begin
         Results(Index) := Results(Index) + 1;
      end;
   end loop;
   TIO.Put_Line("After sampling" & Counter'Image(N) & " random numnbers: ");
   Put_Histogram(Results, Scale => 600, Full => N);
   TIO.New_Line;
   Put_Mean_Et_Al(Sample_Size => N, Val_Sum => Val_Sum, Square_Sum => Squ_Sum);
end Basic_Stat;


If OpenConsole()
  Dim MyList(120)
  Define i, j, StemMax, StemMin
  Restore MyData          ; Get the address of MyData, e.g. the data to print as a Stem-and-leaf plot
  For a=0 To 120
    Read.i MyList(a)      ; Read the data into the used Array
    If MyList(a)>StemMax
      StemMax=MyList(a)   ; Find the largest Stem layer at the same time
    EndIf
    If MyList(a)<StemMin
      StemMin=MyList(a)   ; Find the smallest Stem layer at the same time
    EndIf
  Next
  StemMax/10: StemMin/10  ; Remove the leafs from the Stem limits
  SortArray(MyList(),#PB_Sort_Ascending)  ; Sort the data

  For i=StemMin To StemMax
    Print(RSet(Str(i),3)+" | ")           ; Print the Stem
    For j=0 To 120
      If MyList(j)<10*i                   ; Skip all smaller then current
        Continue
      ElseIf MyList(j)>=10*(i+1)          ; Break current print if a new Stem layer is reached
        Break
      Else
        Print(Str(MyList(j)%10)+" ")      ; Print all Leafs on this current Stem layer
      EndIf
    Next j
    PrintN("")
  Next i

  Print(#CRLF$+#CRLF$+"Press ENTER to exit")
  Input()
  CloseConsole()
EndIf

DataSection
MyData:
  Data.i  12,127, 28, 42, 39,113, 42, 18, 44,118, 44, 37,113,124, 37, 48,127, 36, 29, 31,125,139,131,115
  Data.i 105,132,104,123, 35,113,122, 42,117,119, 58,109, 23,105, 63, 27, 44,105, 99, 41,128,121,116,125
  Data.i  32, 61, 37,127, 29,113,121, 58,114,126, 53,114, 96, 25,109,  7, 31,141, 46, 13, 27, 43,117,116
  Data.i  27,  7, 68, 40, 31,115,124, 42,128, 52, 71,118,117, 38, 27,106, 33,117,116,111, 40,119, 47,105
  Data.i  57,122,109,124,115, 43,120, 43, 27, 27, 18, 28, 48,125,107,114, 34,133, 45,120, 30,127, 31,116,146
EndDataSection


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdint.h>

#define n_bins 10

double rand01() { return rand() / (RAND_MAX + 1.0); }

double avg(int count, double *stddev, int *hist)
{
	double x[count];
	double m = 0, s = 0;

	for (int i = 0; i < n_bins; i++) hist[i] = 0;
	for (int i = 0; i < count; i++) {
		m += (x[i] = rand01());
		hist[(int)(x[i] * n_bins)] ++;
	}

	m /= count;
	for (int i = 0; i < count; i++)
		s += x[i] * x[i];
	*stddev = sqrt(s / count - m * m);
	return m;
}

void hist_plot(int *hist)
{
	int max = 0, step = 1;
	double inc = 1.0 / n_bins;

	for (int i = 0; i < n_bins; i++)
		if (hist[i] > max) max = hist[i];

	/* scale if numbers are too big */
	if (max >= 60) step = (max + 59) / 60;

	for (int i = 0; i < n_bins; i++) {
		printf("[%5.2g,%5.2g]%5d ", i * inc, (i + 1) * inc, hist[i]);
		for (int j = 0; j < hist[i]; j += step)
			printf("#");
		printf("\n");
	}
}

/*  record for moving average and stddev.  Values kept are sums and sum data^2
 *  to avoid excessive precision loss due to divisions, but some loss is inevitable
 */
typedef struct {
	uint64_t size;
	double sum, x2;
	uint64_t hist[n_bins];
} moving_rec;

void moving_avg(moving_rec *rec, double *data, int count)
{
	double sum = 0, x2 = 0;
	/* not adding data directly to the sum in case both recorded sum and
	 * count of this batch are large; slightly less likely to lose precision*/
	for (int i = 0; i < count; i++) {
		sum += data[i];
		x2 += data[i] * data[i];
		rec->hist[(int)(data[i] * n_bins)]++;
	}

	rec->sum += sum;
	rec->x2 += x2;
	rec->size += count;
}

int main()
{
	double m, stddev;
	int hist[n_bins], samples = 10;

	while (samples <= 10000) {
		m = avg(samples, &stddev, hist);
		printf("size %5d: %g %g\n", samples, m, stddev);
		samples *= 10;
	}

	printf("\nHistograph:\n");
	hist_plot(hist);

	printf("\nMoving average:\n  N     Mean    Sigma\n");
	moving_rec rec = { 0, 0, 0, {0} };
	double data[100];
	for (int i = 0; i < 10000; i++) {
		for (int j = 0; j < 100; j++) data[j] = rand01();

		moving_avg(&rec, data, 100);

		if ((i % 1000) == 999) {
			printf("%4lluk %f %f\n",
				rec.size/1000,
				rec.sum / rec.size,
				sqrt(rec.x2 * rec.size - rec.sum * rec.sum)/rec.size
			);
		}
	}
}


using System;
using MathNet.Numerics.Statistics;

class Program
{
    static void Run(int sampleSize)
    {
        double[] X = new double[sampleSize];
        var r = new Random();
        for (int i = 0; i < sampleSize; i++)
            X[i] = r.NextDouble();

        const int numBuckets = 10;
        var histogram = new Histogram(X, numBuckets);
        Console.WriteLine("Sample size: {0:N0}", sampleSize);
        for (int i = 0; i < numBuckets; i++)
        {
            string bar = new String('#', (int)(histogram[i].Count * 360 / sampleSize));
            Console.WriteLine(" {0:0.00} : {1}", histogram[i].LowerBound, bar);
        }
        var statistics = new DescriptiveStatistics(X);
        Console.WriteLine("  Mean: " + statistics.Mean);
        Console.WriteLine("StdDev: " + statistics.StandardDeviation);
        Console.WriteLine();
    }
    static void Main(string[] args)
    {
        Run(100);
        Run(1000);
        Run(10000);
    }
}


#include <iostream>
#include <random>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <cmath>

void printStars ( int number ) {
   if ( number > 0 ) {
      for ( int i = 0 ; i < number + 1 ; i++ )
	 std::cout << '*' ;
   }
   std::cout << '\n' ;
}

int main( int argc , char *argv[] ) {
   const int numberOfRandoms = std::atoi( argv[1] ) ;
   std::random_device rd ;
   std::mt19937 gen( rd( ) ) ;
   std::uniform_real_distribution<> distri( 0.0 , 1.0 ) ;
   std::vector<double> randoms ;
   for ( int i = 0 ; i < numberOfRandoms + 1 ; i++ )
      randoms.push_back ( distri( gen ) ) ;
   std::sort ( randoms.begin( ) , randoms.end( ) ) ;
   double start = 0.0 ;
   for ( int i = 0 ;  i < 9 ; i++ ) {
      double to = start + 0.1 ;
      int howmany =  std::count_if ( randoms.begin( ) , randoms.end( ),
	        [&start , &to] ( double c ) { return c >= start
		  && c < to ; } ) ;
      if ( start == 0.0 ) //double 0.0 output as 0
	 std::cout << "0.0" << " - " << to << ": " ;
      else
	 std::cout << start << " - " << to << ": " ;
      if ( howmany > 50 ) //scales big interval numbers to printable length
	 howmany = howmany / ( howmany / 50 ) ;
      printStars ( howmany ) ;
      start += 0.1 ;
   }
   double mean = std::accumulate( randoms.begin( ) , randoms.end( ) , 0.0 ) / randoms.size( ) ;
   double sum = 0.0 ;
   for ( double num : randoms )
      sum += std::pow( num - mean , 2 ) ;
   double stddev = std::pow( sum / randoms.size( ) , 0.5 ) ;
   std::cout << "The mean is " << mean << " !" << std::endl ;
   std::cout << "Standard deviation is " << stddev << " !" << std::endl ;
   return 0 ;
}


#lang racket
(define (show-stem+leaf data)
  (define xs (sort data <))
  (for ([stem (add1 (floor (/ (last xs) 10)))])
    (printf "~a|" (~a #:width 2 #:align 'right stem))
    (for ([i xs])
      (define-values [q r] (quotient/remainder i 10))
      (when (= q stem) (printf " ~a" r)))
    (newline)))
(show-stem+leaf (sequence->list (in-producer read eof)))


generate_statistics = (n) ->
  hist = {}

  update_hist = (r) ->
    hist[Math.floor 10*r] ||= 0
    hist[Math.floor 10*r] += 1

  sum = 0
  sum_squares = 0.0

  for i in [1..n]
    r = Math.random()
    sum += r
    sum_squares += r*r
    update_hist r
  mean = sum / n
  stddev = Math.sqrt((sum_squares / n) - mean*mean)

  [n, mean, stddev, hist]

display_statistics = (n, mean, stddev, hist) ->
  console.log "-- Stats for sample size #{n}"
  console.log "mean: #{mean}"
  console.log "sdev: #{stddev}"
  for x, cnt of hist
    bars = repeat "=", Math.floor(cnt*300/n)
    console.log "#{x/10}: #{bars} #{cnt}"

repeat = (c, n) ->
  s = ''
  s += c for i in [1..n]
  s

for n in [100, 1000, 10000, 1000000]
  [n, mean, stddev, hist] = generate_statistics n
  display_statistics n, mean, stddev, hist


import std.stdio, std.algorithm, std.array, std.typecons,
       std.range, std.exception;

auto meanStdDev(R)(R numbers) /*nothrow*/ @safe /*@nogc*/ {
    if (numbers.empty)
        return tuple(0.0L, 0.0L);

    real sx = 0.0, sxx = 0.0;
    ulong n;
    foreach (x; numbers) {
        sx += x;
        sxx += x ^^ 2;
        n++;
    }
    return tuple(sx / n, (n * sxx - sx ^^ 2) ^^ 0.5L / n);
}

void showHistogram01(R)(R numbers) /*@safe*/ {
    enum maxWidth = 50; // N. characters.
    ulong[10] bins;
    foreach (immutable x; numbers) {
        immutable index = cast(size_t)(x * bins.length);
        enforce(index >= 0 && index < bins.length);
        bins[index]++;
    }
    immutable real maxFreq = bins.reduce!max;

    foreach (immutable n, immutable i; bins)
        writefln(" %3.1f: %s", n / real(bins.length),
                 replicate("*", cast(int)(i / maxFreq * maxWidth)));
    writeln;
}

version (statistics_basic_main) {
    void main() @safe {
        import std.random;

        foreach (immutable p; 1 .. 7) {
            auto n = iota(10L ^^ p).map!(_ => uniform(0.0L, 1.0L));
            writeln(10L ^^ p, " numbers:");
            writefln(" Mean: %8.6f, SD: %8.6f", n.meanStdDev.tupleof);
            n.showHistogram01;
        }
    }
}


/*REXX program displays a stem and leaf plot of any non-negative numbers [can include 0]*/
parse arg @                                      /* [↓]  Not specified? Then use default*/
if @=''  then @=12 127 28 42 39 113 42 18 44 118 44 37 113 124 37 48 127 36 29 31 125 139,
   131 115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128 121,
   116 125  32  61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 13 27 43 117,
   116  27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116 111 40 119 47 105,
   57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34 133 45 120 30 127 31 116 146
#.=;                            bot=.;    top=.  /* [↑]  define all #. elements as null.*/
     do j=1  for words(@);     y=word(@, j)      /*◄─── process each number in the list.*/
     if \datatype(y,"N")  then do; say '***error*** item' j "isn't numeric:" y;  exit; end
     if y<0               then do; say '***error*** item' j "is negative:"   y;  exit; end
     n=format(y, , 0) / 1                        /*normalize the numbers (not malformed)*/
     stem=word(left(n, length(n) -1)  0, 1)      /*obtain stem (1st digits) from number.*/
     parse var  n '' -1 leaf;   _=stem * sign(n) /*   "   leaf (last digit)   "    "    */
     if bot==.  then do;  bot=_;  top=_;  end    /*handle the first case for TOP and BOT*/
     bot=min(bot, _);           top=max(top, _)  /*obtain the minimum and maximum so far*/
     #.stem.leaf= #.stem.leaf   leaf             /*construct sorted stem-and-leaf entry.*/
     end   /*j*/

w=max(length(min), length(max) )    + 1          /*W:  used to right justify the output.*/
                                                 /* [↓]  display the stem-and-leaf plot.*/
     do k=bot  to top;          $=               /*$:  is the output string, a plot line*/
        do m=0  for 10;         $=$  #.k.m       /*build a line for the stem─&─leaf plot*/
        end  /*m*/
     say right(k, w)    '║'     space($)         /*display a line of stem─and─leaf plot.*/
     end   /*k*/                                 /*stick a fork in it,  we're all done. */


/* Import math library to get:
 *     	1) Square root function 	        : Math.sqrt(x)
 *	2) Power function 		: Math.pow(base, exponent)
 *	3) Random number generator 	: Math.Random()
 */
import 'dart:math' as Math show sqrt, pow, Random;

// Returns average/mean of a list of numbers
num mean(List<num> l)  => l.reduce((num value,num element)=>value+element)/l.length;

// Returns standard deviation of a list of numbers
num stdev(List<num> l) => Math.sqrt((1/l.length)*l.map((num x)=>x*x).reduce((num value,num element) => value+element) - Math.pow(mean(l),2));

/* CODE TO PRINT THE HISTOGRAM STARTS HERE
 *
 * 	Histogram has ten fields, one for every tenth between 0 and 1
 * 	To do this, we save the histogram as a global variable
 * 	that will hold the number of occurences of each tenth in the sample
 */
List<num> histogram = new List.filled(10,0);

/*
 * METHOD TO CREATE A RANDOM SAMPLE OF n NUMBERS (Returns a list)
 *
 * 	While creating each value, this method also increments the
 * 	appropriate index of the histogram
 */
List<num> randomsample(num n){
  List<num> l = new List<num>(n);
  histogram = new List.filled(10,0);
  num random = new Math.Random();
  for (int i = 0; i < n; i++){
    l[i] = random.nextDouble();
    histogram[conv(l[i])] += 1;
  }
  return l;
}

/*
 * METHOD TO RETURN A STRING OF n ASTERIXES (yay ASCII art)
 */
String stars(num n){
  String s = '';
  for (int i = 0; i < n; i++){
    s = s + '*';
  }
  return s;
}

/*
 * METHOD TO DRAW THE HISTOGRAM
 * 1) Get to total for all the values in the histogram
 * 2) For every field in the histogram:
 * 		a) Compute the frequency for every field in the histogram
 * 		b) Print the frequency as asterixes
 */
void drawhistogram(){
  int total = histogram.reduce((num element,num value)=>element+value);
  double freq;
  for (int i = 0; i < 10; i++){
    freq = histogram[i]/total;
    print('${i/10} - ${(i+1)/10} : ' + stars(conv(30*freq)));
  }
}

/* HELPER METHOD:
 * 	converts values between 0-1 to integers between 0-9 inclusive
 * 	useful to figure out which random value generated
 *	corresponds to which field in the histogram
 */
int conv(num i) => (10*i).floor();

/* MAIN FUNCTION
 *
 * Create 5 histograms and print the mean and standard deviation for each:
 * 	1) Sample Size = 100
 *	2) Sample Size = 1000
 *	3) Sample Size = 10000
 *	4) Sample Size = 100000
 *	5) Sample Size = 1000000
 *
 */
void main(){
  List<num> l;
  num m;
  num s;
  List<int> sampleSizes = [100,1000,10000,100000,1000000];
  for (int samplesize in sampleSizes){
    print('---------------  Sample size $samplesize   ----------------');
    l = randomsample(samplesize);
    m = mean(l);
    s = stdev(l);
    drawhistogram();
    print('');
    print('mean: ${m.toStringAsPrecision(8)}   standard deviation: ${s.toStringAsPrecision(8)}');
    print('');
  }
}


class StemLeafPlot
  def initialize(data, options = {})
    opts = {:leaf_digits => 1}.merge(options)
    @leaf_digits = opts[:leaf_digits]
    @multiplier = 10 ** @leaf_digits
    @plot = generate_structure(data)
  end

  private

  def generate_structure(data)
    plot = Hash.new {|h,k| h[k] = []}
    data.sort.each do |value|
      stem, leaf = parse(value)
      plot[stem] << leaf
    end
    plot
  end

  def parse(value)
    stem, leaf = value.abs.divmod(@multiplier)
    [Stem.get(stem, value), leaf.round]
  end

  public

  def print
    stem_width = Math.log10(@plot.keys.max_by {|s| s.value}.value).ceil + 1
    Stem.get_range(@plot.keys).each do |stem|
      leaves = @plot[stem].inject("") {|str,leaf| str << "%*d " % [@leaf_digits, leaf]}
      puts "%*s | %s" % [stem_width, stem, leaves]
    end

    puts "key: 5|4=#{5 * @multiplier + 4}"
    puts "leaf unit: 1"
    puts "stem unit: #@multiplier"
  end
end

class Stem
  @@cache = {}

  def self.get(stem_value, datum)
    sign = datum < 0 ? :- : :+
    cache(stem_value, sign)
  end

  private

  def self.cache(value, sign)
    if @@cache[[value, sign]].nil?
      @@cache[[value, sign]] = self.new(value, sign)
    end
    @@cache[[value, sign]]
  end

  def initialize(value, sign)
    @value = value
    @sign = sign
  end

  public

  attr_accessor :value, :sign

  def negative?
    @sign == :-
  end

  def <=>(other)
    if self.negative?
      if other.negative?
        other.value <=> self.value
      else
        -1
      end
    else
      if other.negative?
        1
      else
        self.value <=> other.value
      end
    end
  end

  def to_s
    "%s%d" % [(self.negative? ? '-' : ' '), @value]
  end

  def self.get_range(array_of_stems)
    min, max = array_of_stems.minmax
    if min.negative?
      if max.negative?
        min.value.downto(max.value).collect {|n| cache(n, :-)}
      else
        min.value.downto(0).collect {|n| cache(n, :-)} + 0.upto(max.value).collect {|n| cache(n, :+)}
      end
    else
      min.value.upto(max.value).collect {|n| cache(n, :+)}
    end
  end

end

data = DATA.read.split.map {|s| Float(s)}
StemLeafPlot.new(data).print

__END__
12 127 28 42 39 113 42 18 44 118 44 37 113 124 37 48 127 36 29 31 125 139 131
115 105 132 104 123 35 113 122 42 117 119 58 109 23 105 63 27 44 105 99 41 128
121 116 125 32 61 37 127 29 113 121 58 114 126 53 114 96 25 109 7 31 141 46 13
27 43 117 116 27 7 68 40 31 115 124 42 128 52 71 118 117 38 27 106 33 117 116
111 40 119 47 105 57 122 109 124 115 43 120 43 27 27 18 28 48 125 107 114 34
133 45 120 30 127 31 116 146


defmodule Statistics do
  def basic(n) do
    {sum, sum2, hist} = generate(n)
    mean = sum / n
    stddev = :math.sqrt(sum2 / n - mean*mean)

    IO.puts "size:   #{n}"
    IO.puts "mean:   #{mean}"
    IO.puts "stddev: #{stddev}"
    Enum.each(0..9, fn i ->
      :io.fwrite "~.1f:~s~n", [0.1*i, String.duplicate("=", trunc(500 * hist[i] / n))]
    end)
    IO.puts ""
  end

  defp generate(n) do
    hist = for i <- 0..9, into: %{}, do: {i,0}
    Enum.reduce(1..n, {0, 0, hist}, fn _,{sum, sum2, h} ->
      r = :rand.uniform
      {sum+r, sum2+r*r, Map.update!(h, trunc(10*r), &(&1+1))}
    end)
  end
end

Enum.each([100,1000,10000], fn n ->
  Statistics.basic(n)
end)


USING: assocs formatting grouping io kernel literals math
math.functions math.order math.statistics prettyprint random
sequences sequences.deep sequences.repeating ;
IN: rosetta-code.statistics-basic

CONSTANT: granularity
    $[ 11 iota [ 10 /f ] map 2 clump ]

: mean/std ( seq -- a b )
    [ mean ] [ population-std ] bi ;

: .mean/std ( seq -- )
    mean/std [ "Mean: " write . ] [ "STD:  " write . ] bi* ;

: count-between ( seq a b -- n )
    [ between? ] 2curry count ;

: histo ( seq -- seq )
    granularity [ first2 count-between ] with map ;

: bar ( n -- str )
    [ dup 50 < ] [ 10 / ] until 2 * >integer "*" swap repeat ;

: (.histo) ( seq -- seq' )
    [ bar ] map granularity swap zip flatten 3 group ;

: .histo ( seq -- )
    (.histo) [ "%.1f - %.1f %s\n" vprintf ] each ;

: stats ( n -- )
    dup "Statistics %d:\n" printf
    random-units [ histo .histo ] [ .mean/std nl ] bi ;

: main ( -- )
    { 100 1,000 10,000 } [ stats ] each ;

MAIN: main


program basic_stats
  implicit none

  integer, parameter :: i64 = selected_int_kind(18)
  integer, parameter :: r64 = selected_real_kind(15)
  integer(i64), parameter :: samples = 1000000000_i64

  real(r64) :: r
  real(r64) :: mean, stddev
  real(r64) :: sumn = 0, sumnsq = 0
  integer(i64) :: n = 0
  integer(i64) :: bin(10) = 0
  integer :: i, ind

  call random_seed

  n = 0
  do while(n <= samples)
    call random_number(r)
    ind = r * 10 + 1
    bin(ind) = bin(ind) + 1_i64
    sumn = sumn + r
    sumnsq = sumnsq + r*r
    n = n + 1_i64
  end do

  mean = sumn / n
  stddev = sqrt(sumnsq/n - mean*mean)
  write(*, "(a, i0)") "sample size = ", samples
  write(*, "(a, f17.15)") "Mean :   ", mean,
  write(*, "(a, f17.15)") "Stddev : ", stddev
  do i = 1, 10
    write(*, "(f3.1, a, a)") real(i)/10.0, ": ", repeat("=", int(bin(i)*500/samples))
  end do

end program


def stemAndLeaf(numbers: List[Int]) = {
  val lineFormat = "%" + (numbers map (_.toString.length) max) + "d | %s"
  val map = numbers groupBy (_ / 10)
  for (stem <- numbers.min / 10 to numbers.max / 10) {
    println(lineFormat format (stem, map.getOrElse(stem, Nil) map (_ % 10) sortBy identity mkString " "))
  }
}


' FB 1.05.0 Win64

Randomize

Sub basicStats(sampleSize As Integer)
  If sampleSize < 1 Then Return
  Dim r(1 To sampleSize) As Double
  Dim h(0 To 9) As Integer '' all zero by default
  Dim sum As Double = 0.0
  Dim hSum As Integer = 0

  ' Generate 'sampleSize' random numbers in the interval [0, 1)
  ' calculate their sum
  ' and in which box they will fall when drawing the histogram
  For i As Integer = 1 To sampleSize
    r(i) = Rnd
    sum += r(i)
    h(Int(r(i) * 10)) += 1
  Next

  For i As Integer = 0 To 9 : hSum += h(i) :  Next
  ' adjust one of the h() values if necessary to ensure hSum = sampleSize
  Dim adj As Integer = sampleSize - hSum
  If adj <> 0 Then
    For i As Integer = 0 To 9
      h(i) += adj
      If h(i) >= 0 Then Exit For
      h(i) -= adj
    Next
  End If

  Dim mean As Double = sum / sampleSize

  Dim sd As Double
  sum = 0.0
  ' Now calculate their standard deviation
  For i As Integer = 1 To sampleSize
    sum += (r(i) - mean) ^ 2.0
  Next
  sd  = Sqr(sum/sampleSize)

  ' Draw a histogram of the data with interval 0.1
  Dim numStars As Integer
  ' If sample size > 500 then normalize histogram to 500
  Dim scale As Double = 1.0
  If sampleSize > 500 Then scale = 500.0 / sampleSize
  Print "Sample size "; sampleSize
  Print
  Print Using "  Mean #.######"; mean;
  Print Using "  SD #.######"; sd
  Print
  For i As Integer = 0 To 9
    Print Using "  #.## : "; i/10.0;
    Print Using "##### " ; h(i);
    numStars = Int(h(i) * scale + 0.5)
    Print String(numStars, "*")
  Next
End Sub

basicStats 100
Print
basicStats 1000
Print
basicStats 10000
Print
basicStats 100000
Print
Print "Press any key to quit"
Sleep


package main

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

func main() {
    sample(100)
    sample(1000)
    sample(10000)
}

func sample(n int) {
    // generate data
    d := make([]float64, n)
    for i := range d {
        d[i] = rand.Float64()
    }
    // show mean, standard deviation
    var sum, ssq float64
    for _, s := range d {
        sum += s
        ssq += s * s
    }
    fmt.Println(n, "numbers")
    m := sum / float64(n)
    fmt.Println("Mean:  ", m)
    fmt.Println("Stddev:", math.Sqrt(ssq/float64(n)-m*m))
    // show histogram
    h := make([]int, 10)
    for _, s := range d {
        h[int(s*10)]++
    }
    for _, c := range h {
        fmt.Println(strings.Repeat("*", c*205/int(n)))
    }
    fmt.Println()
}


package require Tcl 8.5

# How to process a single value, adding it to the table mapping stems to
# leaves.
proc addSLValue {tblName value {splitFactor 10}} {
    upvar 1 $tblName tbl
    # Extract the stem and leaf
    if {$value < 0} {
	set value [expr {round(-$value)}]
	set stem -[expr {$value / $splitFactor}]
    } else {
	set value [expr {round($value)}]
	set stem [expr {$value / $splitFactor}]
    }
    if {![info exist tbl]} {
	dict set tbl min $stem
    }
    dict set tbl max $stem
    set leaf [expr {$value % $splitFactor}]
    dict lappend tbl $stem $leaf
}

# How to do the actual output of the stem-and-leaf table, given that we have
# already done the splitting into stems and leaves.
proc printSLTable {tblName} {
    upvar 1 $tblName tbl
    # Get the range of stems
    set min [dict get $tbl min]
    set max [dict get $tbl max]
    # Work out how much width the stems take so everything lines up
    set l [expr {max([string length $min], [string length $max])}]
    # Print out the table
    for {set i $min} {$i <= $max} {incr i} {
	if {![dict exist $tbl $i]} {
	    puts [format " %*d |"    $l $i]
	} else {
	    puts [format " %*d | %s" $l $i [dict get $tbl $i]]
	}
    }
}

# Assemble the parts into a full stem-and-leaf table printer.
proc printStemLeaf {dataList {splitFactor 10}} {
    foreach value [lsort -real $dataList] {
	addSLValue tbl $value $splitFactor
    }
    printSLTable tbl
}

# Demo code
set data {
    12  127 28  42  39  113 42  18  44  118 44  37  113 124 37  48  127 36
    29  31  125 139 131 115 105 132 104 123 35  113 122 42  117 119 58  109
    23  105 63  27  44  105 99  41  128 121 116 125 32  61  37  127 29  113
    121 58  114 126 53  114 96  25  109 7   31  141 46  13  27  43  117 116
    27  7   68  40  31  115 124 42  128 52  71  118 117 38  27  106 33  117
    116 111 40  119 47  105 57  122 109 124 115 43  120 43  27  27  18  28
    48  125 107 114 34  133 45  120 30  127 31  116 146
}
printStemLeaf $data


F stern_brocot(predicate = series -> series.len < 20)
   V sb = [1, 1]
   V i = 0
   L predicate(sb)
      sb [+]= [sum(sb[i .< i + 2]), sb[i + 1]]
      i++
   R sb

V n_first = 15
print(("The first #. values:\n  ".format(n_first))‘ ’stern_brocot(series -> series.len < :n_first)[0 .< n_first])
print()

V n_max = 10
L(n_occur) Array(1 .. n_max) [+] [100]
   print((‘1-based index of the first occurrence of #3 in the series:’.format(n_occur))‘ ’(stern_brocot(series -> @n_occur !C series).index(n_occur) + 1))
print()

V n_gcd = 1000
V s = stern_brocot(series -> series.len < :n_gcd)[0 .< n_gcd]
assert(all(zip(s, s[1..]).map((prev, this) -> gcd(prev, this) == 1)), ‘A fraction from adjacent terms is reducible’)


import Data.Foldable (foldl') --'
import System.Random (randomRs, newStdGen)
import Control.Monad (zipWithM_)
import System.Environment (getArgs)

intervals :: [(Double, Double)]
intervals = map conv [0 .. 9]
  where
    xs = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
    conv s =
      let [h, l] = take 2 $ drop s xs
      in (h, l)

count :: [Double] -> [Int]
count rands = map (\iv -> foldl'' (loop iv) 0 rands) intervals
  where
    loop :: (Double, Double) -> Int -> Double -> Int
    loop (lo, hi) n x
      | lo <= x && x < hi = n + 1
      | otherwise = n

-- ^ fuses length and filter within (lo,hi)
data Pair a b =
  Pair !a
       !b

-- accumulate sum and length in one fold
sumLen :: [Double] -> Pair Double Double
sumLen = fion2 . foldl'' (\(Pair s l) x -> Pair (s + x) (l + 1)) (Pair 0.0 0)
  where
    fion2 :: Pair Double Int -> Pair Double Double
    fion2 (Pair s l) = Pair s (fromIntegral l)

-- safe division on pairs
divl :: Pair Double Double -> Double
divl (Pair _ 0.0) = 0.0
divl (Pair s l) = s / l

-- sumLen and divl are separate for stddev below
mean :: [Double] -> Double
mean = divl . sumLen

stddev :: [Double] -> Double
stddev xs = sqrt $ foldl'' (\s x -> s + (x - m) ^ 2) 0 xs / l
  where
    p@(Pair s l) = sumLen xs
    m = divl p

main = do
  nr <- read . head <$> getArgs
  -- or in code, e.g.  let nr = 1000
  rands <- take nr . randomRs (0.0, 1.0) <$> newStdGen
  putStrLn $ "The mean is " ++ show (mean rands) ++ " !"
  putStrLn $ "The standard deviation is " ++ show (stddev rands) ++ " !"
  zipWithM_
    (\iv fq -> putStrLn $ ivstr iv ++ ": " ++ fqstr fq)
    intervals
    (count rands)
  where
    fqstr i =
      replicate
        (if i > 50
           then div i (div i 50)
           else i)
        '*'
    ivstr (lo, hi) = show lo ++ " - " ++ show hi

-- To avoid Wiki formatting issue
foldl'' = foldl'


*        Stern-Brocot sequence     - 12/03/2019
STERNBR  CSECT
         USING  STERNBR,R13        base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         SAVE   (14,12)            save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         LA     R4,SB+2            k=2; @sb(k)
         LA     R2,SB+2            i=1; @sb(k-i)
         LA     R3,SB+0            j=2; @sb(k-j)
         LA     R1,NN/2            loop counter
LOOP     LA     R4,2(R4)             @sb(k)++
         LH     R0,0(R2)             sb(k-i)
         AH     R0,0(R3)             sb(k-i)+sb(k-j)
         STH    R0,0(R4)             sb(k)=sb(k-i)+sb(k-j)
         LA     R3,2(R3)             @sb(k-j)++
         LA     R4,2(R4)             @sb(k)++
         LH     R0,0(R3)             sb(k-j)
         STH    R0,0(R4)             sb(k)=sb(k-j)
         LA     R2,2(R2)             @sb(k-i)++
         BCT    R1,LOOP            end loop
         LA     R9,15              n=15
         MVC    PG(5),=CL80'FIRST'
         XDECO  R9,XDEC            edit n
         MVC    PG+5(3),XDEC+9     output n
         XPRNT  PG,L'PG            print buffer
         LA     R10,PG             @pg
         LA     R6,1               i=1
       DO WHILE=(CR,R6,LE,R9)      do i=1 to n
         LR     R1,R6                i
         SLA    R1,1                 ~
         LH     R2,SB-2(R1)          sb(i)
         XDECO  R2,XDEC              edit sb(i)
         MVC    0(4,R10),XDEC+8      output sb(i)
         LA     R10,4(R10)           @pg+=4
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         XPRNT  PG,L'PG            print buffer
        LA     R7,1                j=1
       DO WHILE=(C,R7,LE,=A(11))   do j=1 to 11
       IF C,R7,EQ,=F'11' THEN        if j=11 then
         LA     R7,100                 j=100
       ENDIF    ,                    endif
         LA     R6,1                 i=1
       DO WHILE=(C,R6,LE,=A(NN))     do i=1 to nn
         LR     R1,R6                  i
         SLA    R1,1                   ~
         LH     R2,SB-2(R1)            sb(i)
         CR     R2,R7                  if sb(i)=j
         BE     EXITI                  then leave i
         LA     R6,1(R6)               i++
       ENDDO    ,                    enddo i
EXITI    MVC    PG,=CL80'FIRST INSTANCE OF'
         XDECO  R7,XDEC              edit j
         MVC    PG+17(4),XDEC+8      output j
         MVC    PG+21(7),=C' IS AT '
         XDECO  R6,XDEC              edit i
         MVC    PG+28(4),XDEC+8      output i
         XPRNT  PG,L'PG              print buffer
         LA     R7,1(R7)             j++
       ENDDO    ,                  enddo j
         L      R13,4(0,R13)       restore previous savearea pointer
         RETURN (14,12),RC=0       restore registers from calling sav
         LTORG
NN       EQU    2400               nn
PG       DC     CL80' '            buffer
XDEC     DS     CL12               temp for xdeco
SB       DC     (NN)H'1'           sb(nn)
         REGEQU
         END    STERNBR


puts:	equ	9	; CP/M syscall to print a string
	org	100h
	;;;	Generate the first 1200 elements of the Stern-Brocot sequence
	lxi	b,600	; 2 elements generated per loop
	lxi	h,seq
	mov	e,m	; Initialization
	inx	h
	push	h	; Save considered member pointer
	inx	h	; Insertion pointer
genseq:	xthl		; Load considered member pointer
	mov	d,e	; D = predecessor
	mov	e,m	; E = considered member
	inx	h	; Point at next considered member
	xthl		; Load insertion pointer
	mov	a,d	; A = sum of both members
	add	e
	mov	m,a	; Append the sum
	inx	h
	mov	m,e	; Append the considered member
	inx	h
	dcx 	b	; Decrement counter
	mov	a,b	; Zero?
	ora	c
	jnz	genseq	; If not, generate next members of sequence
	pop	h	; Remove pointer from stack
	;;;	Print first 15 members of sequence
	lxi	d,seq
	mvi	b,15	; 15 members
	mvi	h,0
p15:	ldax	d	; Get current member
	mov	l,a
	call	prhl	; Print member
	inx	d	; Increment pointer
	dcr	b	; Decrement counter
	jnz	p15	; If not zero, print another one
	lxi	d,nl
	mvi	c,puts
	call	5
	;;;	Print indices of first occurrence of 1..10
	lxi	b,010Ah	; B = number, C = counter
	call	fnext
	;;;	Print index of first occurrence of 100
	lxi	b,6401h
	call	fnext
	;;;	Check if the GCD of first 1000 consecutive elements is 0
	xra	a	; Zero out 1001th element as end marker
	sta	seq+1000
	lxi	h,seq	; Start of array
	mov	e,m
	inx	h
gcdchk:	mov	d,e	; (D,E) = next pair
	mov	e,m
	inx	h
	mov	a,e
	mov	b,d
	ana	a	; Reached the end?
	jz	done
	call	gcd	; If not, check GCD
	dcr	a	; Check that it is 1
	jz	gcdchk	; If so, check next pair
	push	h	; GCD not 1 - save pointer
	lxi	d,gcdn	; Print message
	mvi	c,puts
	call	5
	pop	h	; Calculate offset in array
	lxi	d,-seq
	dad	d
	jmp	prhl	; Print offset of pair whose GCD is not 1
done:	lxi	d,gcdy	; Print OK message
	mvi	c,puts
	jmp	5
	;;;	GCD(A,B)
gcd:	cmp	b
	rz		; If A=B, result = A
	jc	b_le_a	; B>A?
	sub	b	; If A>B, subtract B
	jmp 	gcd	; and loop
b_le_a:	mov	c,a
	mov	a,b
	sub	c
	mov	b,a
	mov	a,c
	jmp	gcd
	;;;	Print indices of occurrences of C numbers
	;;;	starting at B
fnext:	lxi	d,seq
fsrch:	ldax	d	; Get current member
	cmp	b	; Is it the number we are looking for?
	inx	d	; Increment number
	jnz	fsrch	; If no match, check next number
	lxi	h,-seq	; Match - subtract start of array
	dad	d
	call	prhl	; Print index
	inr	b	; Look for next number
	dcr	c	; If we need more numbers
	jnz	fnext
	push	d	; Save sequence pointer
	lxi	d,nl	; Print newline
	mvi	c,puts
	call	5
	pop	d	; Restore sequence pointer
	ret
	;;;	Print HL as ASCII number.
prhl:	push	h	; Save all registers
	push	d
	push	b
	lxi	b,pnum	; Store pointer to num string on stack
	push	b
	lxi	b,-10	; Divisor
prdgt:	lxi	d,-1
prdgtl:	inx	d	; Divide by 10 through trial subtraction
	dad	b
	jc	prdgtl
	mvi	a,'0'+10
	add	l	; L = remainder - 10
	pop	h	; Get pointer from stack
	dcx	h	; Store digit
	mov	m,a
	push	h	; Put pointer back on stack
	xchg		; Put quotient in HL
	mov	a,h	; Check if zero
	ora	l
	jnz	prdgt	; If not, next digit
	pop	d	; Get pointer and put in DE
	mvi	c,9	; CP/M print string
	call	5
	pop	b	; Restore registers
	pop	d
	pop	h
	ret
	db	'*****'	; Placeholder for number
pnum:	db	' $'
nl:	db	13,10,'$'
gcdn:	db	'GCD not 1 at: $'
gcdy:	db	'GCD of all pairs of consecutive members is 1.$'
seq:	db	1,1	; Sequence stored here


(import
  [numpy.random [random]]
  [numpy [mean std]]
  [matplotlib.pyplot :as plt])

(for [n [100 1000 10000]]
  (setv v (random n))
  (print "Mean:" (mean v) "SD:" (std v)))

(plt.hist (random 1000))
(plt.show)


procedure main(A)

W := 50                         # avg width for histogram bar
B := 10                         # histogram bins
if *A = 0 then put(A,100)       # 100 if none specified

while N := get(A) do {          # once per argument
   write("\nN=",N)

   N := 0 < integer(N) | next   # skip if invalid

   stddev() # reset
   m := 0.
   H := list(B,0)               # Histogram of
   every i := 1 to N do {       # calc running ...
      s := stddev(r := ?0)      # ... std dev
      m +:= r/N                 # ... mean
      H[integer(*H*r)+1] +:= 1  # ... histogram
      }

   write("mean=",m)
   write("stddev=",s)
   every i := 1 to *H do        # show histogram
      write(right(real(i)/*H,5)," : ",repl("*",integer(*H*50./N*H[i])))
   }
end


puts:	equ	9
	cpu	8086
	bits	16
	org	100h
section	.text
	;;;	Generate the first 1200 elemets of the Stern-Brocot sequence
	mov	cx,600	; 2 elements generated per loop
	mov	si,seq
	mov	di,seq+2
	lodsb
	mov	ah,al	; AH = predecessor
genseq:	lodsb		; AL = considered member
	add	ah,al	; AH = sum
	xchg	ah,al	; Swap them (AL = sum, AH = member)
	stosw		; Write sum and current considered member
	loop	genseq	; Loop 600 times
	;;;	Print first 15 members of sequence
	mov	si,seq
	mov	cx,15
p15:	lodsb		; Get member
	cbw
	call	prax 	; Print member
	loop	p15
	call	prnl
	;;;	Print first occurrences of [1..10]
	mov	al,1
	mov	cx,10
	call	find
	call	prnl
	;;;	Print first occurrence of 100
	mov	al,100
	mov	cx,1
	call	find
	call	prnl
	;;;	Check pairs of GCDs
	mov	cx,1000	; 1000 times
	mov	si,seq
	lodsb
gcdchk:	mov	ah,al	; AH = last member, AL = current member
	lodsb
	mov	dx,ax	; Calculate GCD
	call	gcd
	dec	dl	; See if it is 1
	jnz	.fail	; If not, failure
	loop	gcdchk	; Otherwise, check next pair
	mov	dx,gcdy	; GCD of all pairs is 0
	jmp	pstr
.fail:	mov	dx,gcdn	; GCD of current pair is not 0
	call	pstr
	mov	ax,si
	sub	ax,seq+1
	jmp	prax
	;;;	DL = gcd(DL,DH)
gcd:	cmp	dl,dh
	jl	.lt	; DL < DH
	jg	.gt	; DL > DH
	ret
.lt:	sub	dh,dl	; DL < DH
	jmp	gcd
.gt: 	sub	dl,dh	; DL > DH
	jmp	gcd
	;;;	Print indices of CX consecutive numbers starting
	;;;	at AL.
find:	mov	di,seq
	push	cx	; Keep loop counter
	mov	cx,-1
	repne	scasb	; Find AL starting at [DI]
	pop	cx	; Restore loop counter
	xchg	si,ax	; Keep AL in SI
	mov	ax,di	; Calculate index in sequence
	sub	ax,seq
	call	prax	; Output
	xchg	si,ax	; Restore AL
	inc	ax	; Increment
	loop 	find	; Keep going CX times
	ret
	;;;	Print newline
prnl:	mov	dx,nl
	jmp	pstr
	;;;	Print number in AX
	;;;	Destroys AX, BX, DX, BP
prax:	mov	bp,10	; Divisor
	mov	bx,numbuf
.loop:	xor	dx,dx	; DX = 0
	div	bp	; Divide DX:AX by 10; DX = remainder
	dec	bx	; Move string pointer back
	add	dl,'0'	; Make ASCII digit
	mov	[bx],dl	; Write digit
	test	ax,ax	; Any digits left?
	jnz	.loop
	mov	dx,bx
pstr:	mov	ah,puts	; Print number string
	int	21h
	ret
section	.data
gcdn:	db	'GCD not 1 at: $'
gcdy:	db	'GCD of all pairs of consecutive members is 1.$'
	db	'*****'
numbuf:	db	' $'
nl:	db	13,10,'$'
seq:	db	1,1


   require 'stats'
   (mean,stddev) 1000 [email protected]$ 0
0.484669 0.287482
   (mean,stddev) 10000 [email protected]$ 0
0.503642 0.290777
   (mean,stddev) 100000 [email protected]$ 0
0.499677 0.288726


import static java.lang.Math.pow;
import static java.util.Arrays.stream;
import static java.util.stream.Collectors.joining;
import static java.util.stream.IntStream.range;

public class Test {
    static double[] meanStdDev(double[] numbers) {
        if (numbers.length == 0)
            return new double[]{0.0, 0.0};

        double sx = 0.0, sxx = 0.0;
        long n = 0;
        for (double x : numbers) {
            sx += x;
            sxx += pow(x, 2);
            n++;
        }
        return new double[]{sx / n, pow((n * sxx - pow(sx, 2)), 0.5) / n};
    }

    static String replicate(int n, String s) {
        return range(0, n + 1).mapToObj(i -> s).collect(joining());
    }

    static void showHistogram01(double[] numbers) {
        final int maxWidth = 50;
        long[] bins = new long[10];

        for (double x : numbers)
            bins[(int) (x * bins.length)]++;

        double maxFreq = stream(bins).max().getAsLong();

        for (int i = 0; i < bins.length; i++)
            System.out.printf(" %3.1f: %s%n", i / (double) bins.length,
                    replicate((int) (bins[i] / maxFreq * maxWidth), "*"));
        System.out.println();
    }

    public static void main(String[] a) {
        Locale.setDefault(Locale.US);
        for (int p = 1; p < 7; p++) {
            double[] n = range(0, (int) pow(10, p))
                    .mapToDouble(i -> Math.random()).toArray();

            System.out.println((int)pow(10, p) + " numbers:");
            double[] res = meanStdDev(n);
            System.out.printf(" Mean: %8.6f, SD: %8.6f%n", res[0], res[1]);
            showHistogram01(n);
        }
    }
}


PROC Generate(BYTE ARRAY seq INT POINTER count INT minCount,maxVal)
  INT i

  seq(0)=1 seq(1)=1 count^=2 i=1
  WHILE count^<minCount OR seq(count^-1)#maxVal AND seq(count^-2)#maxVal
  DO
    seq(count^)=seq(i-1)+seq(i)
    seq(count^+1)=seq(i)
    count^==+2 i==+1
  OD
RETURN

PROC PrintSeq(BYTE ARRAY seq INT count)
  INT i

  PrintF("First %I items:%E",count)
  FOR i=0 TO count-1
  DO
    PrintB(seq(i)) Put(32)
  OD
  PutE() PutE()
RETURN

PROC PrintLoc(BYTE ARRAY seq INT seqCount
  BYTE ARRAY loc INT locCount)
  INT i,j
  BYTE value

  FOR i=0 TO locCount-1
  DO
    j=0 value=loc(i)
    WHILE seq(j)#value
    DO
      j==+1
    OD
    PrintF("%B appears at position %I%E",value,j+1)
  OD
  PutE()
RETURN

BYTE FUNC Gcd(BYTE a,b)
  BYTE tmp

  IF a<b THEN
    tmp=a a=b b=tmp
  FI

  WHILE b#0
  DO
    tmp=a MOD b
    a=b b=tmp
  OD
RETURN (a)

PROC PrintGcd(BYTE ARRAY seq INT count)
  INT i

  FOR i=0 TO count-2
  DO
    IF Gcd(seq(i),seq(i+1))>1 THEN
      PrintF("GCD between %I and %I item is greater than 1",i+1,i+2)
      RETURN
    FI
  OD
  Print("GCD between all two consecutive items of the sequence is equal 1")
RETURN

PROC Main()
  BYTE ARRAY seq(2000),loc=[1 2 3 4 5 6 7 8 9 10 100]
  INT count

  Generate(seq,@count,1000,100)
  PrintSeq(seq,15)
  PrintLoc(seq,count,loc,11)
  PrintGcd(seq,1000)
RETURN


with Ada.Text_IO, Ada.Containers.Vectors;

procedure Sequence is

   package Vectors is new
     Ada.Containers.Vectors(Index_Type => Positive, Element_Type => Positive);
   use type Vectors.Vector;

   type Sequence is record
      List: Vectors.Vector;
      Index: Positive;
      -- This implements some form of "lazy evaluation":
      --  + List holds the elements computed, so far, it is extended
      --    if the user tries to "Get" an element not yet computed;
      --  + Index is the location of the next element under consideration
   end record;

   function Initialize return Sequence is
      (List => (Vectors.Empty_Vector & 1 & 1), Index => 2);

   function Get(Seq: in out Sequence; Location: Positive) return Positive is
      -- returns the Location'th element of the sequence
      -- extends Seq.List (and then increases Seq.Index) if neccessary
      That: Positive := Seq.List.Element(Seq.Index);
      This: Positive := That + Seq.List.Element(Seq.Index-1);
   begin
      while Seq.List.Last_Index < Location loop
	 Seq.List := Seq.List & This & That;
	 Seq.Index := Seq.Index + 1;
      end loop;
      return Seq.List.Element(Location);
   end Get;

   S: Sequence := Initialize;
   J: Positive;

   use Ada.Text_IO;

begin
   -- show first fifteen members
   Put("First 15:");
   for I in 1 .. 15 loop
      Put(Integer'Image(Get(S, I)));
   end loop;
   New_Line;

   -- show the index where 1, 2, 3, ... first appear in the sequence
   for I in 1 .. 10 loop
      J := 1;
      while Get(S, J) /= I loop
	 J := J + 1;
      end loop;
      Put("First" & Integer'Image(I) & " at" & Integer'Image(J) & ";  ");
      if I mod 4 = 0 then
	 New_Line; -- otherwise, the output gets a bit too ugly
      end if;
   end loop;

   -- show the index where 100 first appears in the sequence
   J := 1;
   while Get(S, J) /= 100 loop
      J := J + 1;
   end loop;
   Put_Line("First 100 at" & Integer'Image(J) & ".");

   -- check GCDs
   declare
      function GCD (A, B : Integer) return Integer is
	 M : Integer := A;
	 N : Integer := B;
	 T : Integer;
      begin
	 while N /= 0 loop
	    T := M;
	    M := N;
	    N := T mod N;
	 end loop;
	 return M;
      end GCD;

      A, B: Positive;
   begin
      for I in 1 .. 999 loop
	 A := Get(S, I);
	 B := Get(S, I+1);
	 if GCD(A, B) /= 1 then
	    raise Constraint_Error;
	 end if;
      end loop;
      Put_Line("Correct: The first 999 consecutive pairs are relative prime!");
   exception
      when Constraint_Error => Put_Line("Some GCD > 1; this is wrong!!!") ;
   end;
end Sequence;


# Usage: prng N width
function prng {
  cat /dev/urandom | tr -cd '0-9' | fold -w "$2" | head -n "$1"
}


#!/usr/bin/env jsish
"use strict";

function statisticsBasic(args:array|string=void, conf:object=void) {
    var options = { // Rosetta Code, Statistics/Basic
        rootdir      :'',      // Root directory.
        samples      : 0       // Set sample size from options
    };
    var self = { };
    parseOpts(self, options, conf);

    function generateStats(n:number):object {
        var i, sum = 0, sum2 = 0;
        var hist = new Array(10);
        hist.fill(0);
        for (i = 0; i < n; i++) {
            var r = Math.random();
            sum += r;
            sum2 += r*r;
            hist[Math.floor((r*10))] += 1;
        }
        var mean = sum/n;
        var stddev = Math.sqrt((sum2 / n) - mean*mean);
        var obj = {n:n, sum:sum, mean:mean, stddev:stddev};
        return {n:n, sum:sum, mean:mean, stddev:stddev, hist:hist};
    }

    function reportStats(summary:object):void {
        printf("Samples: %d, mean: %f, stddev: %f\n", summary.n, summary.mean, summary.stddev);
        var max = Math.max.apply(summary, summary.hist);
        for (var i = 0; i < 10; i++) {
            printf("%3.1f+ %-70s %5d\n", i * 0.1, 'X'.repeat(70 * summary.hist[i] / max), summary.hist[i]);
        }
        return;
    }

    function main() {
        LogTest('Starting', args);
        switch (typeof(args)) {
            case 'string': args = [args]; break;
            case 'array': break;
            default: args = [];
        }
        if (self.rootdir === '')
            self.rootdir=Info.scriptDir();

        Math.srand(0);
        if (self.samples > 0) reportStats(generateStats(self.samples));
        else if (args[0] && parseInt(args[0])) reportStats(generateStats(parseInt(args[0])));
        else for (var n of [100, 1000, 10000]) reportStats(generateStats(n));

        debugger;
        LogDebug('Done');
        return 0;
    }

    return main();
}

provide(statisticsBasic, 1);

if (isMain()) {
    if (!Interp.conf('unitTest'))
        return runModule(statisticsBasic);

;'  statisticsBasic unit-test';
;   statisticsBasic();

}

/*
=!EXPECTSTART!=
'  statisticsBasic unit-test'
statisticsBasic() ==> Samples: 100, mean: 0.534517, stddev: 0.287124
0.0+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                                        8
0.1+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                          11
0.2+ XXXXXXXXXXXXXXXXXXXXXXXXXX                                                 6
0.3+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                               10
0.4+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                               10
0.5+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                          11
0.6+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                                        8
0.7+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX    16
0.8+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                                             7
0.9+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                  13
Samples: 1000, mean: 0.490335, stddev: 0.286562
0.0+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                  98
0.1+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX   122
0.2+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                          85
0.3+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX             106
0.4+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX             105
0.5+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                101
0.6+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                     93
0.7+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX             106
0.8+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                  98
0.9+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX                         86
Samples: 10000, mean: 0.499492, stddev: 0.287689
0.0+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX          969
0.1+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX        992
0.2+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX  1067
0.3+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX      1011
0.4+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX          973
0.5+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX     1031
0.6+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX          971
0.7+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX        999
0.8+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX        991
0.9+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX        996
0
=!EXPECTEND!=
*/


BEGIN # find members of the Stern-Brocot sequence: starting from 1, 1 the     #
      # subsequent members are the previous two members summed followed by    #
      # the previous                                                          #
    # iterative Greatest Common Divisor routine, returns the gcd of m and n   #
    PROC gcd = ( INT m, n )INT:
         BEGIN
            INT a := ABS m, b := ABS n;
            WHILE b /= 0 DO
                INT new a = b;
                b        := a MOD b;
                a        := new a
            OD;
            a
         END # gcd # ;
    # returns an array of the Stern-Brocot sequence up to n                   #
    OP   STERNBROCOT = ( INT n )[]INT:
         BEGIN
            [ 1 : IF ODD n THEN n + 1 ELSE n FI ]INT result;
            IF n > 0 THEN
                result[ 1 ]  := result[ 2 ] := 1;
                INT next pos := 2;
                FOR i FROM 3 WHILE next pos < n DO
                    INT p1 = result[ i - 1 ];
                    result[ next pos +:= 1 ] := p1 + result[ i - 2 ];
                    result[ next pos +:= 1 ] := p1
                OD
            FI;
            result[ 1 : n ]
         END # STERNPROCOT # ;
    FLEX[ 1 : 0 ]INT sb := STERNBROCOT 1000; # start with 1000 elements        #
                              # if that isn't enough, more will be added later #
    # show the first 15 elements of the sequence                               #
    print( ( "The first 15 elements of the Stern-Brocot sequence are:", newline ) );
    FOR i TO 15 DO
        print( ( whole( sb[ i ], -3 ) ) )
    OD;
    print( ( newline, newline ) );
    # find where the numbers 1-10 first appear                                 #
    INT found 10 := 0;
    [ 10 ]INT pos 10; FOR i TO UPB pos 10 DO pos 10[ i ] := 0 OD;
    FOR i TO UPB sb WHILE found 10 < 10 DO
        INT sb i = sb[ i ];
        IF sb i <= UPB pos 10 THEN
            IF pos 10[ sb i ] = 0 THEN
                # first occurance of this number                               #
                pos 10[ sb i ] := i;
                found 10      +:= 1
            FI
        FI
    OD;
    print( ( "The first positions of 1..", whole( UPB pos 10, 0 ), " in the sequence are:", newline ) );
    FOR i TO UPB pos 10 DO
        print( ( whole( i, -2 ), ":", whole( pos 10[ i ], 0 ), " " ) )
    OD;
    print( ( newline, newline ) );
    # find where the number 100 first appears                                  #
    BOOL found 100 := FALSE;
    FOR i WHILE NOT found 100 DO
        IF i > UPB sb THEN
            # need more elements                                               #
            sb := STERNBROCOT ( UPB sb * 2 )
        FI;
        IF sb[ i ] = 100 THEN
            print( ( "100 first appears at position ", whole( i, 0 ), newline, newline ) );
            found 100 := TRUE
        FI
    OD;
    # check that the pairs of elements up to 1000 are coprime                  #
    BOOL all coprime := TRUE;
    FOR i FROM 2 TO 1000 WHILE all coprime DO
        all coprime := gcd( sb[ i ], sb[ i - 1 ] ) = 1
    OD;
    print( ( "Element pairs up to 1000 are ", IF all coprime THEN "" ELSE "NOT " FI, "coprime", newline ) )
END


using Printf

function hist(numbers)
    maxwidth = 50
    h = fill(0, 10)
    for n in numbers
        h[ceil(Int, 10n)] += 1
    end
    mx = maximum(h)
    for (n, i) in enumerate(h)
        @printf("%3.1f: %s\n", n / 10, "+" ^ floor(Int, i / mx * maxwidth))
    end
end

for i in 1:6
    n = rand(10 ^ i)
    println("\n##\n## $(10 ^ i) numbers")
    @printf("μ: %8.6f; σ: %8.6f\n", mean(n), std(n))
    hist(n)
end


// version 1.1.2

val rand = java.util.Random()

fun basicStats(sampleSize: Int) {
    if (sampleSize < 1) return
    val r = DoubleArray(sampleSize)
    val h = IntArray(10) // all zero by default
    /*
       Generate 'sampleSize' random numbers in the interval [0, 1)
       and calculate in which box they will fall when drawing the histogram
    */
    for (i in 0 until sampleSize) {
        r[i] = rand.nextDouble()
        h[(r[i] * 10).toInt()]++
    }

    // adjust one of the h[] values if necessary to ensure they sum to sampleSize
    val adj = sampleSize - h.sum()
    if (adj != 0) {
        for (i in 0..9) {
            h[i] += adj
            if (h[i] >= 0) break
            h[i] -= adj
        }
    }

    val mean = r.average()
    val sd = Math.sqrt(r.map { (it - mean) * (it - mean) }.average())

    // Draw a histogram of the data with interval 0.1
    var numStars: Int
    // If sample size > 500 then normalize histogram to 500
    val scale = if (sampleSize <= 500) 1.0 else 500.0 / sampleSize
    println("Sample size $sampleSize\n")
    println("  Mean ${"%1.6f".format(mean)}  SD ${"%1.6f".format(sd)}\n")
    for (i in 0..9) {
        print("  %1.2f : ".format(i / 10.0))
        print("%5d ".format(h[i]))
        numStars = (h[i] * scale + 0.5).toInt()
        println("*".repeat(numStars))
    }
    println()
}

fun main(args: Array<String>) {
    val sampleSizes = intArrayOf(100, 1_000, 10_000, 100_000)
    for (sampleSize in sampleSizes) basicStats(sampleSize)
}


begin
integer array S[1:1200];
integer i,ok;

integer function gcd(a,b);
integer a,b;
gcd :=
    if a>b then gcd(a-b,b)
    else if a<b then gcd(a,b-a)
    else a;

integer function first(n);
integer n;
begin
    integer i;
    i := 1;
    while S[i]<>n do i := i + 1;
    first := i;
end;

S[1] := S[2] := 1;
for i := 2 step 1 until 600 do
begin
    S[i*2-1] := S[i] + S[i-1];
    S[i*2] := S[i];
end;

write("First 15 numbers:");
for i := 1 step 1 until 15 do
begin
    if i-i/5*5=1 then write(S[i]) else writeon(S[i]);
end;

write("");
write("First occurrence:");
for i := 1 step 1 until 10 do write(i, " at", first(i));
write(100, " at", first(100));

ok := 1;
for i := 1 step 1 until 999 do
begin
    if gcd(S[i], S[i+1]) <> 1 then
    begin
        write("gcd",S[i],",",S[i+1],"<> 1");
        ok := 0;
    end;
end;
if ok = 1 then write("The GCD of each pair of consecutive members is 1.");
end


#include <flow.h>
#include <flow-flow.h>

DEF-MAIN(argv,argc)
   CLR-SCR
   SET( amount, 1200 )
   DIM(amount) AS-ONES( Stern )

  /* Generate Stern-Brocot sequence: */
   GOSUB( Generate Sequence )
   PRNL( "Find 15 first: ", [1:19] CGET(Stern) )

  /* show Stern-Brocot sequence: */
   SET( i, 1 ), ITERATE( ++i, LE?(i,10), \
                         PRN( "First ",i," at "), {i} GOSUB( Find First ), PRNL )
   PRN( "First 100 at "), {100} GOSUB( Find First ), PRNL

  /* check GCD: */
   ODD-POS, CGET(Stern), EVEN-POS, CGET(Stern), COMP-GCD, GET-SUMMATORY, DIV-INTO( DIV(amount,2) )

   IF ( IS-EQ?(1), PRNL("The GCD of every pair of adjacent elements is 1"),\
                   PRNL("Stern-Brocot Sequence is wrong!") )
END

RUTINES

DEF-FUN(Find First, n )
RET ( SCAN(1, n, Stern) )

DEF-FUN(Generate Sequence)
   SET(i,2)
   FOR( LE?(i, DIV(amount,2)), ++i )
      [i] GET( Stern ), [ MINUS-ONE(i) ] GET( Stern ), ADD-IT
      [ SUB(MUL(i,2),1) ] CPUT( Stern )
      [i] GET( Stern ), [MUL(i,2)] CPUT( Stern )
   NEXT
RET


define stat1(a) => {
	if(#a->size) => {
		local(mean = (with n in #a sum #n) / #a->size)
		local(sdev = math_pow(((with n in #a sum Math_Pow((#n - #mean),2)) / #a->size),0.5))
		return (:#sdev, #mean)
	else
		return (:0,0)
	}
}
define stat2(a) => {
	if(#a->size) => {
		local(sx = 0, sxx = 0)
		with x in #a do => {
			#sx += #x
			#sxx += #x*#x
		}
		local(sdev = math_pow((#a->size * #sxx - #sx * #sx),0.5) / #a->size)
		return (:#sdev, #sx / #a->size)
	else
		return (:0,0)
	}
}
define histogram(a) => {
	local(
		out = '\r',
		h = array(0,0,0,0,0,0,0,0,0,0,0),
		maxwidth = 50,
		sc = 0
	)
	with n in #a do => {
		#h->get(integer(#n*10)+1) += 1
	}
	local(mx = decimal(with n in #h max #n))
	with i in #h do => {
		#out->append((#sc/10.0)->asString(-precision=1)+': '+('+' * integer(#i / #mx * #maxwidth))+'\r')
		#sc++
	}
	return #out
}

with scale in array(100,1000,10000,100000) do => {^
	local(n = array)
	loop(#scale) => { #n->insert(decimal_random) }
	local(sdev1,mean1) = stat1(#n)
	local(sdev2,mean2) = stat2(#n)
	#scale' numbers:\r'
    'Naive  method: sd: '+#sdev1+', mean: '+#mean1+'\r'
    'Second  method: sd: '+#sdev2+', mean: '+#mean2+'\r'
    histogram(#n)
    '\r\r'
^}


call sample    100
call sample   1000
call sample  10000

end

sub sample n
    dim dat( n)
    for i =1 to n
        dat( i) =rnd( 1)
    next i

    '// show mean, standard deviation
    sum =0
    sSq =0
    for i =1 to n
        sum =sum +dat( i)
        sSq =sSq +dat( i)^2
    next i
    print n; " data terms used."

    mean =sum / n
    print "Mean ="; mean

    print "Stddev ="; ( sSq /n -mean^2)^0.5

    '// show histogram
    nBins =10
    dim bins( nBins)
    for i =1 to n
        z =int( nBins *dat( i))
        bins( z) =bins( z) +1
    next i
    for b =0 to nBins -1
        for j =1 to int( nBins *bins( b)) /n *70)
            print "#";
        next j
        print
    next b
    print
end sub


math.randomseed(os.time())

function randList (n)  -- Build table of size n
	local numbers = {}
	for i = 1, n do
		table.insert(numbers, math.random()) -- range correct by default
	end
	return numbers
end

function mean (t)  -- Find mean average of values in table t
	local sum = 0
	for k, v in pairs(t) do
		sum = sum + v
	end
	return sum / #t
end

function stdDev (t)  -- Find population standard deviation of table t
	local squares, avg = 0, mean(t)
	for k, v in pairs(t) do
		squares = squares + ((avg - v) ^ 2)
	end
	local variance = squares / #t
	return math.sqrt(variance)
end

function showHistogram (t)  -- Draw histogram of given table to stdout
	local histBars, compVal = {}
	for range = 0, 9 do
		histBars[range] = 0
		for k, v in pairs(t) do
			compVal = tonumber(string.format("%0.1f", v - 0.05))
			if compVal == range / 10 then
				histBars[range] = histBars[range] + 1
			end
		end
	end
	for k, v in pairs(histBars) do
		io.write("0." .. k .. " " .. string.rep('=', v / #t * 200))
		print(" " .. v)
	end
	print()
end

function showStats (tabSize)  -- Create and display statistics info
	local numList = randList(tabSize)
	print("Table of size " .. #numList)
	print("Mean average: " .. mean(numList))
	print("Standard dev: " .. stdDev(numList))
	showHistogram(numList)
end

for power = 2, 5 do  -- Start of main procedure
	showStats(10 ^ power)
end


task←{
   stern←{⍵{
      ⍺←0 ⋄ ⍺⍺≤⍴⍵:⍺⍺↑⍵
      (⍺+1)∇⍵,(+/,2⊃⊣)2↑⍺↓⍵
   }1 1}
   seq←stern 1200 ⍝ Cache 1200 elements
   ⎕←'First 15 elements:',15↑seq
   ⎕←'Locations of 1..10:',seq⍳⍳10
   ⎕←'Location of 100:',seq⍳100
   ⎕←'All GCDs 1:','no' 'yes'[1+1∧.=2∨/1000↑seq]
}