use AppleScript version "2.4"
use framework "Foundation"
use scripting additions

------------------ STERN-BROCOT SEQUENCE -----------------

-- sternBrocot :: Generator [Int]
on sternBrocot()
    script go
        on |λ|(xs)
            set x to snd(xs)
            tail(xs) & {fst(xs) + x, x}
        end |λ|
    end script
    fmapGen(my head, iterate(go, {1, 1}))
end sternBrocot

--------------------------- TEST -------------------------
on run
    set sbs to take(1200, sternBrocot())
    set ixSB to zip(sbs, enumFrom(1))

    script low
        on |λ|(x)
            12 ≠ fst(x)
        end |λ|
    end script

    script sameFst
        on |λ|(a, b)
            fst(a) = fst(b)
        end |λ|
    end script

    script asList
        on |λ|(x)
            {fst(x), snd(x)}
        end |λ|
    end script

    script below100
        on |λ|(x)
            100 ≠ fst(x)
        end |λ|
    end script

    script fullyReduced
        on |λ|(ab)
            1 = gcd(|1| of ab, |2| of ab)
        end |λ|
    end script

    unlines(map(showJSON, ¬
        {take(15, sbs), ¬
            take(10, map(asList, ¬
                nubBy(sameFst, ¬
                    sortBy(comparing(fst), ¬
                        takeWhile(low, ixSB))))), ¬
            asList's |λ|(fst(take(1, dropWhile(below100, ixSB)))), ¬
            all(fullyReduced, take(1000, zip(sbs, tail(sbs))))}))
end run

--> [1,1,2,1,3,2,3,1,4,3,5,2,5,3,4]
--> [[1,32],[2,24],[3,40],[4,36],[5,44],[6,33],[7,38],[8,42],[9,35],[10,39]]
--> [100,1179]
--> true

------------------------- GENERIC ------------------------

-- Absolute value.
-- abs :: Num -> Num
on abs(x)
    if 0 > x then
        -x
    else
        x
    end if
end abs

-- Applied to a predicate and a list, `all` determines if all elements
-- of the list satisfy the predicate.
-- all :: (a -> Bool) -> [a] -> Bool
on all(p, xs)
    tell mReturn(p)
        set lng to length of xs
        repeat with i from 1 to lng
            if not |λ|(item i of xs, i, xs) then return false
        end repeat
        true
    end tell
end all

-- comparing :: (a -> b) -> (a -> a -> Ordering)
on comparing(f)
    script
        on |λ|(a, b)
            tell mReturn(f)
                set fa to |λ|(a)
                set fb to |λ|(b)
                if fa < fb then
                    -1
                else if fa > fb then
                    1
                else
                    0
                end if
            end tell
        end |λ|
    end script
end comparing

-- drop :: Int -> [a] -> [a]
-- drop :: Int -> String -> String
on drop(n, xs)
    set c to class of xs
    if c is not script then
        if c is not string then
            if n < length of xs then
                items (1 + n) thru -1 of xs
            else
                {}
            end if
        else
            if n < length of xs then
                text (1 + n) thru -1 of xs
            else
                ""
            end if
        end if
    else
        take(n, xs) -- consumed
        return xs
    end if
end drop

-- dropWhile :: (a -> Bool) -> [a] -> [a]
-- dropWhile :: (Char -> Bool) -> String -> String
on dropWhile(p, xs)
    set lng to length of xs
    set i to 1
    tell mReturn(p)
        repeat while i ≤ lng and |λ|(item i of xs)
            set i to i + 1
        end repeat
    end tell
    drop(i - 1, xs)
end dropWhile

-- enumFrom :: a -> [a]
on enumFrom(x)
    script
        property v : missing value
        property blnNum : class of x is not text
        on |λ|()
            if missing value is not v then
                if blnNum then
                    set v to 1 + v
                else
                    set v to succ(v)
                end if
            else
                set v to x
            end if
            return v
        end |λ|
    end script
end enumFrom

-- filter :: (a -> Bool) -> [a] -> [a]
on filter(f, xs)
    tell mReturn(f)
        set lst to {}
        set lng to length of xs
        repeat with i from 1 to lng
            set v to item i of xs
            if |λ|(v, i, xs) then set end of lst to v
        end repeat
        return lst
    end tell
end filter

-- fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
on fmapGen(f, gen)
    script
        property g : gen
        property mf : mReturn(f)'s |λ|
        on |λ|()
            set v to g's |λ|()
            if v is missing value then
                v
            else
                mf(v)
            end if
        end |λ|
    end script
end fmapGen

-- fst :: (a, b) -> a
on fst(tpl)
    if class of tpl is record then
        |1| of tpl
    else
        item 1 of tpl
    end if
end fst

-- gcd :: Int -> Int -> Int
on gcd(a, b)
    set x to abs(a)
    set y to abs(b)
    repeat until y = 0
        if x > y then
            set x to x - y
        else
            set y to y - x
        end if
    end repeat
    return x
end gcd

-- head :: [a] -> a
on head(xs)
    if xs = {} then
        missing value
    else
        item 1 of xs
    end if
end head

-- iterate :: (a -> a) -> a -> Gen [a]
on iterate(f, x)
    script
        property v : missing value
        property g : mReturn(f)'s |λ|
        on |λ|()
            if missing value is v then
                set v to x
            else
                set v to g(v)
            end if
            return v
        end |λ|
    end script
end iterate

-- length :: [a] -> Int
on |length|(xs)
    set c to class of xs
    if list is c or string is c then
        length of xs
    else
        (2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
    end if
end |length|

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- min :: Ord a => a -> a -> a
on min(x, y)
    if y < x then
        y
    else
        x
    end if
end min

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- nubBy :: (a -> a -> Bool) -> [a] -> [a]
on nubBy(f, xs)
    set g to mReturn(f)'s |λ|

    script notEq
        property fEq : g
        on |λ|(a)
            script
                on |λ|(b)
                    not fEq(a, b)
                end |λ|
            end script
        end |λ|
    end script

    script go
        on |λ|(xs)
            if (length of xs) > 1 then
                set x to item 1 of xs
                {x} & go's |λ|(filter(notEq's |λ|(x), items 2 thru -1 of xs))
            else
                xs
            end if
        end |λ|
    end script

    go's |λ|(xs)
end nubBy

-- partition :: predicate -> List -> (Matches, nonMatches)
-- partition :: (a -> Bool) -> [a] -> ([a], [a])
on partition(f, xs)
    tell mReturn(f)
        set ys to {}
        set zs to {}
        repeat with x in xs
            set v to contents of x
            if |λ|(v) then
                set end of ys to v
            else
                set end of zs to v
            end if
        end repeat
    end tell
    Tuple(ys, zs)
end partition

-- showJSON :: a -> String
on showJSON(x)
    set c to class of x
    if (c is list) or (c is record) then
        set ca to current application
        set {json, e} to ca's NSJSONSerialization's dataWithJSONObject:x options:0 |error|:(reference)
        if json is missing value then
            e's localizedDescription() as text
        else
            (ca's NSString's alloc()'s initWithData:json encoding:(ca's NSUTF8StringEncoding)) as text
        end if
    else if c is date then
        "\"" & ((x - (time to GMT)) as «class isot» as string) & ".000Z" & "\""
    else if c is text then
        "\"" & x & "\""
    else if (c is integer or c is real) then
        x as text
    else if c is class then
        "null"
    else
        try
            x as text
        on error
            ("«" & c as text) & "»"
        end try
    end if
end showJSON

-- snd :: (a, b) -> b
on snd(tpl)
    if class of tpl is record then
        |2| of tpl
    else
        item 2 of tpl
    end if
end snd

-- Enough for small scale sorts.
-- Use instead sortOn :: Ord b => (a -> b) -> [a] -> [a]
-- which is equivalent to the more flexible sortBy(comparing(f), xs)
-- and uses a much faster ObjC NSArray sort method
-- sortBy :: (a -> a -> Ordering) -> [a] -> [a]
on sortBy(f, xs)
    if length of xs > 1 then
        set h to item 1 of xs
        set f to mReturn(f)
        script
            on |λ|(x)
                f's |λ|(x, h) ≤ 0
            end |λ|
        end script
        set lessMore to partition(result, rest of xs)
        sortBy(f, |1| of lessMore) & {h} & ¬
            sortBy(f, |2| of lessMore)
    else
        xs
    end if
end sortBy

-- tail :: [a] -> [a]
on tail(xs)
    set blnText to text is class of xs
    if blnText then
        set unit to ""
    else
        set unit to {}
    end if
    set lng to length of xs
    if 1 > lng then
        missing value
    else if 2 > lng then
        unit
    else
        if blnText then
            text 2 thru -1 of xs
        else
            rest of xs
        end if
    end if
end tail

-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
    set c to class of xs
    if list is c then
        if 0 < n then
            items 1 thru min(n, length of xs) of xs
        else
            {}
        end if
    else if string is c then
        if 0 < n then
            text 1 thru min(n, length of xs) of xs
        else
            ""
        end if
    else if script is c then
        set ys to {}
        repeat with i from 1 to n
            set v to xs's |λ|()
            if missing value is v then
                return ys
            else
                set end of ys to v
            end if
        end repeat
        return ys
    else
        missing value
    end if
end take

-- takeWhile :: (a -> Bool) -> [a] -> [a]
-- takeWhile :: (Char -> Bool) -> String -> String
on takeWhile(p, xs)
    if script is class of xs then
        takeWhileGen(p, xs)
    else
        tell mReturn(p)
            repeat with i from 1 to length of xs
                if not |λ|(item i of xs) then ¬
                    return take(i - 1, xs)
            end repeat
        end tell
        return xs
    end if
end takeWhile

-- takeWhileGen :: (a -> Bool) -> Gen [a] -> [a]
on takeWhileGen(p, xs)
    set ys to {}
    set v to |λ|() of xs
    tell mReturn(p)
        repeat while (|λ|(v))
            set end of ys to v
            set v to xs's |λ|()
        end repeat
    end tell
    return ys
end takeWhileGen

-- Tuple (,) :: a -> b -> (a, b)
on Tuple(a, b)
    {type:"Tuple", |1|:a, |2|:b, length:2}
end Tuple

-- unlines :: [String] -> String
on unlines(xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set str to xs as text
    set my text item delimiters to dlm
    str
end unlines

-- zip :: [a] -> [b] -> [(a, b)]
on zip(xs, ys)
    zipWith(Tuple, xs, ys)
end zip

-- zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
on zipWith(f, xs, ys)
    set lng to min(|length|(xs), |length|(ys))
    if 1 > lng then return {}
    set xs_ to take(lng, xs) -- Allow for non-finite
    set ys_ to take(lng, ys) -- generators like cycle etc
    set lst to {}
    tell mReturn(f)
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs_, item i of ys_)
        end repeat
        return lst
    end tell
end zipWith


with(Statistics):
X_100 := Sample( Uniform(0,1), 100 );
Mean( X_100 );
StandardDeviation( X_100 );
Histogram( X_100 );


Sample[n_]:= (Print[#//Length," numbers, Mean : ",#//Mean,", StandardDeviation : ",#//StandardDeviation ];
        BarChart[BinCounts[#,{0,1,.1}], Axes->False, BarOrigin->Left])&[(RandomReal[1,#])&[ n ]]
Sample/@{100,1 000,10 000,1 000 000}


  % Initialize
  N = 0; S=0; S2 = 0;
  binlist = 0:.1:1;
  h = zeros(1,length(binlist));  % initialize histogram

  % read data and perform computation
  while (1)
	% read next sample x
        if (no_data_available) break; end;
        N = N + 1;
        S = S + x;
        S2= S2+ x*x;
        ix= sum(x < binlist);
        h(ix) = h(ix)+1;
  end

  % generate output
  m  = S/N;   % mean
  sd = sqrt(S2/N-mean*mean);  % standard deviation
  bar(binlist,h)


Stats = {}
Stats.count = 0
Stats.sum = 0
Stats.sumOfSquares = 0
Stats.histo = null

Stats.add = function(x)
    self.count = self.count + 1
    self.sum = self.sum + x
    self.sumOfSquares = self.sumOfSquares + x*x
    bin = floor(x*10)
    if not self.histo then self.histo = [0]*10
    self.histo[bin] = self.histo[bin] + 1
end function

Stats.mean = function()
    return self.sum / self.count
end function

Stats.stddev = function()
    m = self.sum / self.count
    return sqrt(self.sumOfSquares / self.count - m*m)
end function

Stats.histogram = function()
    for i in self.histo.indexes
        print "0." + i + ": " + "=" * (self.histo[i]/self.count * 200)
    end for
end function

for sampleSize in [100, 1000, 10000]
    print "Samples: " + sampleSize
    st = new Stats
    for i in range(sampleSize)
        st.add rnd
    end for
    print "Mean: " + st.mean + "  Standard Deviation: " + st.stddev
    st.histogram
end for


Found := FindOneToX(100), FoundList := ""
Loop, 10
    FoundList .= "First " A_Index " found at " Found[A_Index] "`n"
MsgBox, 64, Stern-Brocot Sequence
    , % "First 15: " FirstX(15) "`n"
    .    FoundList
    .   "First 100 found at " Found[100] "`n"
    .   "GCDs of all two consecutive members are " (GCDsUpToXAreOne(1000) ? "" : "not ") "one."
return

class SternBrocot
{
    __New()
    {
        this[1] := 1
        this[2] := 1
        this.Consider := 2
    }

    InsertPair()
    {
        n := this.Consider
        this.Push(this[n] + this[n - 1], this[n])
        this.Consider++
    }
}

; Show the first fifteen members of the sequence. (This should be: 1, 1, 2, 1, 3, 2, 3, 1, 4, 3,
; 5, 2, 5, 3, 4)
FirstX(x)
{
    SB := new SternBrocot()
    while SB.MaxIndex() < x
        SB.InsertPair()
    Loop, % x
        Out .= SB[A_Index] ", "
    return RTrim(Out, " ,")
}

; Show the (1-based) index of where the numbers 1-to-10 first appears in the sequence.
; Show the (1-based) index of where the number 100 first appears in the sequence.
FindOneToX(x)
{
    SB := new SternBrocot(), xRequired := x, Found := []
    while xRequired > 0                     ; While the count of numbers yet to be found is > 0.
    {
        Loop, 2                      ; Consider the second last member and then the last member.
        {
            n := SB[i := SB.MaxIndex() - 2 + A_Index]
            ; If number (n) has not been found yet, and it is less than the maximum number to
            ; find (x), record the index (i) and decrement the count of numbers yet to be found.
            if (Found[n] = "" && n <= x)
                Found[n] := i, xRequired--
        }
        SB.InsertPair()                      ; Insert the two members that will be checked next.
    }
    return Found
}

; Check that the greatest common divisor of all the two consecutive members of the series up to
; the 1000th member, is always one.
GCDsUpToXAreOne(x)
{
    SB := new SternBrocot()
    while SB.MaxIndex() < x
        SB.InsertPair()
    Loop, % x - 1
        if GCD(SB[A_Index], SB[A_Index + 1]) > 1
            return 0
    return 1
}

GCD(a, b) {
    while b
        b := Mod(a | 0x0, a := b)
    return a
}


import random, sequtils, stats, strutils, strformat

proc drawHistogram(ns: seq[float]) =
  var h = newSeq[int](11)
  for n in ns:
    let pos = (n * 10).toInt
    inc h[pos]

  const maxWidth = 50
  let mx = max(h)
  echo ""
  for n, count in h:
    echo n.toFloat / 10, ": ", repeat('+', int(count / mx * maxWidth))
  echo ""

randomize()

# First part: compute directly from a sequence of values.
echo "For 100 numbers:"
let ns = newSeqWith(100, rand(1.0))
echo &"μ = {ns.mean:.12f}   σ = {ns.standardDeviation:.12f}"
ns.drawHistogram()

# Second part: compute incrementally using "RunningStat".
for count in [1_000, 10_000, 100_000, 1_000_000]:
  echo &"For {count} numbers:"
  var rs: RunningStat
  for _ in 1..count:
    let n = rand(1.0)
    rs.push(n)
  echo &"μ = {rs.mean:.12f}   σ = {rs.standardDeviation:.12f}"
  echo()


: main(n)
| l m std i nb |

   // Create list and calculate avg and stddev
   ListBuffer init(n, #[ Float rand ]) dup ->l avg ->m
   0 l apply(#[ sq +]) n / m sq - sqrt ->std
   System.Out "n = " << n << ", avg = " << m << ", std = " << std << cr

   // Histo
   0.0 0.9 0.1 step: i [
      l count(#[ between(i, i 0.1 +) ]) 400 * n / asInteger ->nb
      System.Out i <<wjp(3, JUSTIFY_RIGHT, 2) " - " <<
                 i 0.1 + <<wjp(3, JUSTIFY_RIGHT, 2) " - " <<
                 StringBuffer new "*" <<n(nb) << cr
      ] ;


mean(v)={
  vecsum(v)/#v
};
stdev(v,mu="")={
  if(mu=="",mu=mean(v));
  sqrt(sum(i=1,#v,(v[i]-mu)^2))/#v
};
histogram(v,bins=16,low=0,high=1)={
  my(u=vector(bins),width=(high-low)/bins);
  for(i=1,#v,u[(v[i]-low)\width+1]++);
  u
};
show(n)={
  my(v=vector(n,i,random(1.)),mu=mean(v),s=stdev(v,mu),h=histogram(v),sz=ceil(n/50/16));
  for(i=1,16,for(j=1,h[i]\sz,print1("#"));print());
  print("Mean: "mu);
  print("Stdev: "s);
};
show(100);
show(1000);
show(10000);


10 DEFINT A,B,I,J,S: DIM S(1200)
20 S(1)=1: S(2)=1
30 FOR I=2 TO 600
40 S(I*2-1)=S(I)+S(I-1)
50 S(I*2)=S(I)
60 NEXT I
70 PRINT "First 15 elements: ";
80 FOR I=1 TO 15: PRINT USING"# ";S(I);: NEXT I
85 PRINT
90 FOR I=1 TO 10
100 FOR J=1 TO 1200: IF S(J)<>I THEN NEXT J
110 PRINT "First";I;"at";J
120 NEXT I
130 FOR J=1 TO 1200: IF S(J)<>100 THEN NEXT J
140 PRINT "First 100 at";J
150 FOR I=2 TO 1000
160 A=S(I): B=S(I-1)
170 J=A: A=B: B=J MOD A: IF B THEN 170
180 IF A<>1 THEN PRINT "GCD <> 1 at ";I: STOP
190 NEXT I
200 PRINT "All GCDs are 1."
210 END


get "libhdr"

manifest $( AMOUNT = 1200 $)

let gcd(a,b) =
    a>b -> gcd(a-b, b),
    a<b -> gcd(a, b-a),
    a

let mkstern(s, n) be
$(  s!1 := 1
    s!2 := 1
    for i=2 to n/2 do
    $(  s!(i*2-1) := s!i + s!(i-1)
        s!(i*2) := s!i
    $)
$)

let find(v, n, max) = valof
    for i=1 to max
        if v!i=n then resultis i

let findwrite(v, n, max) be
    writef("%I3 at %I4*N", n, find(v, n, max))

let start() be
$(  let stern = vec AMOUNT
    mkstern(stern, AMOUNT)

    writes("First 15 numbers: ")
    for i=1 to 15 do writef("%N ", stern!i)

    writes("*N*NFirst occurrence:*N")
    for i=1 to 10 do findwrite(stern, i, AMOUNT)
    findwrite(stern, 100, AMOUNT)

    if valof
    $(  for i=2 to AMOUNT
            unless gcd(stern!i, stern!(i-1)) = 1
                resultis false
        resultis true
    $) then
        writes("*NThe GCD of each pair of consecutive members is 1.*N")
$)


my @histogram = (0) x 10;
my $sum = 0;
my $sum_squares = 0;
my $n = $ARGV[0];

for (1..$n) {
  my $current = rand();
  $sum+= $current;
  $sum_squares+= $current ** 2;
  $histogram[$current * @histogram]+= 1;
}

my $mean = $sum / $n;

print "$n numbers\n",
      "Mean:   $mean\n",
      "Stddev: ", sqrt(($sum_squares / $n) - ($mean ** 2)), "\n";

for my $i (0..$#histogram) {
  printf "%.1f - %.1f : ", $i/@histogram, (1 + $i)/@histogram;

  print "*" x (30 * $histogram[$i] * @histogram/$n); # 30 stars expected per row
  print "\n";
}


#include <stdio.h>

typedef unsigned int uint;

/* the sequence, 0-th member is 0 */
uint f(uint n)
{
	return n < 2 ? n : (n&1) ? f(n/2) + f(n/2 + 1) : f(n/2);
}

uint gcd(uint a, uint b)
{
	return a ? a < b ? gcd(b%a, a) : gcd(a%b, b) : b;
}

void find(uint from, uint to)
{
	do {
		uint n;
		for (n = 1; f(n) != from ; n++);
		printf("%3u at Stern #%u.\n", from, n);
	} while (++from <= to);
}

int main(void)
{
	uint n;
	for (n = 1; n < 16; n++) printf("%u ", f(n));
	puts("are the first fifteen.");

	find(1, 10);
	find(100, 0);

	for (n = 1; n < 1000 && gcd(f(n), f(n+1)) == 1; n++);
	printf(n == 1000 ? "All GCDs are 1.\n" : "GCD of #%d and #%d is not 1", n, n+1);

	return 0;
}


function generate_statistics(integer n)
sequence hist = repeat(0,10)
atom sum_r = 0,
     sum_squares = 0.0

    for i=1 to n do
        atom r = rnd()
        sum_r += r
        sum_squares += r*r
        hist[floor(10*r)+1] += 1
    end for
    atom mean = sum_r / n
    atom stddev = sqrt((sum_squares / n) - mean*mean)

     return {n, mean, stddev, hist}
end function

procedure display_statistics(sequence x)
atom n, mean, stddev
sequence hist
    {n, mean, stddev, hist} = x
    printf(1,"-- Stats for sample size %d\n",{n})
    printf(1,"mean: %g\n",{mean})
    printf(1,"sdev: %g\n",{stddev})
    for i=1 to length(hist) do
        integer cnt = hist[i]
        string bars = repeat('=',floor(cnt*300/n))
        printf(1,"%.1f: %s %d\n",{i/10,bars,cnt})
    end for
end procedure

for n=2 to 5 do
    display_statistics(generate_statistics(power(10,n+(n=5))))
end for


(seed (time))

(scl 8)

(de statistics (Cnt . Prg)
   (prinl Cnt " numbers")
   (let (Sum 0  Sqr 0  Hist (need 10 NIL 0))
      (do Cnt
         (let N (run Prg 1)  # Get next number
            (inc 'Sum N)
            (inc 'Sqr (*/ N N 1.0))
            (inc (nth Hist (inc (/ N 0.1)))) ) )
      (let M (*/ Sum Cnt)
         (prinl "Mean:   " (round M))
         (prinl "StdDev: "
            (round
               (sqrt
                  (- (*/ Sqr Cnt) (*/ M M 1.0))
                  1.0 ) ) ) )
      (for (I . H) Hist
         (prin (format I 1) " ")
         (do (*/ H 400 Cnt) (prin '=))
         (prinl) ) ) )

(for I (2 4 6)
   (statistics (** 10 I)
      (rand 0 (dec 1.0)) )
   (prinl) )


using System;
using System.Collections.Generic;
using System.Linq;

static class Program {
    static List<int> l = new List<int>() { 1, 1 };

    static int gcd(int a, int b) {
        return a > 0 ? a < b ? gcd(b % a, a) : gcd(a % b, b) : b; }

    static void Main(string[] args) {
        int max = 1000; int take = 15; int i = 1;
        int[] selection = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100 };
        do { l.AddRange(new List<int>() { l[i] + l[i - 1], l[i] }); i += 1; }
        while (l.Count < max || l[l.Count - 2] != selection.Last());
        Console.Write("The first {0} items In the Stern-Brocot sequence: ", take);
        Console.WriteLine("{0}\n", string.Join(", ", l.Take(take)));
        Console.WriteLine("The locations of where the selected numbers (1-to-10, & 100) first appear:");
        foreach (int ii in selection) {
            int j = l.FindIndex(x => x == ii) + 1; Console.WriteLine("{0,3}: {1:n0}", ii, j); }
        Console.WriteLine(); bool good = true;
        for (i = 1; i <= max; i++) { if (gcd(l[i], l[i - 1]) != 1) { good = false; break; } }
        Console.WriteLine("The greatest common divisor of all the two consecutive items of the" +
                          " series up to the {0}th item is {1}always one.", max, good ? "" : "not ");
    }
}


 stat: procedure options (main); /* 21 May 2014 */

stats: procedure (values, mean, standard_deviation);
   declare (values(*), mean, standard_deviation) float;
   declare n fixed binary (31) initial ( (hbound(values,1)) );

   mean = sum(values)/n;

   standard_deviation = sqrt( sum(values - mean)**2 / n);

end stats;

   declare values (*) float controlled;
   declare (mean, stddev) float;
   declare bin(0:9) fixed;
   declare (i, n) fixed binary (31);

   do n = 100, 1000, 10000, 100000;
      allocate values(n);
      values = random();
      call stats (values, mean, stddev);

      if n = 100 then
         do;
            bin = 0;
            do i = 1 to 100;
               bin(10*values(i)) += 1;
            end;
            put skip list ('Histogram for 100 values:');
            do i = 0 to 9;  /* display histogram */
               put skip list (repeat('.', bin(i)) );
            end;
         end;

      put skip list (n || ' values: mean=' || mean, 'stddev=' || stddev);
      free values;
   end;

end stat;


Procedure.f randomf()
  #RNG_max_resolution = 2147483647
  ProcedureReturn Random(#RNG_max_resolution) / #RNG_max_resolution
EndProcedure

Procedure sample(n)
  Protected i, nBins, binNumber, tickMarks, maxBinValue
  Protected.f sum, sumSq, mean

  Dim dat.f(n)
  For i = 1 To n
    dat(i) = randomf()
  Next

  ;show mean, standard deviation
  For i = 1 To n
    sum + dat(i)
    sumSq + dat(i) * dat(i)
  Next i

  PrintN(Str(n) + " data terms used.")
  mean = sum / n
  PrintN("Mean =" + StrF(mean))
  PrintN("Stddev =" + StrF((sumSq / n) - Sqr(mean * mean)))

  ;show histogram
  nBins = 10
  Dim bins(nBins)
  For i = 1 To n
    binNumber = Int(nBins * dat(i))
    bins(binNumber) + 1
  Next

  maxBinValue = 1
  For i = 0 To nBins
    If bins(i) > maxBinValue
      maxBinValue = bins(i)
    EndIf
  Next

  #normalizedMaxValue = 70
  For binNumber = 0 To nBins
    tickMarks = Int(bins(binNumber) * #normalizedMaxValue / maxBinValue)
    PrintN(ReplaceString(Space(tickMarks), " ", "#"))
  Next
  PrintN("")
EndProcedure

If OpenConsole()
  sample(100)
  sample(1000)
  sample(10000)

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


#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>

unsigned gcd( unsigned i, unsigned j ) {
    return i ? i < j ? gcd( j % i, i ) : gcd( i % j, j ) : j;
}
void createSequence( std::vector<unsigned>& seq, int c ) {
    if( 1500 == seq.size() ) return;
    unsigned t = seq.at( c ) + seq.at( c + 1 );
    seq.push_back( t );
    seq.push_back( seq.at( c + 1 ) );
    createSequence( seq, c + 1 );
}
int main( int argc, char* argv[] ) {
    std::vector<unsigned> seq( 2, 1 );
    createSequence( seq, 0 );

    std::cout << "First fifteen members of the sequence:\n    ";
    for( unsigned x = 0; x < 15; x++ ) {
        std::cout << seq[x] << " ";
    }

    std::cout << "\n\n";
    for( unsigned x = 1; x < 11; x++ ) {
        std::vector<unsigned>::iterator i = std::find( seq.begin(), seq.end(), x );
        if( i != seq.end() ) {
            std::cout << std::setw( 3 ) << x << " is at pos. #" << 1 + distance( seq.begin(), i ) << "\n";
        }
    }

    std::cout << "\n";
    std::vector<unsigned>::iterator i = std::find( seq.begin(), seq.end(), 100 );
    if( i != seq.end() ) {
        std::cout << 100 << " is at pos. #" << 1 + distance( seq.begin(), i ) << "\n";
    }

    std::cout << "\n";
    unsigned g;
    bool f = false;
    for( int x = 0, y = 1; x < 1000; x++, y++ ) {
        g =  gcd( seq[x], seq[y] );
	if( g != 1 ) f = true;
        std::cout << std::setw( 4 ) << x + 1 << ": GCD (" << seq[x] << ", "
                  << seq[y] << ") = " << g << ( g != 1 ? " <-- ERROR\n" : "\n" );
    }
    std::cout << "\n" << ( f ? "THERE WERE ERRORS --- NOT ALL GCDs ARE '1'!" : "CORRECT: ALL GCDs ARE '1'!" ) << "\n\n";
    return 0;
}


def sd1(numbers):
    if numbers:
        mean = sum(numbers) / len(numbers)
        sd = (sum((n - mean)**2 for n in numbers) / len(numbers))**0.5
        return sd, mean
    else:
        return 0, 0

def sd2(numbers):
    if numbers:
        sx = sxx = n = 0
        for x in numbers:
            sx += x
            sxx += x*x
            n += 1
        sd = (n * sxx - sx*sx)**0.5 / n
        return sd, sx / n
    else:
        return 0, 0

def histogram(numbers):
    h = [0] * 10
    maxwidth = 50 # characters
    for n in numbers:
        h[int(n*10)] += 1
    mx = max(h)
    print()
    for n, i in enumerate(h):
        print('%3.1f: %s' % (n / 10, '+' * int(i / mx * maxwidth)))
    print()

if __name__ == '__main__':
    import random
    for i in range(1, 6):
        n = [random.random() for j in range(10**i)]
        print("\n##\n## %i numbers\n##" % 10**i)
        print('  Naive  method: sd: %8.6f, mean: %8.6f' % sd1(n))
        print('  Second method: sd: %8.6f, mean: %8.6f' % sd2(n))
        histogram(n)


#Generate the sets
a = runif(10,min=0,max=1)
b = runif(100,min=0,max=1)
c = runif(1000,min=0,max=1)
d = runif(10000,min=0,max=1)

#Print out the set of 10 values
cat("a = ",a)

#Print out the Mean and Standard Deviations of each of the sets
cat("Mean of a : ",mean(a))
cat("Standard Deviation of a : ", sd(a))
cat("Mean of b : ",mean(b))
cat("Standard Deviation of b : ", sd(b))
cat("Mean of c : ",mean(c))
cat("Standard Deviation of c : ", sd(c))
cat("Mean of d : ",mean(d))
cat("Standard Deviation of d : ", sd(d))

#Plotting the histogram of d
hist(d)

#Following lines error out due to insufficient memory

cat("Mean of a trillion random values in the range [0,1] : ",mean(runif(10^12,min=0,max=1)))
cat("Standard Deviation of a trillion random values in the range [0,1] : ", sd(runif(10^12,min=0,max=1)))


#lang racket
(require math (only-in srfi/27 random-real))

(define (histogram n xs Δx)
  (define (r x) (~r x #:precision 1 #:min-width 3))
  (define (len count) (exact-floor (/ (* count 200) n)))
  (for ([b (bin-samples (range 0 1 Δx) <= xs)])
    (displayln (~a (r (sample-bin-min b)) "-" (r (sample-bin-max b)) ": "
                   (make-string (len (length (sample-bin-values b))) #\*)))))

(define (task n)
  (define xs (for/list ([_ n]) (random-real)))
  (displayln (~a "Number of samples: " n))
  (displayln (~a "Mean: " (mean xs)))
  (displayln (~a "Standard deviance: " (stddev xs)))
  (histogram n xs 0.1)
  (newline))

(task 100)
(task 1000)
(task 10000)


;; each step adds two items
(defn sb-step [v]
  (let [i (quot (count v) 2)]
    (conj v (+ (v (dec i)) (v i)) (v i))))

;; A lazy, infinite sequence -- `take` what you want.
(def all-sbs (sequence (map peek) (iterate sb-step [1 1])))

;; zero-based
(defn first-appearance [n]
  (first (keep-indexed (fn [i x] (when (= x n) i)) all-sbs)))

;; inlined abs; rem is slightly faster than mod, and the same result for positive values
(defn gcd [a b]
  (loop [a (if (neg? a) (- a) a)
         b (if (neg? b) (- b) b)]
    (if (zero? b)
      a
      (recur b (rem a b)))))

(defn check-pairwise-gcd [cnt]
  (let [sbs (take (inc cnt) all-sbs)]
    (every? #(= 1 %) (map gcd sbs (rest sbs)))))

;; one-based index required by problem statement
(defn report-sb []
  (println "First 15 Stern-Brocot members:" (take 15 all-sbs))
  (println "First appearance of N at 1-based index:")
  (doseq [n [1 2 3 4 5 6 7 8 9 10 100]]
    (println " first" n "at" (inc (first-appearance n))))
  (println "Check pairwise GCDs = 1 ..." (check-pairwise-gcd 1000))
  true)

(report-sb)


for 100, 1_000, 10_000 -> $N {
    say "size: $N";
    my @data = rand xx $N;
    printf "mean: %f\n", my $mean = $N R/ [+] @data;
    printf "stddev: %f\n", sqrt
    $mean**2 R- $N R/ [+] @data »**» 2;
    printf "%.1f %s\n", .key, '=' x (500 * .value.elems / $N)
        for sort @data.classify: (10 * *).Int / 10;
    say '';
}


/*REXX program generates some random numbers, shows bin histogram, finds mean & stdDev. */
numeric digits 20                                /*use twenty decimal digits precision, */
showDigs=digits()%2                              /* ··· but only show ten decimal digits*/
parse arg size seed .                            /*allow specification:  size, and seed.*/
if size=='' | size==","  then size=100           /*Not specified?  Then use the default.*/
if datatype(seed,'W')    then call random ,,seed /*allow a  seed  for the  RANDOM  BIF. */
#.=0                                             /*count of the numbers in each bin.    */
                do j=1  for size                 /*generate some random numbers.        */
                @.j=random(, 99999)  /  100000   /*express random number as a fraction. */
                _=substr(@.j'00', 3, 1)          /*determine which bin the number is in,*/
                #._=#._ + 1                      /*    ···  and bump its count.         */
                end   /*j*/

     do k=0  for 10;    kp=k + 1                 /*show a histogram of the bins.        */
     lr='0.'k      ;    if k==0  then lr= "0  "  /*adjust for the  low range.           */
     hr='0.'kp     ;    if k==9  then hr= "1  "  /*   "    "   "  high range.           */
     barPC=right( strip( left( format( 100*#.k / size, , 2), 5)), 5)   /*compute the %. */
     say lr"──►"hr' '   barPC  copies("─", barPC * 2  % 1 )            /*show histogram.*/
     end   /*k*/
say
say 'sample size = ' size;          say
avg=  mean(size)         ;          say '       mean = '           format(avg, , showDigs)
std=stdDev(size)         ;          say '     stdDev = '           format(std, , showDigs)
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
mean:   arg N;   $=0;    do m=1  for N;  $=$ + @.m;           end;     return      $/N
stdDev: arg N;   $=0;    do s=1  for N;  $=$ + (@.s-avg)**2;  end;     return sqrt($/N) /1
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x; if x=0  then return 0; d=digits(); m.=9; numeric form; h=d+6
      numeric digits;  parse value format(x,2,1,,0) 'E0'  with  g 'E' _ .;  g=g*.5'e'_ % 2
         do j=0  while h>9;      m.j=h;               h=h%2+1;        end /*j*/
         do k=j+5  to 0  by -1;  numeric digits m.k;  g=(g+x/g)*.5;   end /*k*/;  return g


stern = proc (n: int) returns (array[int])
    s: array[int] := array[int]$fill(1, n, 1)
    for i: int in int$from_to(2, n/2) do
        s[i*2-1] := s[i] + s[i-1]
        s[i*2] := s[i]
    end
    return (s)
end stern

gcd = proc (a,b: int) returns (int)
    while b ~= 0 do
        a, b := b, a//b
    end
    return (a)
end gcd

find = proc [T: type] (a: array[T], val: T) returns (int) signals (not_found)
       where T has equal: proctype (T,T) returns (bool)
    for i: int in array[T]$indexes(a) do
        if a[i] = val then return (i) end
    end
    signal not_found
end find

start_up = proc ()
    po: stream := stream$primary_output()
    s: array[int] := stern(1200)

    stream$puts(po, "First 15 numbers:")
    for i: int in int$from_to(1, 15) do
        stream$puts(po, " " || int$unparse(s[i]))
    end
    stream$putl(po, "")

    for i: int in int$from_to(1, 10) do
        stream$putl(po, "First " || int$unparse(i) || " at " ||
                        int$unparse(find[int](s, i)))
    end
    stream$putl(po, "First 100 at " || int$unparse(find[int](s, 100)))

    begin
        for i: int in int$from_to(2, array[int]$high(s)) do
            if gcd(s[i-1], s[i]) ~= 1 then
                exit gcd_not_one(i)
            end
        end
        stream$putl(po, "The GCD of every pair of adjacent elements is 1.")
    end except when gcd_not_one(i: int):
        stream$putl(po, "The GCD of the pair at " || int$unparse(i) || " is not 1.")
    end
end start_up


(defun stern-brocot (numbers)
  (declare ((or null (vector integer)) numbers))
  (cond ((null numbers)
         (setf numbers (make-array 2 :element-type 'integer :adjustable t :fill-pointer t
                                     :initial-element 1)))
        ((zerop (length numbers))
         (vector-push-extend 1 numbers)
         (vector-push-extend 1 numbers))
        (t
         (assert (evenp (length numbers)))
         (let* ((considered-index (/ (length numbers) 2))
                (considered (aref numbers considered-index))
                (precedent  (aref numbers (1- considered-index))))
           (vector-push-extend (+ considered precedent) numbers)
           (vector-push-extend considered numbers))))
  numbers)

(defun first-15 ()
  (loop for input = nil then seq
        for seq = (stern-brocot input)
        while (< (length seq) 15)
        finally (format t "First 15: ~{~A~^ ~}~%" (coerce (subseq seq 0 15) 'list))))

(defun first-1-to-10 ()
  (loop with seq = (stern-brocot nil)
        for i from 1 to 10
        for index = (loop with start = 0
                          for pos = (position i seq :start start)
                          until pos
                          do (setf start (length seq)
                                   seq   (stern-brocot seq))
                          finally (return (1+ pos)))
        do (format t "First ~D at ~D~%" i index)))

(defun first-100 ()
  (loop for input = nil then seq
        for start = (length input)
        for seq = (stern-brocot input)
        for pos = (position 100 seq :start start)
        until pos
        finally (format t "First 100 at ~D~%" (1+ pos))))

(defun check-gcd ()
  (loop for input = nil then seq
        for seq = (stern-brocot input)
        while (< (length seq) 1000)
        finally (if (loop for i from 0 below 999
                          always (= 1 (gcd (aref seq i) (aref seq (1+ i)))))
                    (write-line "Correct.  The GCDs of all the two consecutive numbers are 1.")
                    (write-line "Wrong."))))

(defun main ()
  (first-15)
  (first-1-to-10)
  (first-100)
  (check-gcd))


# Project : Statistics/Basic

decimals(9)
sample(100)
sample(1000)
sample(10000)

func sample(n)
       samp = list(n)
       for i =1 to n
           samp[i] =random(9)/10
       next
       sum = 0
       sumSq = 0
       for i = 1 to n
            sum = sum + samp[i]
            sumSq	= sumSq +pow(samp[i],2)
       next
       see n + " Samples used." + nl
       mean = sum / n
       see "Mean    = " + mean + nl
       see "Std Dev = " + pow((sumSq /n -pow(mean,2)),0.5) + nl
       bins2 = 10
       bins = list(bins2)
       for i = 1 to n
            z = floor(bins2 * samp[i])
            if z != 0
               bins[z] = bins[z] +1
            ok
       next
       for b = 1 to bins2
            see b + " " + nl
            for j = 1 to floor(bins2 *bins[b]) /n *70
                see "*"
            next
            see nl
       next
       see nl


def generate_statistics(n)
  sum = sum2 = 0.0
  hist = Array.new(10, 0)
  n.times do
    r = rand
    sum += r
    sum2 += r**2
    hist[(10*r).to_i] += 1
  end
  mean = sum / n
  stddev = Math::sqrt((sum2 / n) - mean**2)

  puts "size: #{n}"
  puts "mean:   #{mean}"
  puts "stddev: #{stddev}"
  hist.each_with_index {|x,i| puts "%.1f:%s" % [0.1*i, "=" * (70*x/hist.max)]}
  puts
end

[100, 1000, 10000].each {|n| generate_statistics n}


call sample    100
call sample   1000
call sample  10000

end

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

    ' calculate mean, standard deviation
    sum		= 0
    sumSq	= 0
    for i = 1 to n
        sum	= sum + samp(i)
        sumSq	= sumSq + samp(i)^2
    next i
    print n; " Samples used."

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

    print "Std Dev = "; (sumSq /n -mean^2)^0.5

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


#![feature(iter_arith)]
extern crate rand;

use rand::distributions::{IndependentSample, Range};

pub fn mean(data: &[f32]) -> Option<f32> {
    if data.is_empty() {
        None
    } else {
        let sum: f32 = data.iter().sum();
        Some(sum / data.len() as f32)
    }
}

pub fn variance(data: &[f32]) -> Option<f32> {
    if data.is_empty() {
        None
    } else {
        let mean = mean(data).unwrap();
        let mut sum = 0f32;
        for &x in data {
            sum += (x - mean).powi(2);
        }
        Some(sum / data.len() as f32)
    }
}

pub fn standard_deviation(data: &[f32]) -> Option<f32> {
    if data.is_empty() {
        None
    } else {
        let variance = variance(data).unwrap();
        Some(variance.sqrt())
    }
}

fn print_histogram(width: u32, data: &[f32]) {
    let mut histogram = [0; 10];
    let len = histogram.len() as f32;
    for &x in data {
        histogram[(x * len) as usize] += 1;
    }
    let max_frequency = *histogram.iter().max().unwrap() as f32;
    for (i, &frequency) in histogram.iter().enumerate() {
        let bar_width = frequency as f32 * width as f32 / max_frequency;
        print!("{:3.1}: ", i as f32 / len);
        for _ in 0..bar_width as usize {
            print!("*");
        }
        println!("");
    }
}

fn main() {
    let range = Range::new(0f32, 1f32);
    let mut rng = rand::thread_rng();

    for &number_of_samples in [1000, 10_000, 1_000_000].iter() {
        let mut data = vec![];
        for _ in 0..number_of_samples {
            let x = range.ind_sample(&mut rng);
            data.push(x);
        }
        println!("  Statistics for sample size {}", number_of_samples);
        println!("Mean:               {:?}", mean(&data));
        println!("Variance:           {:?}", variance(&data));
        println!("Standard deviation: {:?}", standard_deviation(&data));
        print_histogram(40, &data);
    }
}


include "cowgol.coh";

# Redefining these is enough to change the type and length everywhere,
# but arrays are 0-based so you need one extra element.
typedef Stern is uint8;  # 8-bit math is enough for the numbers we need
var stern: Stern[1201];  # Array containing Stern-Brocot sequence

# Fill up the Stern-Brocot array
sub GenStern() is
    stern[1] := 1;
    stern[2] := 1;

    var i: @indexof stern := 1;
    var last: @indexof stern := @sizeof stern / 2;
    while i <= last loop
        stern[i*2-1] := stern[i] + stern[i-1];
        stern[i*2] := stern[i];
        i := i + 1;
    end loop;
end sub;

# Find the first location of a given number
sub FindFirst(n: Stern): (i: @indexof stern) is
    i := 1;
    while i < @sizeof stern and stern[i] != n loop
        i := i + 1;
    end loop;
end sub;

GenStern(); # Generate sequence

# Print the first 15 numbers
var i: @indexof stern := 1;
while i <= 15 loop
    print_i32(stern[i] as uint32);
    print_char(' ');
    i := i + 1;
end loop;
print_nl();

# Print the first occurrence of 1..10
var j: Stern := 1;
while j <= 10 loop
    print_i32(FindFirst(j) as uint32);
    print_char(' ');
    j := j + 1;
end loop;
print_nl();

# Print the first occurrence of 100
print_i32(FindFirst(100) as uint32);
print_nl();

# Check that all GCDs of consecutive pairs are 1
sub gcd(a: Stern, b: Stern): (r: Stern) is
    while a != b loop
        if a > b then
            a := a - b;
        else
            b := b - a;
        end if;
    end loop;
    r := a;
end sub;

i := 1;
while i < @sizeof stern / 2 loop
    if gcd(stern[i], stern[i+1]) != 1 then
        print("GCD not 1 at: ");
        print_i32(i as uint32);
        print_nl();
        ExitWithError();
    end if;
    i := i + 1;
end loop;

print("All GCDs are 1.\n");


import std.stdio, std.numeric, std.range, std.algorithm;

/// Generates members of the stern-brocot series, in order,
/// returning them when the predicate becomes false.
uint[] sternBrocot(bool delegate(in uint[]) pure nothrow @safe @nogc pred=seq => seq.length < 20)
pure nothrow @safe {
    typeof(return) sb = [1, 1];
    size_t i = 0;
    while (pred(sb)) {
        sb ~= [sb[i .. i + 2].sum, sb[i + 1]];
        i++;
    }
    return sb;
}

void main() {
    enum nFirst = 15;
    writefln("The first %d values:\n%s\n", nFirst,
             sternBrocot(seq => seq.length < nFirst).take(nFirst));

    foreach (immutable nOccur; iota(1, 10 + 1).chain(100.only))
        writefln("1-based index of the first occurrence of %3d in the series: %d",
                 nOccur, sternBrocot(seq => nOccur != seq[$ - 2]).length - 1);

    enum nGcd = 1_000;
    auto s = sternBrocot(seq => seq.length < nGcd).take(nGcd);
    assert(zip(s, s.dropOne).all!(ss => ss[].gcd == 1),
           "A fraction from adjacent terms is reducible.");
}


def mean(a:Array[Double])=a.sum / a.size
def stddev(a:Array[Double])={
   val sum = a.fold(0.0)((a, b) => a + math.pow(b,2))
   math.sqrt((sum/a.size) - math.pow(mean(a),2))
}
def hist(a:Array[Double]) = {
   val grouped=(SortedMap[Double, Array[Double]]() ++ (a groupBy (x => math.rint(x*10)/10)))
   grouped.map(v => (v._1, v._2.size))
}
def printHist(a:Array[Double])=for((g,v) <- hist(a)){
   println(s"$g: ${"*"*(205*v/a.size)} $v")
}

for(n <- Seq(100,1000,10000)){
   val a = Array.fill(n)(Random.nextDouble)
   println(s"$n numbers")
   println(s"Mean: ${mean(a)}")
   println(s"StdDev: ${stddev(a)}")
   printHist(a)
   println
}


func generate_statistics(n) {
    var(sum=0, sum2=0);
    var hist = 10.of(0);

    n.times {
        var r = 1.rand;
        sum += r;
        sum2 += r**2;
        hist[10*r] += 1;
    }

    var mean = sum/n;
    var stddev = Math.sqrt(sum2/n - mean**2);

    say "size: #{n}";
    say "mean:   #{mean}";
    say "stddev: #{stddev}";

    var max = hist.max;
    hist.range.each {|i|
        printf("%.1f:%s\n", 0.1*i, "=" * 70*hist[i]/max);
    }
    print "\n";
}

[100, 1000, 10000].each {|n| generate_statistics(n) }


;; stern (2n ) = stern (n)
;; stern(2n+1) = stern(n) + stern(n+1)

(define (stern n)
	(cond
		(( < n 3) 1)
		((even? n) (stern (/ n 2)))
		(else (let ((m (/ (1- n) 2))) (+ (stern m) (stern (1+ m)))))))
(remember 'stern)


defmodule SternBrocot do
  def sequence do
    Stream.unfold({0,{1,1}}, fn {i,acc} ->
      a = elem(acc, i)
      b = elem(acc, i+1)
      {a, {i+1, Tuple.append(acc, a+b) |> Tuple.append(b)}}
    end)
  end

  def task do
    IO.write "First fifteen members of the sequence:\n  "
    IO.inspect Enum.take(sequence, 15)
    Enum.each(Enum.concat(1..10, [100]), fn n ->
      i = Enum.find_index(sequence, &(&1==n)) + 1
      IO.puts "#{n} first appears at #{i}"
    end)
    Enum.take(sequence, 1000)
    |> Enum.chunk(2,1)
    |> Enum.all?(fn [a,b] -> gcd(a,b) == 1 end)
    |> if(do: "All GCD's are 1", else: "Whoops, not all GCD's are 1!")
    |> IO.puts
  end

  defp gcd(a,0), do: abs(a)
  defp gcd(a,b), do: gcd(b, rem(a,b))
end

SternBrocot.task


package require Tcl 8.5
proc stats {size} {
    set sum 0.0
    set sum2 0.0
    for {set i 0} {$i < $size} {incr i} {
	set r [expr {rand()}]

	incr histo([expr {int(floor($r*10))}])
	set sum [expr {$sum + $r}]
	set sum2 [expr {$sum2 + $r**2}]
    }
    set mean [expr {$sum / $size}]
    set stddev [expr {sqrt($sum2/$size - $mean**2)}]
    puts "$size numbers"
    puts "Mean:   $mean"
    puts "StdDev: $stddev"
    foreach i {0 1 2 3 4 5 6 7 8 9} {
	# The 205 is a magic factor stolen from the Go solution
	puts [string repeat "*" [expr {$histo($i)*205/int($size)}]]
    }
}

stats 100
puts ""
stats 1000
puts ""
stats 10000


Option Base 1
Private Function mean(s() As Variant) As Double
    mean = WorksheetFunction.Average(s)
End Function
Private Function standard_deviation(s() As Variant) As Double
    standard_deviation = WorksheetFunction.StDev(s)
End Function
Public Sub basic_statistics()
    Dim s() As Variant
    For e = 2 To 4
        ReDim s(10 ^ e)
        For i = 1 To 10 ^ e
            s(i) = Rnd()
        Next i
        Debug.Print "sample size"; UBound(s), "mean"; mean(s), "standard deviation"; standard_deviation(s)
        t = WorksheetFunction.Frequency(s, [{0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0}])
        For i = 1 To 10
            Debug.Print Format((i - 1) / 10, "0.00");
            Debug.Print "-"; Format(i / 10, "0.00"),
            Debug.Print String$(t(i, 1) / (10 ^ (e - 2)), "X");
            Debug.Print
        Next i
        Debug.Print
    Next e
End Sub


// Generate Stern-Brocot Sequence. Nigel Galloway: October 11th., 2018
let sb=Seq.unfold(fun (n::g::t)->Some(n,[g]@[email protected][n+g;g]))[1;1]


USING: formatting io kernel lists lists.lazy locals math
math.ranges prettyprint sequences ;
IN: rosetta-code.stern-brocot

: fn ( n -- m )
    [ 1 0 ] dip
    [ dup zero? ] [
        dup 1 bitand zero?
        [ dupd [ + ] 2dip        ]
        [ [ dup ] [ + ] [ ] tri* ] if
        -1 shift
    ] until drop nip ;

:: search ( n -- m )
    1 0 lfrom [ fn n = ] lfilter ltake list>array first ;

: first15 ( -- )
    15 [1,b] [ fn pprint bl ] each
    "are the first fifteen." print ;

: first-appearances ( -- )
    10 [1,b] 100 suffix
    [ dup search "First %3u at Stern #%u.\n" printf ] each ;

: gcd-test ( -- )
    1,000 [1,b] [ dup 1 + [ fn ] [email protected] gcd nip 1 = not ] filter
    empty? "" " not" ? "All GCDs are%s 1.\n" printf ;

: main ( -- ) first15 first-appearances gcd-test ;

MAIN: main


import rand
import math

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

fn sample(n int) {
    // generate data
    mut d := []f64{len: n}
    for i in 0.. d.len {
        d[i] = rand.f64()
    }
    // show mean, standard deviation
    mut sum, mut ssq := f64(0), f64(0)
    for  s in d {
        sum += s
        ssq += s * s
    }
    println("$n numbers")
    m := sum / f64(n)
    println("Mean:  $m")
    println("Stddev: ${math.sqrt(ssq/f64(n)-m*m)}")
    // show histogram
    mut h := []int{len: 10}
    for s in d {
        h[int(s*10)]++
    }
    for c in h {
        println("*".repeat(c*205/int(n)))
    }
    println('')
}


import "random" for Random
import "/math" for Nums

var r = Random.new()
for (i in [100, 1000, 10000]) {
    var a = List.filled(i, 0)
    for (j in 0...i) a[j] = r.float()
    System.print("For %(i) random numbers:")
    System.print("  mean    = %(Nums.mean(a))")
    System.print("  std/dev = %(Nums.popStdDev(a))")
    var scale = i / 100
    System.print("  scale   = %(scale) per asterisk")
    var sums = List.filled(10, 0)
    for (e in a) {
        var f = (e*10).floor
        sums[f] = sums[f] + 1
    }
    for (j in 0..8) {
        sums[j] = (sums[j] / scale).round
        System.print("  0.%(j) - 0.%(j+1): %("*" * sums[j])")
    }
    sums[9] = 100 - Nums.sum(sums[0..8])
    System.print("  0.9 - 1.0: %("*" * sums[9])\n")
}


fcn mean(ns)  { ns.sum(0.0)/ns.len() }
fcn stdDev(ns){
   m:=mean(ns); (ns.reduce('wrap(p,n){ x:=(n-m); p+x*x },0.0)/ns.len()).sqrt()
}


: stern ( n -- x : return N'th item of Stern-Brocot sequence)
  dup 2 >= if
      2 /mod swap if
         dup 1+ recurse
         swap recurse
         +
      else
         recurse
      then
  then
;

: first ( n -- x : return X such that stern X = n )
  1 begin over over stern <> while 1+ repeat
  swap drop
;

: gcd ( a b -- a gcd b )
  begin swap over mod dup 0= until drop
;

: task
  ( Print first 15 numbers )
  ." First 15: " 1 begin dup stern . 1+ dup 15 > until
  drop cr

  ( Print first occurrence of 1..10 )
  1 begin
      ." First " dup . ." at " dup first .
      1+ cr
  dup 10 > until
  drop

  ( Print first occurrence of 100 )
  ." First 100 at " 100 first . cr

  ( Check that the GCD of each adjacent pair up to 1000 is 1 )
  -1 2 begin
     dup stern over 1- stern gcd 1 =
     rot and swap
     1+
  dup 1000 > until
  swap if
     ." All GCDs are 1."
     drop
  else
     ." GCD <> 1 at: " .
  then
  cr
;

task
bye


* STERN-BROCOT SEQUENCE - FORTRAN IV
      DIMENSION ISB(2400)
      NN=2400
      ISB(1)=1
      ISB(2)=1
      I=1
      J=2
      K=2
 1    IF(K.GE.NN) GOTO 2
        K=K+1
        ISB(K)=ISB(K-I)+ISB(K-J)
        K=K+1
        ISB(K)=ISB(K-J)
        I=I+1
        J=J+1
        GOTO 1
 2    N=15
      WRITE(*,101) N
  101 FORMAT(1X,'FIRST',I4)
      WRITE(*,102) (ISB(I),I=1,15)
  102 FORMAT(15I4)
      DO 5 J=1,11
        JJ=J
        IF(J.EQ.11) JJ=100
        DO 3 I=1,K
          IF(ISB(I).EQ.JJ) GOTO 4
 3      CONTINUE
 4      WRITE(*,103) JJ,I
  103   FORMAT(1X,'FIRST',I4,' AT ',I4)
 5    CONTINUE
      END


' version 02-03-2019
' compile with: fbc -s console

#Define max 2000

Dim Shared As UInteger stern(max +2)

Sub stern_brocot

    stern(1) = 1
    stern(2) = 1

    Dim As UInteger i = 2 , n = 2, ub = UBound(stern)

    Do While i < ub
        i += 1
        stern(i) = stern(n) + stern(n -1)
        i += 1
        stern(i) = stern(n)
        n += 1
    Loop

End Sub

Function gcd(x As UInteger, y As UInteger) As UInteger

    Dim As UInteger t

    While y
        t = y
        y = x Mod y
        x = t
    Wend

    Return x

End Function

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

Dim As UInteger i

stern_brocot

Print "The first 15 are: " ;
For i = 1 To 15
    Print stern(i); " ";
Next

Print : Print
Print "  Index   First nr."
Dim As UInteger d = 1
For i = 1 To max
    If stern(i) = d Then
        Print Using " ######"; i; stern(i)
        d += 1
        If d = 11 Then d = 100
        If d = 101 Then Exit For
        i = 0
    End If
Next

Print : Print
d = 0
For i = 1 To 1000
    If gcd(stern(i), stern(i +1)) <> 1 Then
        d = gcd(stern(i), stern(i +1))
        Exit For
    End If
Next

If d = 0 Then
    Print "GCD of two consecutive members of the series up to the 1000th member is 1"
Else
    Print "The GCD for index "; i; " and "; i +1; " = "; d
End If

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


package main

import (
    "fmt"

    "sternbrocot"
)

func main() {
    // Task 1, using the conventional sort of generator that generates
    // terms endlessly.
    g := sb.Generator()

    // Task 2, demonstrating the generator.
    fmt.Println("First 15:")
    for i := 1; i <= 15; i++ {
        fmt.Printf("%2d:  %d\n", i, g())
    }

    // Task 2 again, showing a simpler technique that might or might not be
    // considered to "generate" terms.
    s := sb.New()
    fmt.Println("First 15:", s.FirstN(15))

    // Tasks 3 and 4.
    for _, x := range []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100} {
        fmt.Printf("%3d at 1-based index %d\n", x, 1+s.Find(x))
    }

    // Task 5.
    fmt.Println("1-based indexes: gcd")
    for n, f := range s.FirstN(1000)[:999] {
        g := gcd(f, (*s)[n+1])
        fmt.Printf("%d,%d: gcd(%d, %d) = %d\n", n+1, n+2, f, (*s)[n+1], g)
        if g != 1 {
            panic("oh no!")
            return
        }
    }
}

// gcd copied from greatest common divisor task
func gcd(x, y int) int {
    for y != 0 {
        x, y = y, x%y
    }
    return x
}


import Data.List (elemIndex)

sb :: [Int]
sb = 1 : 1 : f (tail sb) sb
  where
    f (a : aa) (b : bb) = a + b : a : f aa bb

main :: IO ()
main = do
  print $ take 15 sb
  print
    [ (i, 1 + (\(Just i) -> i) (elemIndex i sb))
      | i <- [1 .. 10] <> [100]
    ]
  print $
    all (\(a, b) -> 1 == gcd a b) $
      take 1000 $ zip sb (tail sb)


sternbrocot=:1 :0
  ind=. 0
  seq=. 1 1
  while. -. u seq do.
    ind=. ind+1
    seq=. seq, +/\. seq {~ _1 0 +ind
  end.
)


import java.math.BigInteger;
import java.util.LinkedList;

public class SternBrocot {
	static LinkedList<Integer> sequence = new LinkedList<Integer>(){{
		add(1); add(1);
	}};

	private static void genSeq(int n){
		for(int conIdx = 1; sequence.size() < n; conIdx++){
			int consider = sequence.get(conIdx);
			int pre = sequence.get(conIdx - 1);
			sequence.add(consider + pre);
			sequence.add(consider);
		}

	}

	public static void main(String[] args){
		genSeq(1200);
		System.out.println("The first 15 elements are: " + sequence.subList(0, 15));
		for(int i = 1; i <= 10; i++){
			System.out.println("First occurrence of " + i + " is at " + (sequence.indexOf(i) + 1));
		}

		System.out.println("First occurrence of 100 is at " + (sequence.indexOf(100) + 1));

		boolean failure = false;
		for(int i = 0; i < 999; i++){
			failure |= !BigInteger.valueOf(sequence.get(i)).gcd(BigInteger.valueOf(sequence.get(i + 1))).equals(BigInteger.ONE);
		}
		System.out.println("All GCDs are" + (failure ? " not" : "") + " 1");
	}
}


(() => {
    'use strict';

    const main = () => {

        // sternBrocot :: Generator [Int]
        const sternBrocot = () => {
            const go = xs => {
                const x = snd(xs);
                return tail(append(xs, [fst(xs) + x, x]));
            };
            return fmapGen(head, iterate(go, [1, 1]));
        };

        // TESTS ------------------------------------------
        const
            sbs = take(1200, sternBrocot()),
            ixSB = zip(sbs, enumFrom(1));

        return unlines(map(
            JSON.stringify,
            [
                take(15, sbs),
                take(10,
                    map(listFromTuple,
                        nubBy(
                            on(eq, fst),
                            sortBy(
                                comparing(fst),
                                takeWhile(x => 12 !== fst(x), ixSB)
                            )
                        )
                    )
                ),
                listFromTuple(
                    take(1, dropWhile(x => 100 !== fst(x), ixSB))[0]
                ),
                all(tpl => 1 === gcd(fst(tpl), snd(tpl)),
                    take(1000, zip(sbs, tail(sbs)))
                )
            ]
        ));
    };

    // GENERIC ABSTRACTIONS -------------------------------

    // Just :: a -> Maybe a
    const Just = x => ({
        type: 'Maybe',
        Nothing: false,
        Just: x
    });

    // Nothing :: Maybe a
    const Nothing = () => ({
        type: 'Maybe',
        Nothing: true,
    });

    // Tuple (,) :: a -> b -> (a, b)
    const Tuple = (a, b) => ({
        type: 'Tuple',
        '0': a,
        '1': b,
        length: 2
    });

    // | Absolute value.

    // abs :: Num -> Num
    const abs = Math.abs;

    // Determines whether all elements of the structure
    // satisfy the predicate.

    // all :: (a -> Bool) -> [a] -> Bool
    const all = (p, xs) => xs.every(p);

    // append (++) :: [a] -> [a] -> [a]
    // append (++) :: String -> String -> String
    const append = (xs, ys) => xs.concat(ys);

    // chr :: Int -> Char
    const chr = String.fromCodePoint;

    // comparing :: (a -> b) -> (a -> a -> Ordering)
    const comparing = f =>
        (x, y) => {
            const
                a = f(x),
                b = f(y);
            return a < b ? -1 : (a > b ? 1 : 0);
        };

    // dropWhile :: (a -> Bool) -> [a] -> [a]
    // dropWhile :: (Char -> Bool) -> String -> String
    const dropWhile = (p, xs) => {
        const lng = xs.length;
        return 0 < lng ? xs.slice(
            until(
                i => i === lng || !p(xs[i]),
                i => 1 + i,
                0
            )
        ) : [];
    };

    // enumFrom :: a -> [a]
    function* enumFrom(x) {
        let v = x;
        while (true) {
            yield v;
            v = succ(v);
        }
    }

    // eq (==) :: Eq a => a -> a -> Bool
    const eq = (a, b) => {
        const t = typeof a;
        return t !== typeof b ? (
            false
        ) : 'object' !== t ? (
            'function' !== t ? (
                a === b
            ) : a.toString() === b.toString()
        ) : (() => {
            const aks = Object.keys(a);
            return aks.length !== Object.keys(b).length ? (
                false
            ) : aks.every(k => eq(a[k], b[k]));
        })();
    };

    // fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
    function* fmapGen(f, gen) {
        const g = gen;
        let v = take(1, g)[0];
        while (0 < v.length) {
            yield(f(v))
            v = take(1, g)[0]
        }
    }

    // fst :: (a, b) -> a
    const fst = tpl => tpl[0];

    // gcd :: Int -> Int -> Int
    const gcd = (x, y) => {
        const
            _gcd = (a, b) => (0 === b ? a : _gcd(b, a % b)),
            abs = Math.abs;
        return _gcd(abs(x), abs(y));
    };

    // head :: [a] -> a
    const head = xs => xs.length ? xs[0] : undefined;

    // isChar :: a -> Bool
    const isChar = x =>
        ('string' === typeof x) && (1 === x.length);

    // iterate :: (a -> a) -> a -> Gen [a]
    function* iterate(f, x) {
        let v = x;
        while (true) {
            yield(v);
            v = f(v);
        }
    }

    // Returns Infinity over objects without finite length
    // this enables zip and zipWith to choose the shorter
    // argument when one is non-finite, like cycle, repeat etc

    // length :: [a] -> Int
    const length = xs => xs.length || Infinity;

    // listFromTuple :: (a, a ...) -> [a]
    const listFromTuple = tpl =>
        Array.from(tpl);

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) => xs.map(f);

    // nubBy :: (a -> a -> Bool) -> [a] -> [a]
    const nubBy = (p, xs) => {
        const go = xs => 0 < xs.length ? (() => {
            const x = xs[0];
            return [x].concat(
                go(xs.slice(1)
                    .filter(y => !p(x, y))
                )
            )
        })() : [];
        return go(xs);
    };

    // e.g. sortBy(on(compare,length), xs)

    // on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
    const on = (f, g) => (a, b) => f(g(a), g(b));

    // ord :: Char -> Int
    const ord = c => c.codePointAt(0);

    // snd :: (a, b) -> b
    const snd = tpl => tpl[1];

    // sortBy :: (a -> a -> Ordering) -> [a] -> [a]
    const sortBy = (f, xs) =>
        xs.slice()
        .sort(f);

    // succ :: Enum a => a -> a
    const succ = x =>
        isChar(x) ? (
            chr(1 + ord(x))
        ) : isNaN(x) ? (
            undefined
        ) : 1 + x;

    // tail :: [a] -> [a]
    const tail = xs => 0 < xs.length ? xs.slice(1) : [];

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, xs) =>
        xs.constructor.constructor.name !== 'GeneratorFunction' ? (
            xs.slice(0, n)
        ) : [].concat.apply([], Array.from({
            length: n
        }, () => {
            const x = xs.next();
            return x.done ? [] : [x.value];
        }));

    // takeWhile :: (a -> Bool) -> [a] -> [a]
    // takeWhile :: (Char -> Bool) -> String -> String
    const takeWhile = (p, xs) =>
        xs.constructor.constructor.name !==
        'GeneratorFunction' ? (() => {
            const lng = xs.length;
            return 0 < lng ? xs.slice(
                0,
                until(
                    i => lng === i || !p(xs[i]),
                    i => 1 + i,
                    0
                )
            ) : [];
        })() : takeWhileGen(p, xs);

    // takeWhileGen :: (a -> Bool) -> Gen [a] -> [a]
    const takeWhileGen = (p, xs) => {
        const ys = [];
        let
            nxt = xs.next(),
            v = nxt.value;
        while (!nxt.done && p(v)) {
            ys.push(v);
            nxt = xs.next();
            v = nxt.value
        }
        return ys;
    };

    // uncons :: [a] -> Maybe (a, [a])
    const uncons = xs => {
        const lng = length(xs);
        return (0 < lng) ? (
            lng < Infinity ? (
                Just(Tuple(xs[0], xs.slice(1))) // Finite list
            ) : (() => {
                const nxt = take(1, xs);
                return 0 < nxt.length ? (
                    Just(Tuple(nxt[0], xs))
                ) : Nothing();
            })() // Lazy generator
        ) : Nothing();
    };

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // until :: (a -> Bool) -> (a -> a) -> a -> a
    const until = (p, f, x) => {
        let v = x;
        while (!p(v)) v = f(v);
        return v;
    };

    // Use of `take` and `length` here allows for zipping with non-finite
    // lists - i.e. generators like cycle, repeat, iterate.

    // zip :: [a] -> [b] -> [(a, b)]
    const zip = (xs, ys) => {
        const lng = Math.min(length(xs), length(ys));
        return Infinity !== lng ? (() => {
            const bs = take(lng, ys);
            return take(lng, xs).map((x, i) => Tuple(x, bs[i]));
        })() : zipGen(xs, ys);
    };

    // zipGen :: Gen [a] -> Gen [b] -> Gen [(a, b)]
    const zipGen = (ga, gb) => {
        function* go(ma, mb) {
            let
                a = ma,
                b = mb;
            while (!a.Nothing && !b.Nothing) {
                let
                    ta = a.Just,
                    tb = b.Just
                yield(Tuple(fst(ta), fst(tb)));
                a = uncons(snd(ta));
                b = uncons(snd(tb));
            }
        }
        return go(uncons(ga), uncons(gb));
    };

    // MAIN ---
    return main();
})();


def until(cond; update):
  def _until:
    if cond then . else (update | _until) end;
  try _until catch if .== "break" then empty else . end ;

def gcd(a; b):
  # subfunction expects [a,b] as input
  # i.e. a ~ .[0] and b ~ .[1]
  def rgcd: if .[1] == 0 then .[0]
         else [.[1], .[0] % .[1]] | rgcd
         end;
  [a,b] | rgcd ;


using Printf

function sternbrocot(f::Function=(x) -> length(x) ≥ 20)::Vector{Int}
    rst = Int[1, 1]
    i = 2
    while !f(rst)
        append!(rst, Int[rst[i] + rst[i-1], rst[i]])
        i += 1
    end
    return rst
end

println("First 15 elements of Stern-Brocot series:\n", sternbrocot(x -> length(x) ≥ 15)[1:15], "\n")

for i in (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 100)
    occurr = findfirst(x -> x == i, sternbrocot(x -> i ∈ x))
    @printf("Index of first occurrence of %3i in the series: %4i\n", i, occurr)
end

print("\nAssertion: the greatest common divisor of all the two\nconsecutive members of the series up to the 1000th member, is always one: ")
sb = sternbrocot(x -> length(x) > 1000)
if all(gcd(prev, this) == 1 for (prev, this) in zip(sb[1:1000], sb[2:1000]))
    println("Confirmed.")
else
    println("Rejected.")
end


// version 1.1.0

val sbs = mutableListOf(1, 1)

fun sternBrocot(n: Int, fromStart: Boolean = true) {
    if (n < 4 || (n % 2 != 0)) throw IllegalArgumentException("n must be >= 4 and even")
    var consider = if (fromStart) 1 else n / 2 - 1
    while (true) {
        val sum = sbs[consider] + sbs[consider - 1]
        sbs.add(sum)
        sbs.add(sbs[consider])
        if (sbs.size == n) break
        consider++
    }
}

fun gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)

fun main(args: Array<String>) {
    var n = 16  // needs to be even to ensure 'considered' number is added
    println("First 15 members of the Stern-Brocot sequence")
    sternBrocot(n)
    println(sbs.take(15))

    val firstFind = IntArray(11)  // all zero by default
    firstFind[0] = -1 // needs to be non-zero for subsequent test
    for ((i, v) in sbs.withIndex())
        if (v <= 10 && firstFind[v] == 0) firstFind[v] = i + 1
    loop@ while (true) {
        n += 2
        sternBrocot(n, false)
        val vv = sbs.takeLast(2)
        var m = n - 1
        for (v in vv) {
            if (v <= 10 && firstFind[v] == 0) firstFind[v] = m
            if (firstFind.all { it != 0 }) break@loop
            m++
        }
    }
    println("\nThe numbers 1 to 10 first appear at the following indices:")
    for (i in 1..10) println("${"%2d".format(i)} -> ${firstFind[i]}")

    print("\n100 first appears at index ")
    while (true) {
        n += 2
        sternBrocot(n, false)
        val vv = sbs.takeLast(2)
        if (vv[0] == 100) {
            println(n - 1); break
        }
        if (vv[1] == 100) {
            println(n); break
        }
    }

    print("\nThe GCDs of each pair of the series up to the 1000th member are ")
    for (p in 0..998 step 2) {
        if (gcd(sbs[p], sbs[p + 1]) != 1) {
            println("not all one")
            return
        }
    }
    println("all one")
}


-- Task 1
function sternBrocot (n)
    local sbList, pos, c = {1, 1}, 2
    repeat
        c = sbList[pos]
        table.insert(sbList, c + sbList[pos - 1])
        table.insert(sbList, c)
        pos = pos + 1
    until #sbList >= n
    return sbList
end

-- Return index in table 't' of first value matching 'v'
function findFirst (t, v)
    for key, value in pairs(t) do
        if v then
            if value == v then return key end
        else
            if value ~= 0 then return key end
        end
    end
    return nil
end

-- Return greatest common divisor of 'x' and 'y'
function gcd (x, y)
    if y == 0 then
        return math.abs(x)
    else
        return gcd(y, x % y)
    end
end

-- Check GCD of adjacent values in 't' up to 1000 is always 1
function task5 (t)
    for pos = 1, 1000 do
        if gcd(t[pos], t[pos + 1]) ~= 1 then return "FAIL" end
    end
    return "PASS"
end

-- Main procedure
local sb = sternBrocot(10000)
io.write("Task 2: ")
for n = 1, 15 do io.write(sb[n] .. " ") end
print("\n\nTask 3:")
for i = 1, 10 do print("\t" .. i, findFirst(sb, i)) end
print("\nTask 4: " .. findFirst(sb, 100))
print("\nTask 5: " .. task5(sb))


            NORMAL MODE IS INTEGER
            VECTOR VALUES FRST15 = $20HFIRST 15 NUMBERS ARE*$
            VECTOR VALUES FRSTAT = $6HFIRST ,I3,S1,11HAPPEARS AT ,I4*$
            VECTOR VALUES NUMBER = $I4*$

            DIMENSION STERN(1200)
            STERN(1) = 1
            STERN(2) = 1

          R GENERATE FIRST 1200 MEMBERS OF THE STERN-BROCOT SEQUENCE
            THROUGH GENSEQ, FOR I = 1, 1, I .GE. 600
            STERN(I*2-1) = STERN(I) + STERN(I-1)
GENSEQ      STERN(I*2) = STERN(I)

          R PRINT FIRST 15 VALUES OF STERN-BROCOT SEQUENCE
            PRINT FORMAT FRST15
            THROUGH P15, FOR I = 1, 1, I .G. 15
P15         PRINT ON LINE FORMAT NUMBER, STERN(I)

          R PRINT FIRST OCCURRENCE OF 1..10
            THROUGH FRST10, FOR I = 1, 1, I .G. 10
FRST10      PRINT FORMAT FRSTAT, I, FIRST.(I)
            PRINT FORMAT FRSTAT, 100, FIRST.(100)

          R SEARCH FOR FIRST OCCURRENCE OF N IN SEQUENCE
            INTERNAL FUNCTION(N)
            ENTRY TO FIRST.
            THROUGH SCAN, FOR K = 1, 1, I .G. 1200
SCAN        WHENEVER N .E. STERN(K), FUNCTION RETURN K
            END OF FUNCTION
            END OF PROGRAM


sb = {1, 1};
Do[
 sb = sb~Join~{[email protected][[i - 1 ;; i]], sb[[i]]}
 ,
 {i, 2, 1000}
 ]
Take[sb, 15]
Flatten[FirstPosition[sb, #] & /@ Range[10]]
[email protected][sb, 100]
AllTrue[Partition[Take[sb, 1000], 2, 1], Apply[GCD] /* EqualTo[1]]


MODULE SternBrocot;
FROM InOut IMPORT WriteString, WriteCard, WriteLn;

CONST Amount = 1200;

VAR stern: ARRAY [1..Amount] OF CARDINAL;
    i: CARDINAL;

PROCEDURE GCD(a,b: CARDINAL): CARDINAL;
    VAR c: CARDINAL;
BEGIN
    WHILE b # 0 DO
        c := a MOD b;
        a := b;
        b := c;
    END;
    RETURN a;
END GCD;

PROCEDURE Generate;
    VAR i: CARDINAL;
BEGIN
    stern[1] := 1;
    stern[2] := 1;
    FOR i := 2 TO Amount DIV 2 DO
        stern[i*2 - 1] := stern[i] + stern[i-1];
        stern[i*2] := stern[i];
    END;
END Generate;

PROCEDURE FindFirst(n: CARDINAL): CARDINAL;
    VAR i: CARDINAL;
BEGIN
    FOR i := 1 TO Amount DO
        IF stern[i] = n THEN
            RETURN i;
        END;
    END;
END FindFirst;

PROCEDURE ShowFirst(n: CARDINAL);
BEGIN
    WriteString("First");
    WriteCard(n,4);
    WriteString(" at ");
    WriteCard(FindFirst(n), 4);
    WriteLn;
END ShowFirst;

BEGIN
    Generate;

    WriteString("First 15 numbers:");
    FOR i := 1 TO 15 DO
        WriteCard(stern[i], 2);
    END;
    WriteLn;

    FOR i := 1 TO 10 DO
        ShowFirst(i);
    END;
    ShowFirst(100);
    WriteLn;

    FOR i := 2 TO Amount DO
        IF GCD(stern[i-1], stern[i]) # 1 THEN
            WriteString("GCD of adjacent elements not 1 at: ");
            WriteCard(i-1, 4);
            WriteLn;
            HALT;
        END;
    END;
    WriteString("The GCD of every pair of adjacent elements is 1.");
    WriteLn;
END SternBrocot.


import math, strformat, strutils

iterator sternBrocot(): (int, int) =
  ## Yield index and value of the terms of the sequence.
  var sequence: seq[int]
  sequence.add 1
  sequence.add 1
  var index = 1
  yield (1, 1)
  yield (2, 1)
  while true:
    sequence.add sequence[index] + sequence[index - 1]
    yield (sequence.len, sequence[^1])
    sequence.add sequence[index]
    yield (sequence.len, sequence[^1])
    inc index

# Fiind first 15 terms.
var res: seq[int]
for i, n in sternBrocot():
  res.add n
  if i == 15: break
echo "First 15 terms: ", res.join(" ")
echo()

# Find indexes for 1..10.
var indexes: array[1..10, int]
var toFind = 10
for i, n in sternBrocot():
  if n in 1..10 and indexes[n] == 0:
    indexes[n] = i
    dec toFind
    if toFind == 0: break
for n in 1..10:
  echo &"Index of first occurrence of number {n:3}: {indexes[n]:4}"

# Find index for 100.
var index: int
for i, n in sternBrocot():
  if n == 100:
    index = i
    break
echo &"Index of first occurrence of number 100: {index:4}"
echo()

# Check GCD.
var prev = 1
index = 1
for i, n in sternBrocot():
  if gcd(prev, n) != 1: break
  prev = n
  inc index
  if index > 1000: break
if index <= 1000:
  echo "Found two successive terms at index: ", index
else:
  echo "All consecutive terms up to the 1000th member have a GCD equal to one."


: stern(n)
| l i |
   ListBuffer new dup add(1) dup add(1) dup ->l
   n 1- 2 / loop: i [ l at(i) l at(i 1+) tuck + l add l add ]
   n 2 mod ifFalse: [ dup removeLast drop ] dup freeze ;

stern(10000) Constant new: Sterns


\\ Stern-Brocot sequence
\\ 5/27/16 aev
SternBrocot(n)={
my(L=List([1,1]),k=2); if(n<3,return(L));
for(i=2,n, listput(L,L[i]+L[i-1]); if(k++>=n, break); listput(L,L[i]);if(k++>=n, break));
return(Vec(L));
}
\\ Find the first item in any list starting with sind index (return 0 or index).
\\ 9/11/2015 aev
findinlist(list, item, sind=1)={
my(idx=0, ln=#list); if(ln==0 || sind<1 || sind>ln, return(0));
for(i=sind, ln, if(list[i]==item, idx=i; break;)); return(idx);
}
{
\\ Required tests:
my(v,j);
v=SternBrocot(15);
print1("The first 15: "); print(v);
v=SternBrocot(1200);
print1("The first [email protected]: "); \\print(v);
for(i=1,10, if(j=findinlist(v,i), print1(i,"@",j,", ")));
if(j=findinlist(v,100), print(100,"@",j));
v=SternBrocot(10000);
print1("All GCDs=1?: ");
j=1; for(i=2,10000, j*=gcd(v[i-1],v[i]));
if(j==1, print("Yes"), print("No"));
}


program StrnBrCt;
{$IFDEF FPC}
  {$MODE DELPHI}
{$ENDIF}
const
  MaxCnt = 10835282;{ seq[i] < 65536 = high(Word) }
//MaxCnt = 500*1000*1000;{ 2Gbyte -> real 0.85 s user 0.31 }
type
  tSeqdata =  word;//cardinal LongWord
  pSeqdata = pWord;//pcardinal pLongWord
  tseq = array of tSeqdata;

function SternBrocotCreate(size:NativeInt):tseq;
var
  pSeq,pIns : pSeqdata;
  PosIns : NativeInt;
  sum : tSeqdata;
Begin
  setlength(result,Size+1);
  dec(Size); //== High(result)
  pIns := @result[size];// set at end
  PosIns := -size+2;    // negative index campare to 0
  pSeq := @result[0];

  sum := 1;
  pSeq[0]:= sum;pSeq[1]:= sum;
  repeat
    pIns[PosIns+1] := sum;//append copy of considered
    inc(sum,pSeq[0]);
    pIns[PosIns  ] := sum;
    inc(pSeq);
    inc(PosIns,2);sum := pSeq[1];//aka considered
  until PosIns>= 0;
  setlength(result,length(result)-1);
end;

function FindIndex(const s:tSeq;value:tSeqdata):NativeInt;
Begin
  result := 0;
  while result <= High(s) do
  Begin
    if s[result] = value then
      EXIT(result+1);
    inc(result);
  end;
end;

function gcd_iterative(u, v: NativeInt): NativeInt;
//http://rosettacode.org/wiki/Greatest_common_divisor#Pascal_.2F_Delphi_.2F_Free_Pascal
var
  t: NativeInt;
begin
  while v <> 0 do begin
    t := u;u := v;v := t mod v;
  end;
  gcd_iterative := abs(u);
end;

var
  seq : tSeq;
  i : nativeInt;
Begin
  seq:= SternBrocotCreate(MaxCnt);
// Show the first fifteen members of the sequence.
  For i := 0 to 13 do write(seq[i],',');writeln(seq[14]);
//Show the (1-based) index of where the numbers 1-to-10 first appears in the
  For i := 1 to 10 do
    write(i,' @ ',FindIndex(seq,i),',');
  writeln(#8#32);
//Show the (1-based) index of where the number 100 first appears in the sequence.
  writeln(100,' @ ',FindIndex(seq,100));
//Check that the greatest common divisor of all the two consecutive members of the series up to the 1000th member, is always one.
  i := 999;
  if i > High(seq) then
    i := High(seq);
  Repeat
    IF gcd_iterative(seq[i],seq[i+1]) <>1 then
    Begin
      writeln(' failure at  ',i+1,'  ',seq[i],'  ',seq[i+1]);
      BREAK;
    end;
    dec(i);
  until i <0;
  IF i< 0 then
    writeln('GCD-test is O.K.');
  setlength(seq,0);
end.


use strict;
use warnings;

sub stern_brocot {
    my @list = (1, 1);
    sub {
	push @list, $list[0] + $list[1], $list[1];
	shift @list;
    }
}

{
    my $generator = stern_brocot;
    print join ' ', map &$generator, 1 .. 15;
    print "\n";
}

for (1 .. 10, 100) {
    my $index = 1;
    my $generator = stern_brocot;
    $index++ until $generator->() == $_;
    print "first occurrence of $_ is at index $index\n";
}

{
    sub gcd {
	my ($u, $v) = @_;
	$v ? gcd($v, $u % $v) : abs($u);
    }
    my $generator = stern_brocot;
    my ($a, $b) = ($generator->(), $generator->());
    for (1 .. 1000) {
	die "unexpected GCD for $a and $b" unless gcd($a, $b) == 1;
	($a, $b) = ($b, $generator->());
    }
}


sequence sb = {1,1}
integer c = 2

function stern_brocot(integer n)
    while length(sb)<n do
        sb &= sb[c]+sb[c-1] & sb[c]
        c += 1
    end while
    return sb[1..n]
end function

sequence s = stern_brocot(15)
puts(1,"first 15:")
?s
integer n = 16, k
sequence idx = tagset(10)
for i=1 to length(idx) do
    while 1 do
        k = find(idx[i],s)
        if k!=0 then exit end if
        n *= 2
        s = stern_brocot(n)
    end while
    idx[i] = k
end for
puts(1,"indexes of 1..10:")
?idx
puts(1,"index of 100:")
while 1 do
    k = find(100,s)
    if k!=0 then exit end if
    n *= 2
    s = stern_brocot(n)
end while
?k
s = stern_brocot(1000)
integer maxgcd = 1
for i=1 to 999 do
    maxgcd = max(gcd(s[i],s[i+1]),maxgcd)
end for
printf(1,"max gcd:%d\n",{maxgcd})


(de nmbr (N)
   (let (A 1  B 0)
      (while (gt0 N)
         (if (bit? 1 N)
            (inc 'B A)
            (inc 'A B) )
         (setq N (>> 1 N)) )
      B ) )

(let Lst (mapcar nmbr (range 1 2000))
   (println 'First-15: (head 15 Lst))
   (for N 10
      (println 'First N 'found 'at: (index N Lst)) )
   (println 'First 100 'found 'at: (index 100 Lst))
   (for (L Lst (cdr L) (cddr L))
      (test 1 (gcd (car L) (cadr L))) )
   (prinl "All consecutive pairs are relative prime!") )


sternBrocot: procedure options(main);
    %replace MAX by 1200;
    declare S(1:MAX) fixed;

    /* find the first occurrence of N in S */
    findFirst: procedure(n) returns(fixed);
        declare (n, i) fixed;
        do i=1 to MAX;
            if S(i)=n then return(i);
        end;
    end findFirst;

    /* find the greatest common divisor of A and B */
    gcd: procedure(a, b) returns(fixed) recursive;
        declare (a, b) fixed;
        if b = 0 then return(a);
        return(gcd(b, mod(a, b)));
    end gcd;

    /* calculate S(i) up to MAX */
    declare i fixed;
    S(1) = 1; S(2) = 1;
    do i=2 to MAX/2;
        S(i*2-1) = S(i) + S(i-1);
        S(i*2) = S(i);
    end;

    /* print first 15 elements */
    put skip list('First 15 elements: ');
    do i=1 to 15;
        put edit(S(i)) (F(2));
    end;

    /* find first occurrences of 1..10 and 100 */
    do i=1 to 10;
        put skip list('First',i,'at',findFirst(i));
    end;
    put skip list('First   ',100,'at',findFirst(100));

    /* check GCDs of adjacent pairs up to 1000th element */
    do i=2 to 1000;
        if gcd(S(i-1),S(i)) ^= 1 then do;
            put skip list('GCD of adjacent pair not 1 at i=',i);
            stop;
        end;
    end;
    put skip list('All GCDs of adjacent pairs are 1.');
end sternBrocot;


100H:
/* FIND LOCATION OF FIRST ELEMENT IN ARRAY */
FIND$FIRST: PROCEDURE (ARR, EL) ADDRESS;
    DECLARE (ARR, N) ADDRESS, (EL, A BASED ARR) BYTE;
    N = 0;
LOOP:
    IF A(N) = EL THEN RETURN N;
    ELSE N = N + 1;
    GO TO LOOP;
END FIND$FIRST;

/* CP/M CALL */
BDOS: PROCEDURE (FN, ARG);
    DECLARE FN BYTE, ARG ADDRESS;
    GO TO 5;
END BDOS;

PRINT: PROCEDURE (STRING);
    DECLARE STRING ADDRESS;
    CALL BDOS(9, STRING);
END PRINT;

/* PRINT NUMBER */
PRINT$NUMBER: PROCEDURE (N);
    DECLARE S (6) BYTE INITIAL ('.....$');
    DECLARE (N, P) ADDRESS, C BASED P BYTE;
    P = .S(5);
DIGIT:
    P = P - 1;
    C = N MOD 10 + '0';
    IF (N := N / 10) > 0 THEN GO TO DIGIT;
    CALL PRINT(P);
END PRINT$NUMBER;

/* GENERATE FIRST 1200 ELEMENTS OF STERN-BROCOT SEQUENCE */
DECLARE S (1201) BYTE, I ADDRESS;
S(1) = 1;
S(2) = 1;
DO I = 2 TO 600;
    S(I*2-1) = S(I) + S(I-1);
    S(I*2) = S(I);
END;

/* PRINT FIRST 15 ELEMENTS */
CALL PRINT(.'FIRST 15 ELEMENTS: $');
DO I = 1 TO 15;
    CALL PRINT$NUMBER(S(I));
    CALL PRINT(.' $');
END;
CALL PRINT(.(13,10,'$'));

/* PRINT FIRST OCCURRENCE OF N */
PRINT$FIRST: PROCEDURE (N);
    DECLARE N BYTE;
    CALL PRINT(.'FIRST $');
    CALL PRINT$NUMBER(N);
    CALL PRINT(.' AT $');
    CALL PRINT$NUMBER(FIND$FIRST(.S, N));
    CALL PRINT(.(13,10,'$'));
END PRINT$FIRST;

DO I = 1 TO 10;
    CALL PRINT$FIRST(I);
END;
CALL PRINT$FIRST(100);

/* CHECK GCDS */
GCD: PROCEDURE (A, B) BYTE;
    DECLARE (A, B, C) BYTE;
LOOP:
    C = A;
    A = B;
    B = C MOD A;
    IF B <> 0 THEN GO TO LOOP;
    RETURN A;
END GCD;

DO I = 2 TO 1000;
    IF GCD(S(I-1),S(I)) <> 1 THEN DO;
        CALL PRINT(.'GCD NOT 1 AT: $');
        CALL PRINT$NUMBER(I);
        CALL BDOS(0,0);
    END;
END;

CALL PRINT(.'ALL GCDS ARE 1$');
CALL BDOS(0,0);
EOF


# An iterative approach
function iter_sb($count = 2000)
{
    # Taken from RosettaCode GCD challenge
    function Get-GCD ($x, $y)
    {
        if ($y -eq 0) { $x } else { Get-GCD $y ($x%$y) }
    }

    $answer = @(1,1)
    $index = 1
    while ($answer.Length -le $count)
    {
        $answer += $answer[$index] + $answer[$index - 1]
        $answer += $answer[$index]
        $index++
    }

    0..14 | foreach {$answer[$_]}

    1..10 | foreach {'Index of {0}: {1}' -f $_, ($answer.IndexOf($_) + 1)}

    'Index of 100: {0}' -f ($answer.IndexOf(100) + 1)

    [bool] $gcd = $true
    1..999 | foreach {$gcd = $gcd -and ((Get-GCD $answer[$_] $answer[$_ - 1]) -eq 1)}
    'GCD = 1 for first 1000 members: {0}' -f $gcd
}


EnableExplicit
Define.i i

If OpenConsole("")
  PrintN("Stern-Brocot_sequence")
Else
  End 1
EndIf

Procedure.i f(n.i)
  If n<2
    ProcedureReturn n
  ElseIf n&1
    ProcedureReturn f(n/2)+f(n/2+1)
  Else
    ProcedureReturn f(n/2)
  EndIf
EndProcedure

Procedure.i gcd(a.i,b.i)
  If b : ProcedureReturn gcd(b,a%b) : EndIf
  ProcedureReturn a
EndProcedure

Procedure.i ind(m.i)
  Define.i i=1
  While f(i)<>m : i+1 : Wend
  ProcedureReturn i
EndProcedure

Print("First 15 elements: ")
For i=1 To 15
  Print(Str(f(i))+Space(3))
Next
PrintN(~"\n")

For i=1 To 10
  PrintN(RSet(Str(i),3)+" is at pos. #"+Str(ind(i)))
Next
PrintN("100 is at pos. #"+Str(ind(100)))
PrintN("")

i=1
While i<1000 And gcd(f(i),f(i+1))=1 : i+1 : Wend
If i=1000
  PrintN("All GCDs are 1.")
Else
  PrintN("GCD of "+Str(i)+" and "+Str(i+1)+" is not 1")
EndIf

Input()


def stern_brocot(predicate=lambda series: len(series) < 20):
    """\
    Generates members of the stern-brocot series, in order, returning them when the predicate becomes false

    >>> print('The first 10 values:',
              stern_brocot(lambda series: len(series) < 10)[:10])
    The first 10 values: [1, 1, 2, 1, 3, 2, 3, 1, 4, 3]
    >>>
    """

    sb, i = [1, 1], 0
    while predicate(sb):
        sb += [sum(sb[i:i + 2]), sb[i + 1]]
        i += 1
    return sb

if __name__ == '__main__':
    from fractions import gcd

    n_first = 15
    print('The first %i values:\n  ' % n_first,
          stern_brocot(lambda series: len(series) < n_first)[:n_first])
    print()
    n_max = 10
    for n_occur in list(range(1, n_max + 1)) + [100]:
        print('1-based index of the first occurrence of %3i in the series:' % n_occur,
              stern_brocot(lambda series: n_occur not in series).index(n_occur) + 1)
              # The following would be much faster. Note that new values always occur at odd indices
              # len(stern_brocot(lambda series: n_occur != series[-2])) - 1)

    print()
    n_gcd = 1000
    s = stern_brocot(lambda series: len(series) < n_gcd)[:n_gcd]
    assert all(gcd(prev, this) == 1
               for prev, this in zip(s, s[1:])), 'A fraction from adjacent terms is reducible'


  [ [ dup while
      tuck mod again ]
    drop abs ]           is gcd       ( n n --> n   )

  [ 2dup peek
    dip [ 1+ 2dup peek ]
    over + swap join
    swap dip join ]      is two-terms ( [ n --> [ n )

  ' [ 1 1 ] 0
  8 times two-terms
  over 15 split drop
  witheach [ echo sp ] cr
  [ two-terms
    over -2 peek 100 = until ]
  drop
  10 times
   [ i^ 1+ over find 1+ echo sp ] cr
  dup size 1 - echo cr
  false swap
  behead swap witheach
    [ tuck gcd 1 != if
        [ dip not conclude ] ]
  drop iff
    [ say "Reducible pair found." ]
  else
    [ say "No reducible pairs found." ]


## Stern-Brocot sequence
## 12/19/16 aev
SternBrocot <- function(n){
  V <- 1; k <- n/2;
  for (i in 1:k)
    { V[2*i] = V[i]; V[2*i+1] = V[i] + V[i+1];}
  return(V);
}

## Required tests:
require(pracma);
{
cat(" *** The first 15:",SternBrocot(15),"\n");
cat(" *** The first [email protected]:","\n");
V=SternBrocot(40);
for (i in 1:10) {j=match(i,V); cat(i,"@",j,",")}
V=SternBrocot(1200);
i=100; j=match(i,V); cat(i,"@",j,"\n");
V=SternBrocot(1000); j=1;
for (i in 2:1000) {j=j*gcd(V[i-1],V[i])}
if(j==1) {cat(" *** All GCDs=1!\n")} else {cat(" *** All GCDs!=1??\n")}
}


#lang racket
;; OEIS Definition
;; A002487
;;   Stern's diatomic series
;;   (or Stern-Brocot sequence):
;;     a(0) = 0, a(1) = 1;
;;     for n > 0:
;;       a(2*n) = a(n),
;;       a(2*n+1) = a(n) + a(n+1).
(define A002487
  (let ((memo (make-hash '((0 . 0) (1 . 1)))))
    (lambda (n)
      (hash-ref! memo n
                 (lambda ()
                   (define n/2 (quotient n 2))
                   (+ (A002487 n/2) (if (even? n) 0 (A002487 (add1 n/2)))))))))

(define Stern-Brocot A002487)

(displayln "Show the first fifteen members of the sequence.
(This should be: 1, 1, 2, 1, 3, 2, 3, 1, 4, 3, 5, 2, 5, 3, 4)")
(for/list ((i (in-range 1 (add1 15)))) (Stern-Brocot i))

(displayln "Show the (1-based) index of where the numbers 1-to-10 first appears in the sequence.")
(for ((n (in-range 1 (add1 10))))
  (for/first ((i (in-naturals 1))
              #:when (= n (Stern-Brocot i)))
    (printf "~a first found at a(~a)~%" n i)))

(displayln "Show the (1-based) index of where the number 100 first appears in the sequence.")
(for/first ((i (in-naturals 1)) #:when (= 100 (Stern-Brocot i))) i)

(displayln "Check that the greatest common divisor of all the two consecutive members of the
series up to the 1000th member, is always one.")
(unless
    (for/first ((i (in-range 1 1000))
                #:unless (= 1 (gcd (Stern-Brocot i) (Stern-Brocot (add1 i))))) #t)
  (display "\tdidn't find gcd > (or otherwise ≠) 1"))


constant @Stern-Brocot = 1, 1, { |(@_[$_ - 1] + @_[$_], @_[$_]) given ++$ } ... *;

put @Stern-Brocot[^15];

for flat 1..10, 100 -> $ix {
    say "First occurrence of {$ix.fmt('%3d')} is at index: {([email protected]($ix, :k)).fmt('%4d')}";
}

say so 1 == all map ^1000: { [gcd] @Stern-Brocot[$_, $_ + 1] }


/*REXX program generates & displays a Stern─Brocot sequence; finds 1─based indices; GCDs*/
parse arg N idx fix chk .                        /*get optional arguments from the C.L. */
if   N=='' |   N==","  then   N=   15            /*Not specified?  Then use the default.*/
if idx=='' | idx==","  then idx=   10            /* "      "         "   "   "     "    */
if fix=='' | fix==","  then fix=  100            /* "      "         "   "   "     "    */
if chk=='' | chk==","  then chk= 1000            /* "      "         "   "   "     "    */

if N>0  then say center('the first'   N   "numbers in the Stern─Brocot sequence", 70, '═')
a= Stern_Brocot(N)                               /*invoke function to generate sequence.*/
say a                                            /*display the sequence to the terminal.*/
say
say center('the 1─based index for the first'       idx        "integers",   70, '═')
a= Stern_Brocot(-idx)                            /*invoke function to generate sequence.*/
w= length(idx);        do i=1  for idx
                       say 'for '   right(i, w)",  the index is: "          wordpos(i, a)
                       end   /*i*/
say
say center('the 1─based index for'  fix, 70, "═")
a= Stern_Brocot(-fix)                            /*invoke function to generate sequence.*/
say 'for '       fix",  the index is: "      wordpos(fix, a)
say
if chk<2  then exit 0
say center('checking if all two consecutive members have a GCD=1', 70, '═')
a= Stern_Brocot(chk)                             /*invoke function to generate sequence.*/
                       do c=1  for chk-1;    if gcd(subword(a, c, 2))==1  then iterate
                       say 'GCD check failed at index'         c;         exit 13
                       end   /*c*/
say
say '───── All '     chk     " two consecutive members have a GCD of unity."
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
gcd: procedure; $=;     do i=1  for arg();     $= $ arg(i)              /*get arg list. */
                        end   /*i*/
     parse var $ x z .;                if x=0  then x= z                /*is zero case? */
     x=abs(x)                                                           /*use absolute x*/
               do j=2  to words($);    y=abs( word($, j) )
               if y=0  then iterate                                     /*ignore zeros. */
                  do  until y==0;      parse value x//y y  with  y x    /* ◄──heavy work*/
                  end   /*until*/
               end      /*j*/
     return x                                                           /*return the GCD*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
Stern_Brocot:  parse arg h 1 f;                $= 1 1;           if h<0  then h= 1e9
                                                                         else f= 0
               f= abs(f)
                             do k=2  until words($)>=h  |  wordpos(f, $)\==0
                             _= word($, k);      $= $   (_ + word($, k-1) )   _
                             end   /*k*/
               if f==0  then return subword($, 1, h)
                             return $


# Project : Stern-Brocot sequence

limit = 1200
item = list(limit+1)
item[1] = 1
item[2] = 1
nr = 2
gcd = 1
gcdall = 1
for num = 3 to limit
      item[num] = item[nr] + item[nr-1]
      item[num+1] = item[nr]
      nr = nr + 1
      num = num + 1
next
showarray(item,15)

for x = 1 to 100
      if x < 11 or x = 100
         totalitem(x)
      ok
next

for n = 1 to len(item) - 1
      if gcd(item[n],item[n+1]) != 1
         gcdall = gcd
      ok
next

if gcdall = 1
   see "Correct: The first 999 consecutive pairs are relative prime!" + nl
ok

func totalitem(p)
        pos = find(item, p)
        see string(x) + " at Stern #" + pos + "." + nl

func showarray(vect,ln)
        svect = ""
        for n = 1 to ln
              svect = svect + vect[n] + ", "
        next
        svect = left(svect, len(svect) - 2)
        see svect
        see nl

func gcd(gcd,b)
        while b
                  c = gcd
                  gcd = b
                  b = c % b
        end
        return gcd


def sb
  return enum_for :sb unless block_given?
  a=[1,1]
  0.step do |i|
    yield a[i]
    a << a[i]+a[i+1] << a[i+1]
  end
end

puts "First 15: #{sb.first(15)}"

[*1..10,100].each do |n|
  puts "#{n} first appears at #{sb.find_index(n)+1}."
end

if sb.take(1000).each_cons(2).all? { |a,b| a.gcd(b) == 1 }
  puts "All GCD's are 1"
else
  puts "Whoops, not all GCD's are 1!"
end


lazy val sbSeq: Stream[BigInt] = {
  BigInt("1") #::
  BigInt("1") #::
  (sbSeq zip sbSeq.tail zip sbSeq.tail).
  flatMap{ case ((a,b),c) => List(a+b,c) }
}

// Show the results
{
println( s"First 15 members: ${(for( n <- 0 until 15 ) yield sbSeq(n)) mkString( "," )}" )
println
for( n <- 1 to 10; pos = sbSeq.indexOf(n) + 1 ) println( s"Position of first $n is at $pos" )
println
println( s"Position of first 100 is at ${sbSeq.indexOf(100) + 1}" )
println
println( s"Greatest Common Divisor for first 1000 members is 1: " +
  (sbSeq zip sbSeq.tail).take(1000).forall{ case (a,b) => a.gcd(b) == 1 } )
}


; Recursive function to return the Nth Stern-Brocot sequence number.

(define stern-brocot
  (lambda (n)
    (cond
      ((<= n 0)
        0)
      ((<= n 2)
        1)
      ((even? n)
        (stern-brocot (/ n 2)))
      (else
        (let ((earlier (/ (1+ n) 2)))
          (+ (stern-brocot earlier) (stern-brocot (1- earlier))))))))


# Declare a function to generate the Stern-Brocot sequence
func stern_brocot {
    var list = [1, 1]
    {
        list.append(list[0]+list[1], list[1])
        list.shift
    }
}

# Show the first fifteen members of the sequence.
say 15.of(stern_brocot()).join(' ')

# Show the (1-based) index of where the numbers 1-to-10 first appears
# in the sequence, and where the number 100 first appears in the sequence.
for i (1..10, 100) {
    var index = 1
    var generator = stern_brocot()
    while (generator() != i) {
        ++index
    }
    say "First occurrence of #{i} is at index #{index}"
}

# Check that the greatest common divisor of all the two consecutive
# members of the series up to the 1000th member, is always one.
var generator = stern_brocot()
var (a, b) = (generator(), generator())
{
    assert_eq(gcd(a, b), 1)
    a = b
    b = generator()
} * 1000

say "All GCD's are 1"


*       GCD function
        DEFINE('GCD(A,B)')                      :(GCD_END)
GCD     GCD = A
        EQ(B,0)                                 :S(RETURN)
        A = B
        B = REMDR(GCD,B)                        :(GCD)
GCD_END

*       Find first occurrence of element in array
        DEFINE('IDX(ARR,ELM)')                  :(IDX_END)
IDX     IDX = 1
ITEST   EQ(ARR<IDX>,ELM)                        :S(RETURN)
        IDX = IDX + 1                           :(ITEST)
IDX_END

*       Declare array
        SEQ = ARRAY(1200,1)

*       Fill array with Stern-Brocot sequence
        IX = 1
FILL    IX = IX + 1
        SEQ<IX * 2 - 1> = SEQ<IX> + SEQ<IX - 1>
        SEQ<IX * 2> = SEQ<IX>                   :S(FILL)

*       Print first 15 elements
DONE    IX = 1
        S = "First 15 elements:"
P15     S = S " " SEQ<IX>
        IX = IX + 1 LT(IX,15)                   :S(P15)
        OUTPUT = S

*       Print first occurrence of 1..10 and 100
        N = 1
FIRSTN  OUTPUT = "First " N " at " IDX(SEQ,N)
        N = N + 1 LT(N,10)                      :S(FIRSTN)
        OUTPUT = "First 100 at " IDX(SEQ,100)

*       Test GCD between 1000 consecutive members
        IX = 2
GCDTEST EQ(GCD(SEQ<IX - 1>,SEQ<IX>),1)          :F(GCDFAIL)
        IX = IX + 1 LT(IX,1000)                 :S(GCDTEST)
        OUTPUT = "All GCDs are 1."              :(END)
GCDFAIL OUTPUT = "GCD is not 1 at " IX "."

END


struct SternBrocot: Sequence, IteratorProtocol {
  private var seq = [1, 1]

  mutating func next() -> Int? {
    seq += [seq[0] + seq[1], seq[1]]

    return seq.removeFirst()
  }
}

func gcd<T: BinaryInteger>(_ a: T, _ b: T) -> T {
  guard a != 0 else {
    return b
  }

  return a < b ? gcd(b % a, a) : gcd(a % b, b)
}

print("First 15: \(Array(SternBrocot().prefix(15)))")

var found = Set<Int>()

for (i, val) in SternBrocot().enumerated() {
  switch val {
  case 1...10 where !found.contains(val), 100 where !found.contains(val):
    print("First \(val) at \(i + 1)")
    found.insert(val)
  case _:
    continue
  }

  if found.count == 11 {
    break
  }
}

let firstThousand = SternBrocot().prefix(1000)
let gcdIsOne = zip(firstThousand, firstThousand.dropFirst()).allSatisfy({ gcd($0.0, $0.1) == 1 })

print("GCDs of all two consecutive members are \(gcdIsOne ? "" : "not")one")


#!/usr/bin/env tclsh
#

package require generator   ;# from tcllib

namespace eval stern-brocot {
    proc generate {{count 100}} {
        set seq {1 1}
        set n 0
        while {[llength $seq] < $count} {
            lassign [lrange $seq $n $n+1] a b
            lappend seq [expr {$a + $b}] $b
            incr n
        }
        return $seq
    }

    proc genr {} {
        yield [info coroutine]
        set seq {1 1}
        while {1} {
            set seq [lassign $seq a]
            set b [lindex $seq 0]
            set c [expr {$a + $b}]
            lappend seq $c $b
            yield $a
        }
    }

    proc Step {a b args} {
        set c [expr {$a + $b}]
        list $a [list $b {*}$args $c $b]
    }

    generator define gen {} {
        set cmd [list 1 1]
        while {1} {
            lassign [Step {*}$cmd] a cmd
            generator yield $a
        }
    }

    namespace export {[a-z]*}
    namespace ensemble create
}

interp alias {} sb {} stern-brocot

# a simple adaptation of gcd from http://wiki.tcl.tk/2891
proc coprime {a args} {
    set gcd $a
    foreach arg $args {
        while {$arg != 0} {
            set t $arg
            set arg [expr {$gcd % $arg}]
            set gcd $t
            if {$gcd == 1} {return true}
        }
    }
    return false
}

proc main {} {

    puts "#1. First 15 members of the Stern-Brocot sequence:"
    puts \t[generator to list [generator take 16 [sb gen]]]

    puts "#2. First occurrences of 1 through 10:"
    set first {}
    set got 0
    set i 0
    generator foreach x [sb gen] {
        incr i
        if {$x>10} continue
        if {[dict exists $first $x]} continue
        dict set first $x $i
        if {[incr got] >= 10} break
    }
    foreach {a b} [lsort -integer -stride 2 $first] {
        puts "\tFirst $a at $b"
    }

    puts "#3. First occurrence of 100:"
    set i 0
    generator foreach x [sb gen] {
        incr i
        if {$x eq 100} break
    }
    puts "\tFirst $x at $i"

    puts "#4. Check first 1k elements for common divisors:"
    set prev [expr {2*3*5*7*11*13*17*19+1}] ;# a handy prime
    set i 0
    generator foreach x [sb gen] {
        if {[incr i] >= 1000} break
        if {![coprime $x $prev]} {
            error "Element $i, $x is not coprime with $prev!"
        }
        set prev $x
    }
    puts "\tFirst $i elements are all pairwise coprime"
}

main


sb = Array(1,1)
i = 1 'considered
j = 2 'precedent
n = 0 'loop counter
Do
	ReDim Preserve sb(UBound(sb) + 1)
	sb(UBound(sb)) = sb(UBound(sb) - i) + sb(UBound(sb) - j)
	ReDim Preserve sb(UBound(sb) + 1)
	sb(UBound(sb)) = sb(UBound(sb) - j)
	i = i + 1
	j = j + 1
	n = n + 1
Loop Until n = 2000

WScript.Echo "First 15: " & DisplayElements(15)

For k = 1 To 10
	WScript.Echo "The first instance of " & k & " is in #" & ShowFirstInstance(k) & "."
Next

WScript.Echo "The first instance of " & 100 & " is in #" & ShowFirstInstance(100) & "."

Function DisplayElements(n)
	For i = 0 To n - 1
		If i < n - 1 Then
			DisplayElements = DisplayElements & sb(i) & ", "
		Else
			DisplayElements = DisplayElements & sb(i)
		End If
	Next
End Function

Function ShowFirstInstance(n)
	For i = 0 To UBound(sb)
		If sb(i) = n Then
			ShowFirstInstance = i + 1
			Exit For
		End If
	Next
End Function