#include <stdio.h>
#include <stdbool.h>
#include <time.h>

#define n 100
#define nn ((n * (n + 1)) >> 1)

bool Contains(int lst[], int item, int size) {
	for (int i = size - 1; i >= 0; i--)
 		if (item == lst[i]) return true;
	return false;
}

int * MianChowla()
{
	static int mc[n]; mc[0] = 1;
	int sums[nn];	sums[0] = 2;
	int sum, le, ss = 1;
	for (int i = 1; i < n; i++) {
		le = ss;
		for (int j = mc[i - 1] + 1; ; j++) {
			mc[i] = j;
			for (int k = 0; k <= i; k++) {
				sum = mc[k] + j;
				if (Contains(sums, sum, ss)) {
					ss = le; goto nxtJ;
				}
				sums[ss++] = sum;
			}
			break;
		nxtJ:;
		}
	}
	return mc;
}

int main() {
	clock_t st = clock(); int * mc; mc = MianChowla();
        double et = ((double)(clock() - st)) / CLOCKS_PER_SEC;
	printf("The first 30 terms of the Mian-Chowla sequence are:\n");
	for (int i = 0; i < 30; i++) printf("%d ", mc[i]);
	printf("\n\nTerms 91 to 100 of the Mian-Chowla sequence are:\n");
	for (int i = 90; i < 100; i++) printf("%d ", mc[i]);
	printf("\n\nComputation time was %f seconds.", et);
}


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

static class Program {
    static int[] MianChowla(int n) {
        int[] mc = new int[n - 1 + 1];
        HashSet<int> sums = new HashSet<int>(), ts = new HashSet<int>();
        int sum; mc[0] = 1; sums.Add(2);
        for (int i = 1; i <= n - 1; i++) {
            for (int j = mc[i - 1] + 1; ; j++) {
                mc[i] = j;
                for (int k = 0; k <= i; k++) {
                    sum = mc[k] + j;
                    if (sums.Contains(sum)) { ts.Clear(); break; }
                    ts.Add(sum);
                }
                if (ts.Count > 0) { sums.UnionWith(ts); break; }
            }
        }
        return mc;
    }

    static void Main(string[] args)
    {
        const int n = 100; Stopwatch sw = new Stopwatch();
        string str = " of the Mian-Chowla sequence are:\n";
        sw.Start(); int[] mc = MianChowla(n); sw.Stop();
        Console.Write("The first 30 terms{1}{2}{0}{0}Terms 91 to 100{1}{3}{0}{0}" +
            "Computation time was {4}ms.{0}", '\n', str, string.Join(" ", mc.Take(30)),
            string.Join(" ", mc.Skip(n - 10)), sw.ElapsedMilliseconds);
    }
}


using namespace std;

#include <iostream>
#include <ctime>

#define n 100
#define nn ((n * (n + 1)) >> 1)

bool Contains(int lst[], int item, int size) {
	for (int i = 0; i < size; i++) if (item == lst[i]) return true;
	return false;
}

int * MianChowla()
{
	static int mc[n]; mc[0] = 1;
	int sums[nn];	sums[0] = 2;
	int sum, le, ss = 1;
	for (int i = 1; i < n; i++) {
		le = ss;
		for (int j = mc[i - 1] + 1; ; j++) {
			mc[i] = j;
			for (int k = 0; k <= i; k++) {
				sum = mc[k] + j;
				if (Contains(sums, sum, ss)) {
					ss = le; goto nxtJ;
				}
				sums[ss++] = sum;
			}
			break;
		nxtJ:;
		}
	}
	return mc;
}

int main() {
	clock_t st = clock(); int * mc; mc = MianChowla();
	double et = ((double)(clock() - st)) / CLOCKS_PER_SEC;
	cout << "The first 30 terms of the Mian-Chowla sequence are:\n";
	for (int i = 0; i < 30; i++) { cout << mc[i] << ' '; }
	cout << "\n\nTerms 91 to 100 of the Mian-Chowla sequence are:\n";
	for (int i = 90; i < 100; i++) { cout << mc[i] << ' '; }
	cout << "\n\nComputation time was " << et << " seconds.";
}


// Generate Mian-Chowla sequence. Nigel Galloway: March 23rd., 2019
let mC=let rec fN i g l=seq{
         let a=(l*2)::[for i in i do yield i+l]@g
         let b=[l+1..l*2]|>Seq.find(fun e->Seq.forall(fun g->(Seq.contains (g-e)>>not) i) a)
         yield b; yield! fN (l::i) (a|>List.filter(fun n->n>b)) b}
       seq{yield 1; yield! fN [] [] 1}


USING: fry hash-sets io kernel math prettyprint sequences sets ;

: next ( seq sums speculative -- seq' sums' speculative' )
    dup reach [ + ] with map over dup + suffix! >hash-set pick
    over intersect null?
    [ swapd union [ [ suffix! ] keep ] dip swap ] [ drop ] if
    1 + ;

: mian-chowla ( n -- seq )
    [ V{ 1 } HS{ 2 } [ clone ] [email protected] 2 ] dip
    '[ pick length _ < ] [ next ] while 2drop ;

100 mian-chowla
[ 30 head "First 30 terms of the Mian-Chowla sequence:" ]
[ 10 tail* "Terms 91-100 of the Mian-Chowla sequence:" ] bi
[ print [ pprint bl ] each nl nl ] [email protected]


redim as uinteger mian(0 to 1)
redim as uinteger sums(0 to 2)
mian(0) = 1 : mian(1) = 2
sums(0) = 2 : sums(1) = 3 : sums(2) = 4
dim as uinteger n_mc = 2, n_sm = 3, curr = 3, tempsum
while n_mc < 101
    for i as uinteger = 0 to n_mc - 1
        tempsum = curr + mian(i)
        for j as uinteger = 0 to n_sm - 1
            if tempsum = sums(j) then goto loopend
        next j
    next i
    redim preserve as uinteger mian(0 to n_mc)
    mian(n_mc) = curr
    redim preserve as uinteger sums(0 to n_sm + n_mc)
    for j as uinteger = 0 to n_mc - 1
        sums(n_sm + j) = mian(j) + mian(n_mc)
    next j
    n_mc += 1
    n_sm += n_mc
    sums(n_sm-1) = 2*curr
    loopend:
    curr += 1
wend

print "Mian-Chowla numbers 1 through 30: ",
for i as uinteger = 0 to 29
    print mian(i),
next i
print
print "Mian-Chowla numbers 91 through 100: ",
for i as uinteger = 90 to 99
    print mian(i),
next i
print


package main

import "fmt"

func contains(is []int, s int) bool {
    for _, i := range is {
        if s == i {
            return true
        }
    }
    return false
}

func mianChowla(n int) []int {
    mc := make([]int, n)
    mc[0] = 1
    is := []int{2}
    var sum int
    for i := 1; i < n; i++ {
        le := len(is)
    jloop:
        for j := mc[i-1] + 1; ; j++ {
            mc[i] = j
            for k := 0; k <= i; k++ {
                sum = mc[k] + j
                if contains(is, sum) {
                    is = is[0:le]
                    continue jloop
                }
                is = append(is, sum)
            }
            break
        }
    }
    return mc
}

func main() {
    mc := mianChowla(100)
    fmt.Println("The first 30 terms of the Mian-Chowla sequence are:")
    fmt.Println(mc[0:30])
    fmt.Println("\nTerms 91 to 100 of the Mian-Chowla sequence are:")
    fmt.Println(mc[90:100])
}


import Data.Set (Set, fromList, insert, member)

------------------- MIAN-CHOWLA SEQUENCE -----------------
mianChowlas :: Int -> [Int]
mianChowlas =
  reverse . snd . (iterate nextMC (fromList [2], [1]) !!) . subtract 1

nextMC :: (Set Int, [Int]) -> (Set Int, [Int])
nextMC (sumSet, mcs@(n:_)) =
  (foldr insert sumSet ((2 * m) : fmap (m +) mcs), m : mcs)
  where
    valid x = not $ any (flip member sumSet . (x +)) mcs
    m = until valid succ n

--------------------------- TEST -------------------------
main :: IO ()
main =
  (putStrLn . unlines)
    [ "First 30 terms of the Mian-Chowla series:"
    , show (mianChowlas 30)
    , []
    , "Terms 91 to 100 of the Mian-Chowla series:"
    , show $ drop 90 (mianChowlas 100)
    ]


NB. http://rosettacode.org/wiki/Mian-Chowla_sequence

NB. Dreadfully inefficient implementation recomputes all the sums to n-1
NB. and computes the full addition table rather than just a triangular region
NB. However, this implementation is sufficiently quick to meet the requirements.

NB. The vector head is the next speculative value
NB. Beheaded, the vector is Mian-Chowla sequence.

Until =: conjunction def 'u^:(0 = v)^:_'
unique =: -:&# ~.   NB. tally of list matches that of set

next_mc =: [: (, {.) (>:@:{. , }.)Until([email protected]:((<:/[email protected]@# #&, +/~)@:(}. , {.)))

prime_q =: 1&p:   NB. for fun look at prime generation suitability


import java.util.Arrays;

public class MianChowlaSequence {

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        System.out.println("First 30 terms of the Mian–Chowla sequence.");
        mianChowla(1, 30);
        System.out.println("Terms 91 through 100 of the Mian–Chowla sequence.");
        mianChowla(91, 100);
        long end = System.currentTimeMillis();
        System.out.printf("Elapsed = %d ms%n", (end-start));
    }

    private static void mianChowla(int minIndex, int maxIndex) {
        int [] sums = new int[1];
        int [] chowla = new int[maxIndex+1];
        sums[0] = 2;
        chowla[0] = 0;
        chowla[1] = 1;
        if ( minIndex == 1 ) {
            System.out.printf("%d ", 1);
        }
        int chowlaLength = 1;
        for ( int n = 2 ; n <= maxIndex ; n++ ) {

            //  Sequence is strictly increasing.
            int test = chowla[n - 1];
            //  Bookkeeping.  Generate only new sums.
            int[] sumsNew = Arrays.copyOf(sums, sums.length + n);
            int sumNewLength = sums.length;
            int savedsSumNewLength = sumNewLength;

            //  Generate test candidates for the next value of the sequence.
            boolean found = false;
            while ( ! found ) {
                test++;
                found = true;
                sumNewLength = savedsSumNewLength;
                //  Generate test sums
                for ( int j = 0 ; j <= chowlaLength ; j++ ) {
                    int testSum = (j == 0 ? test : chowla[j]) + test;
                    boolean duplicate = false;

                    //  Check if test Sum in array
                    for ( int k = 0 ; k < sumNewLength ; k++ ) {
                        if ( sumsNew[k] == testSum ) {
                            duplicate = true;
                            break;
                        }
                    }
                    if ( ! duplicate ) {
                        //  Add to array
                        sumsNew[sumNewLength] = testSum;
                        sumNewLength++;
                    }
                    else {
                        //  Duplicate found.  Therefore, test candidate of the next value of the sequence is not OK.
                        found = false;
                        break;
                    }
                }
            }

            //  Bingo!  Now update bookkeeping.
            chowla[n] = test;
            chowlaLength++;
            sums = sumsNew;
            if ( n >= minIndex ) {
                System.out.printf("%d %s", chowla[n], (n==maxIndex ? "\n" : ""));
            }
        }
    }

}


(() => {
    'use strict';

    // main :: IO ()
    const main = () => {
        const genMianChowla = mianChowlas();
        console.log([
            'Mian-Chowla terms 1-30:',
            take(30)(
                genMianChowla
            ),

            '\nMian-Chowla terms 91-100:',
            (
                drop(60)(genMianChowla),
                take(10)(
                    genMianChowla
                )
            )
        ].join('\n') + '\n');
    };

    // mianChowlas :: Gen [Int]
    function* mianChowlas() {
        let
            mcs = [1],
            sumSet = new Set([2]),
            x = 1;
        while (true) {
            yield x;
            [sumSet, mcs, x] = nextMC(sumSet, mcs, x);
        }
    }

    // nextMC :: Set Int -> [Int] -> Int -> (Set Int, [Int], Int)
    const nextMC = (setSums, mcs, n) => {
        // Set of sums -> Series up to n -> Next term in series
        const valid = x => {
            for (const m of mcs) {
                if (setSums.has(x + m)) return false;
            }
            return true;
        };
        const x = until(valid)(x => 1 + x)(n);
        return [
            sumList(mcs)(x)
            .reduce(
                (a, n) => (a.add(n), a),
                setSums
            ),
            mcs.concat(x),
            x
        ];
    };

    // sumList :: [Int] -> Int -> [Int]
    const sumList = xs =>
        // Series so far -> additional term -> new sums
        n => [2 * n].concat(xs.map(x => n + x));

    // ---------------- GENERIC FUNCTIONS ----------------

    // drop :: Int -> [a] -> [a]
    // drop :: Int -> Generator [a] -> Generator [a]
    // drop :: Int -> String -> String
    const drop = n =>
        xs => Infinity > length(xs) ? (
            xs.slice(n)
        ) : (take(n)(xs), xs);

    // length :: [a] -> Int
    const length = xs =>
        // 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
        'GeneratorFunction' !== xs.constructor
        .constructor.name ? (
            xs.length
        ) : Infinity;

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

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

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


# Input: a bag-of-words (bow)
# Output: either an augmented bow, or nothing if a duplicate is found
def augment_while_unique(stream):
  label $out
  | foreach ((stream|tostring), null) as $word (.;
       if $word == null then .
       elif has($word) then break $out
       else .[$word] = 1
       end;
      select($word == null) );

# For speedup, store "sums" as a hash
def mian_chowlas:
  {m:[1], sums: {"1":1}}
  | recurse(
      .m as $m
      | .sums as $sums
      | first(range(1+$m[-1]; infinite) as $i
	      | $sums
	      | augment_while_unique( ($m[] | (.+$i)), (2*$i))
	      | [$i, .] ) as [$i, $sums]
      | {m: ($m + [$i]), $sums} )
  | .m[-1] ;


function mianchowla(n)
    seq = ones(Int, n)
    sums = Dict{Int,Int}()
    tempsums = Dict{Int,Int}()
    for i in 2:n
        seq[i] = seq[i - 1] + 1
        incrementing = true
        while incrementing
            for j in 1:i
                tsum = seq[j] + seq[i]
                if haskey(sums, tsum)
                    seq[i] += 1
                    empty!(tempsums)
                    break
                else
                    tempsums[tsum] = 0
                    if j == i
                        merge!(sums, tempsums)
                        empty!(tempsums)
                        incrementing = false
                    end
                end
            end
        end
    end
    seq
end

function testmianchowla()
    println("The first 30 terms of the Mian-Chowla sequence are $(mianchowla(30)).")
    println("The 91st through 100th terms of the Mian-Chowla sequence are $(mianchowla(100)[91:100]).")
end

testmianchowla()
@time testmianchowla()


// Version 1.3.21

fun mianChowla(n: Int): List<Int> {
    val mc = MutableList(n) { 0 }
    mc[0] = 1
    val hs = HashSet<Int>(n * (n + 1) / 2)
    hs.add(2)
    val hsx = mutableListOf<Int>()
    for (i in 1 until n) {
        hsx.clear()
        var j = mc[i - 1]
        outer@ while (true) {
            j++
            mc[i] = j
            for (k in 0..i) {
                val sum = mc[k] + j
                if (hs.contains(sum)) {
                    hsx.clear()
                    continue@outer
                }
                hsx.add(sum)
            }
            hs.addAll(hsx)
            break
        }
    }
    return mc
}

fun main() {
    val mc = mianChowla(100)
    println("The first 30 terms of the Mian-Chowla sequence are:")
    println(mc.subList(0, 30))
    println("\nTerms 91 to 100 of the Mian-Chowla sequence are:")
    println(mc.subList(90, 100))
}


n = {m} = {1};
tmp = {2};
Do[
 m++;
 While[ContainsAny[tmp, m + n],
  m++
  ];
 tmp = Join[tmp, n + m];
 AppendTo[tmp, 2 m];
 AppendTo[n, m]
 ,
 {99}
 ]
Row[Take[n, 30], ","]
Row[Take[n, {91, 100}], ","]


import intsets, strutils, times

proc mianchowla(n: Positive): seq[int] =
  result = @[1]
  var sums = [2].toIntSet()
  var candidate = 1

  while result.len < n:
    # Test successive candidates.
    var fit = false
    result.add 0    # Make room for next value.
    while not fit:
      inc candidate
      fit = true
      result[^1] = candidate
      # Check the sums.
      for val in result:
        if val + candidate in sums:
          # Failed to satisfy criterium.
          fit = false
          break
    # Add the new sums to the set of sums.
    for val in result:
      sums.incl val + candidate

let t0 = now()
let seq100 = mianchowla(100)
echo "The first 30 terms of the Mian-Chowla sequence are:"
echo seq100[0..29].join(" ")
echo ""
echo "Terms 91 to 100 of the sequence are:"
echo seq100[90..99].join(" ")

echo ""
echo "Computation time: ", (now() - t0).inMilliseconds, " ms"


use strict;
use warnings;
use feature 'say';

sub generate_mc {
    my($max)  = @_;
    my $index = 0;
    my $test  = 1;
    my %sums  = (2 => 1);
    my @mc    = 1;
    while ($test++) {
        my %these = %sums;
        map { next if ++$these{$_ + $test} > 1 } @mc[0..$index], $test;
        %sums = %these;
        $index++;
        return @mc if (push @mc, $test) > $max-1;
    }
}

my @mian_chowla = generate_mc(100);
say "First 30 terms in the Mian–Chowla sequence:\n", join(' ', @mian_chowla[ 0..29]),
    "\nTerms 91 through 100:\n",                     join(' ', @mian_chowla[90..99]);


function mian_chowla(integer n)
sequence mc = {1},
         is = {false,true}
    integer len_is = 2, s
    for i=2 to n do
        sequence isx = {}
        integer j = mc[i-1]+1
        mc = append(mc,j)
        while true do
            for k=1 to length(mc) do
                s = mc[k] + j
                if s<=len_is and is[s] then
                    isx = {}
                    exit
                end if
                isx = append(isx,s)
            end for
            if length(isx) then
                s = isx[$]
                if s>len_is then
                    is &= repeat(false,s-len_is)
                    len_is = length(is)
                end if
                for k=1 to length(isx) do
                    is[isx[k]] = true
                end for
                exit
            end if
            j += 1
            mc[i] = j
        end while
    end for
    return mc
end function

atom t0 = time()
sequence mc = mian_chowla(100)
printf(1,"The first 30 terms of the Mian-Chowla sequence are:\n %V\n",{mc[1..30]})
printf(1,"Terms 91 to 100 of the Mian-Chowla sequence are:\n %V\n",{mc[91..100]})
printf(1,"completed in %s\n",{elapsed(time()-t0)})


from itertools import count, islice, chain
import time

def mian_chowla():
    mc = [1]
    yield mc[-1]
    psums = set([2])
    newsums = set([])
    for trial in count(2):
        for n in chain(mc, [trial]):
            sum = n + trial
            if sum in psums:
                newsums.clear()
                break
            newsums.add(sum)
        else:
            psums |= newsums
            newsums.clear()
            mc.append(trial)
            yield trial

def pretty(p, t, s, f):
    print(p, t, " ".join(str(n) for n in (islice(mian_chowla(), s, f))))

if __name__ == '__main__':
    st = time.time()
    ts = "of the Mian-Chowla sequence are:\n"
    pretty("The first 30 terms", ts, 0, 30)
    pretty("\nTerms 91 to 100", ts, 90, 100)
    print("\nComputation time was", (time.time()-st) * 1000, "ms")


  [ stack ]                          is makeable    (   --> s )

  [ temp put
    1 bit makeable put
    ' [ 1 ] 1
    [ true temp put
      1+
      over witheach
        [ over + bit
          makeable share & if
            [ false temp replace
              conclude ] ]
      temp take if
        [ dup dip join
          over witheach
           [ over + bit
             makeable take
             | makeable put ] ]
      over size temp share = until ]
    makeable release
    temp release
    drop ]                           is mian-chowla ( n --> [ )

100 mian-chowla
30 split swap echo cr
-10 split nip echo


my @mian-chowla = 1, |(2..Inf).map: -> $test {
    state $index = 1;
    state %sums  = 2 => 1;
    my $next;
    my %these;
    @mian-chowla[^$index].map: { ++$next and last if %sums{$_ + $test}:exists; ++%these{$_ + $test} };
    next if $next;
    ++%sums{$test + $test};
    %sums.push: %these;
    ++$index;
    $test
};

put "First 30 terms in the Mian–Chowla sequence:\n", @mian-chowla[^30];
put "\nTerms 91 through 100:\n", @mian-chowla[90..99];


require 'set'
n, ts, mc, sums = 100, [], [1], Set.new
sums << 2
st = Time.now
for i in (1 .. (n-1))
   for j in mc[i-1]+1 .. Float::INFINITY
      mc[i] = j
      for k in (0 .. i)
         if (sums.include?(sum = mc[k]+j))
            ts.clear
            break
         end
         ts << sum
      end
      if (ts.length > 0)
         sums = sums | ts
         break
      end
   end
end
et = (Time.now - st) * 1000
s = " of the Mian-Chowla sequence are:\n"
puts "The first 30 terms#{s}#{mc.slice(0..29).join(' ')}\n\n"
puts "Terms 91 to 100#{s}#{mc.slice(90..99).join(' ')}\n\n"
puts "Computation time was #{et.round(1)}ms."


var (n, sums, ts, mc) = (100, Set([2]), [], [1])
var st = Time.micro_sec
for i in (1 ..^ n) {
   for j in (mc[i-1]+1 .. Inf) {
      mc[i] = j
      for k in (0 .. i) {
         var sum = mc[k]+j
         if (sums.exists(sum)) {
            ts.clear
            break
         }
         ts << sum
      }
      if (ts.len > 0) {
         sums = (sums|Set(ts...))
         break
      }
   }
}
var et = (Time.micro_sec - st)
var s = " of the Mian-Chowla sequence are:\n"
say "The first 30 terms#{s}#{mc.ft(0, 29).join(' ')}\n"
say "Terms 91 to 100#{s}#{mc.ft(90, 99).join(' ')}\n"
say "Computation time was #{et} seconds."


public func mianChowla(n: Int) -> [Int] {
  var mc = Array(repeating: 0, count: n)
  var ls = [2: true]
  var sum = 0

  mc[0] = 1

  for i in 1..<n {
    var lsx = [Int]()

    jLoop: for j in (mc[i-1]+1)... {
      mc[i] = j

      for k in 0...i {
        sum = mc[k] + j

        if ls[sum] ?? false {
          lsx = []
          continue jLoop
        }

        lsx.append(sum)
      }

      for n in lsx {
        ls[n] = true
      }

      break
    }
  }

  return mc
}

let seq = mianChowla(n: 100)

print("First 30 terms in sequence are: \(Array(seq.prefix(30)))")
print("Terms 91 to 100 are: \(Array(seq[90..<100]))")


' Mian-Chowla sequence - VBScript - 15/03/2019
    Const m = 100, mm=28000
    ReDim r(mm), v(mm * 2)
    Dim n, t, i, j, l, s1, s2, iterate_t
    ReDim seq(m)
    t0=Timer
    s1 = "1": s2 = ""
    seq(1) = 1: n = 1: t = 1
    Do While n < m
        t = t + 1
        iterate_t = False
        For i = 1 to t * 2
            v(i) = 0
        Next
        i = 1
        Do While i <= t And Not iterate_t
            If r(i) = 0 Then
                j = i
                Do While j <= t And Not iterate_t
                    If r(j) = 0 Then
                        l = i + j
                        If v(l) = 1 Then
                            r(t) = 1
                            iterate_t = True
                        End If
                        If Not iterate_t Then v(l) = 1
                    End If
                    j = j + 1
                Loop
            End If
            i = i + 1
        Loop
        If Not iterate_t Then
            n = n + 1
            seq(n) = t
            if           n<= 30 then s1 = s1 & " " & t
            if n>=91 and n<=100 then s2 = s2 & " " & t
        End If
    Loop
    wscript.echo "t="& t
    wscript.echo "The Mian-Chowla sequence for elements 1 to 30:"
    wscript.echo s1
    wscript.echo "The Mian-Chowla sequence for elements 91 to 100:"
    wscript.echo s2
    wscript.echo "Computation time: "&  Int(Timer-t0) &" sec"


Module Module1
Function MianChowla(ByVal n As Integer) As Integer()
        Dim mc(n - 1) As Integer, sums, ts As New HashSet(Of Integer),
        sum As Integer : mc(0) = 1 : sums.Add(2)
        For i As Integer = 1 To n - 1
            For j As Integer = mc(i - 1) + 1 To Integer.MaxValue
                mc(i) = j
                For k As Integer = 0 To i
                    sum = mc(k) + j
                    If sums.Contains(sum) Then ts.Clear() : Exit For
                    ts.Add(sum)
                Next
                If ts.Count > 0 Then sums.UnionWith(ts) : Exit For
            Next
        Next
        Return mc
    End Function

    Sub Main(ByVal args As String())
        Const n As Integer = 100
        Dim sw As New Stopwatch(), str As String = " of the Mian-Chowla sequence are:" & vbLf
        sw.Start() : Dim mc As Integer() = MianChowla(n) : sw.Stop()
        Console.Write("The first 30 terms{1}{2}{0}{0}Terms 91 to 100{1}{3}{0}{0}" &
            "Computation time was {4}ms.{0}", vbLf, str,
            String.Join(" ", mc.Take(30)), String.Join(" ", mc.Skip(n - 10)), sw.ElapsedMilliseconds)
    End Sub
End Module


var mianChowla = Fn.new { |n|
    var mc = List.filled(n, 0)
    var sums = {}
    var ts = {}
    mc[0] = 1
    sums[2] = true
    for (i in 1...n) {
        var j = mc[i-1] + 1
        while (true) {
            mc[i] = j
            for (k in 0..i) {
                var sum = mc[k] + j
                if (sums[sum]) {
                    ts.clear()
                    break
                }
                ts[sum] = true
            }
            if (ts.count > 0) {
                for (key in ts.keys) sums[key] = true
                break
            }
            j = j + 1
        }
    }
    return mc
}

var start = System.clock
var mc = mianChowla.call(100)
System.print("The first 30 terms of the Mian-Chowla sequence are:\n%(mc[0..29].join(" "))")
System.print("\nTerms 91 to 100 of the Mian-Chowla sequence are:\n%(mc[90..99].join(" "))")
System.print("\nTook %(((System.clock - start)*1000).round) milliseconds")


F main(bpm = 72, bpb = 4)
   V t = 60.0 / bpm
   V counter = 0
   L
      counter++
      I counter % bpb != 0
         print(‘tick’)
      E
         print(‘TICK’)
      sleep(t)

main()


with Ada.Text_IO;   use Ada.Text_IO;

 --This package is for the delay.
with Ada.Calendar;  use Ada.Calendar;

 --This package adds sound
with Ada.Characters.Latin_1;

procedure Main is

begin

   Put_Line ("Hello, this is 60 BPM");

   loop

      Ada.Text_IO.Put (Ada.Characters.Latin_1.BEL);
      delay 0.9; --Delay in seconds.  If you change to 0.0 the program will crash.

   end loop;

end Main;


set bpm to the text returned of (display dialog "How many beats per minute?" default answer 60)
set pauseBetweenBeeps to (60 / bpm)
repeat
	beep
	delay pauseBetweenBeeps
end repeat


startMetronome: function [bpm,msr][
    freq: 60000/bpm
    i: 0
    while [true][
        loop msr-1 'x[
            prints "\a"
            pause freq
        ]
        inc 'i
        print ~"\aAND |i|"
        pause freq
    ]
]

tempo: to :integer arg\0
beats: to :integer arg\1

startMetronome tempo beats


bpm      = 120 ; Beats per minute
pattern  = 4/4 ;
duration = 100 ; Milliseconds
beats    = 0   ; internal counter

Gui -Caption

StringSplit, p, pattern, /

Start := A_TickCount

Loop
{
	Gui Color, 0xFF0000
	Gui Show, w200 h200 Na
	SoundBeep 750, duration
	beats++
	Sleep 1000 * 60 / bpm - duration
	Loop % p1 -1
	{
		Gui Color, 0x00FF00
		Gui Show, w200 h200 Na
		SoundBeep, , duration
		beats++
		Sleep 1000 * 60 / bpm - duration
	}
}

Esc::
	MsgBox % "Metronome beeped " beats " beats, over " (A_TickCount-Start)/1000 " seconds. "
	ExitApp


# syntax: GAWK -f METRONOME.AWK
@load "time"
BEGIN {
    metronome(120,6,10)
    metronome(72,4)
    exit(0)
}
function metronome(beats_per_min,beats_per_bar,limit,  beats,delay,errors) {
    print("")
    if (beats_per_min+0 <= 0) { print("error: beats per minute is invalid") ; errors++ }
    if (beats_per_bar+0 <= 0) { print("error: beats per bar is invalid") ; errors++ }
    if (limit+0 <= 0) { limit = 999999 }
    if (errors > 0) { return }
    delay = 60 / beats_per_min
    printf("delay=%f",delay)
    while (beats < limit) {
      printf((beats++ % beats_per_bar == 0) ? "\nTICK" : " tick")
      sleep(delay)
    }
}


      BeatPattern$ = "HLLL"
      Tempo% = 100

      *font Arial,36
      REPEAT
        FOR beat% = 1 TO LEN(BeatPattern$)
          IF MID$(BeatPattern$, beat%, 1) = "H" THEN
            SOUND 1,-15,148,1
          ELSE
            SOUND 1,-15,100,1
          ENDIF
          VDU 30
          COLOUR 2
          PRINT LEFT$(BeatPattern$,beat%-1);
          COLOUR 9
          PRINT MID$(BeatPattern$,beat%,1);
          COLOUR 2
          PRINT MID$(BeatPattern$,beat%+1);
          WAIT 6000/Tempo%
        NEXT
      UNTIL FALSE


#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>

struct timeval start, last;

inline int64_t tv_to_u(struct timeval s)
{
	return s.tv_sec * 1000000 + s.tv_usec;
}

inline struct timeval u_to_tv(int64_t x)
{
	struct timeval s;
	s.tv_sec = x / 1000000;
	s.tv_usec = x % 1000000;
	return s;
}

void draw(int dir, int64_t period, int64_t cur, int64_t next)
{
	int len = 40 * (next - cur) / period;
	int s, i;

	if (len > 20) len = 40 - len;
	s = 20 + (dir ? len : -len);

	printf("\033[H");
	for (i = 0; i <= 40; i++) putchar(i == 20 ? '|': i == s ? '#' : '-');
}

void beat(int delay)
{
	struct timeval tv = start;
	int dir = 0;
	int64_t d = 0, corr = 0, slp, cur, next = tv_to_u(start) + delay;
	int64_t draw_interval = 20000;
	printf("\033[H\033[J");
	while (1) {
		gettimeofday(&tv, 0);
		slp = next - tv_to_u(tv) - corr;
		usleep(slp);
		gettimeofday(&tv, 0);

		putchar(7); /* bell */
		fflush(stdout);

		printf("\033[5;1Hdrift: %d compensate: %d (usec)   ",
			(int)d, (int)corr);
		dir = !dir;

		cur = tv_to_u(tv);
		d = cur - next;
		corr = (corr + d) / 2;
		next += delay;

		while (cur + d + draw_interval < next) {
			usleep(draw_interval);
			gettimeofday(&tv, 0);
			cur = tv_to_u(tv);
			draw(dir, delay, cur, next);
			fflush(stdout);
		}
	}
}

int main(int c, char**v)
{
	int bpm;

	if (c < 2 || (bpm = atoi(v[1])) <= 0) bpm = 60;
	if (bpm > 600) {
		fprintf(stderr, "frequency %d too high\n", bpm);
		exit(1);
	}

	gettimeofday(&start, 0);
	last = start;
	beat(60 * 1000000 / bpm);

	return 0;
}


(ql:quickload '(cl-openal cl-alc))

(defparameter *short-max* (- (expt 2 15) 1))
(defparameter *2-pi* (* 2 pi))

(defun make-sin (period)
  "Create a generator for a sine wave of the given PERIOD."
  (lambda (x)
    (sin (* *2-pi* (/ x period)))))

(defun make-tone (length frequency sampling-frequency)
  "Create a vector containing sound information of the given LENGTH,
FREQUENCY, and SAMPLING-FREQUENCY."
  (let ((data (make-array (truncate (* length sampling-frequency))
                          :element-type '(signed-byte 16)))
        (generator (make-sin (/ sampling-frequency frequency))))
    (dotimes (i (length data))
      (setf (aref data i)
            (truncate (* *short-max* (funcall generator i)))))
    data))

(defun internal-time-ms ()
  "Get the process's real time in ms."
  (* 1000 (/ (get-internal-real-time) internal-time-units-per-second)))

(defun spin-wait (next-real-time)
  "Wait until the process's real time has reached the given time."
  (loop while (< (internal-time-ms) next-real-time)))

(defun upload (buffer data sampling-frequency)
  "Upload the given vector DATA to a BUFFER at the given SAMPLING-FREQUENCY."
  (cffi:with-pointer-to-vector-data (data-ptr data)
    (al:buffer-data buffer :mono16 data-ptr (* 2 (length data))
                    sampling-frequency)))

(defun metronome (beats/minute pattern &optional (sampling-frequency 44100))
  "Play a metronome until interrupted."
  (let ((ms/beat (/ 60000 beats/minute)))
    (alc:with-device (device)
      (alc:with-context (context device)
        (alc:make-context-current context)
        (al:with-buffer (low-buffer)
          (al:with-buffer (high-buffer)
            (al:with-source (source)
              (al:source source :gain 0.5)
              (flet ((play-it (buffer)
                       (al:source source :buffer buffer)
                       (al:source-play source))
                     (upload-it (buffer time frequency)
                       (upload buffer
                               (make-tone time frequency sampling-frequency)
                               sampling-frequency)))
                (upload-it low-buffer 0.1 440)
                (upload-it high-buffer 0.15 880)
                (let ((next-scheduled-tone (internal-time-ms)))
                  (loop
                     (loop for symbol in pattern do
                          (spin-wait next-scheduled-tone)
                          (incf next-scheduled-tone ms/beat)
                          (case symbol
                            (l (play-it low-buffer))
                            (h (play-it high-buffer)))
                          (princ symbol))
                     (terpri)))))))))))


program Metronome;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows,
  System.SysUtils;

procedure StartMetronome(bpm: double; measure: Integer);
var
  counter: Integer;
begin
  counter := 0;
  while True do
  begin
    Sleep(Trunc(1000 * (60.0 / bpm)));
    inc(counter);
    if counter mod measure = 0 then
      writeln('TICK')
    else
      writeln('TOCK');
  end;
end;

begin
  StartMetronome(120, 4);
end.


;; available preloaded sounds are : ok, ko, tick, tack, woosh, beep, digit .
(lib 'timer)

(define (metronome) (blink) (play-sound 'tack))
(at-every 1000 'metronome) ;; every 1000 msec
;; CTRL-C to stop


open System
open System.Threading
// You can use .wav files for your clicks.
// If used, make sure they are in the same file
// as this program's executable file.
let high_pitch =
    new System.Media.SoundPlayer("Ping Hi.wav")
let low_pitch =
    new System.Media.SoundPlayer("Ping Low.wav")
let factor x y = x / y
// Notice that exact bpm would not work by using
// Thread.Sleep() as there are additional function calls
// that would consume a miniscule amount of time.
// This number may need to be adjusted based on the cpu.
let cpu_error = -750.0
let print = function
| 1 -> high_pitch.Play(); printf "\nTICK "
| _ -> low_pitch.Play(); printf "tick "
let wait (time:int) =
    Thread.Sleep(time)
// Composition of functions
let tick = float>>factor (60000.0+cpu_error)>>int>>wait
let rec play beats_per_measure current_beat beats_per_minute =
    match current_beat, beats_per_measure with
    | a, b ->
        current_beat |> print
        beats_per_minute |> tick
        if a <> b then
            beats_per_minute |> play beats_per_measure (current_beat + 1)
[<EntryPointAttribute>]
let main (args : string[]) =
    let tempo, beats = int args.[0], int args.[1]
    Seq.initInfinite (fun i -> i + 1)
    |> Seq.iter (fun _ -> tempo |> play beats 1 |> ignore)
    0


USING: accessors calendar circular colors.constants colors.hsv
command-line continuations io kernel math math.parser namespaces
openal.example sequences system timers ui ui.gadgets
ui.pens.solid ;
IN: rosetta-code.metronome

: bpm>duration ( bpm -- duration ) 60 swap / seconds ;

: blink-gadget ( gadget freq -- )
    1.0 1.0 1.0 <hsva>  <solid> >>interior relayout-1 ;

: blank-gadget ( gadget -- )
    COLOR: white <solid> >>interior relayout-1 ;

: play-note ( gadget freq -- )
    [ blink-gadget ] [ 0.3 play-sine blank-gadget ] 2bi ;

: metronome-iteration ( gadget circular -- )
    [ first play-note ] [ rotate-circular ] bi ;

TUPLE: metronome-gadget < gadget bpm notes timer ;

: <metronome-gadget> ( bpm notes -- gadget )
    \ metronome-gadget new swap >>notes swap >>bpm ;

: metronome-quot ( gadget -- quot )
    dup notes>> <circular> [ metronome-iteration ] 2curry ;

: metronome-timer ( gadget -- timer )
    [ metronome-quot ] [ bpm>> bpm>duration ] bi every ;

M: metronome-gadget graft* ( gadget -- )
    [ metronome-timer ] keep timer<< ;

M: metronome-gadget ungraft*
    timer>> stop-timer ;

M: metronome-gadget pref-dim* drop { 200 200 } ;

: metronome-defaults ( -- bpm notes ) 60 { 440 220 330 } ;

: metronome-ui ( bpm notes -- ) <metronome-gadget> "Metronome" open-window ;

: metronome-example ( -- ) metronome-defaults metronome-ui ;

: validate-args ( int-args -- )
    [ length 2 < ] [ [ 0 <= ] any? ] bi or [ "args error" throw ] when ;

: (metronome-cmdline) ( args -- bpm notes )
    [ string>number ] map dup validate-args
    unclip swap ;

: metronome-cmdline ( -- bpm notes )
    command-line get [ metronome-defaults ] [ (metronome-cmdline) ] if-empty ;

: print-defaults ( -- )
  metronome-defaults swap prefix
  [ " " write ] [ number>string write ] interleave nl ;

: metronome-usage ( -- )
    "Usage: metronome [BPM FREQUENCIES...]" print
    "Arguments must be non-zero" print
    "Example: metronome " write print-defaults flush ;

: metronome-main ( -- )
     [ [ metronome-cmdline metronome-ui ] [ drop metronome-usage 1 exit ] recover ] with-ui ;

MAIN: metronome-main


REM FreeBASIC no tiene la capacidad de emitir sonido de forma nativa.
REM La función Sound no es mía, incluyo los créditos correspondientes.
' Sound Function v0.3 For DOS/Linux/Win by yetifoot
' Credits:
'    http://www.frontiernet.net/~fys/snd.htm
'    http://delphi.about.com/cs/adptips2003/a/bltip0303_3.htm
#ifdef __FB_WIN32__
#include Once "windows.bi"
#endif
Sub Sound_DOS_LIN(Byval freq As Uinteger, dur As Uinteger)
    Dim t As Double
    Dim As Ushort fixed_freq = 1193181 \ freq

    Asm
        mov  dx, &H61                  ' turn speaker on
        in   al, dx
        or   al, &H03
        out  dx, al
        mov  dx, &H43                  ' get the timer ready
        mov  al, &HB6
        out  dx, al
        mov  ax, word Ptr [fixed_freq] ' move freq to ax
        mov  dx, &H42                  ' port to out
        out  dx, al                    ' out low order
        xchg ah, al
        out  dx, al                    ' out high order
    End Asm

    t = Timer
    While ((Timer - t) * 1000) < dur ' wait for out specified duration
        Sleep(1)
    Wend

    Asm
        mov  dx, &H61                  ' turn speaker off
        in   al, dx
        and  al, &HFC
        out  dx, al
    End Asm
End Sub

Sub Sound(Byval freq As Uinteger, dur As Uinteger)
    #ifndef __fb_win32__
    ' If not windows Then call the asm version.
    Sound_DOS_LIN(freq, dur)
    #Else
    ' If Windows
    Dim osv As OSVERSIONINFO

    osv.dwOSVersionInfoSize = Sizeof(OSVERSIONINFO)
    GetVersionEx(@osv)

    Select Case osv.dwPlatformId
    Case VER_PLATFORM_WIN32_NT
        ' If NT then use Beep from API
        Beep_(freq, dur)
    Case Else
        ' If not on NT then use the same as DOS/Linux
        Sound_DOS_LIN(freq, dur)
    End Select
    #endif
End Sub

'----------

Sub metronome()
    Dim As Double bpm = 120.0  ' beats por minuto
    Dim As Long retardo = 1000*(60.0 / bpm)
    Dim As Integer bpb = 4     ' beats por compás
    Dim As Integer counter = 0 ' contador interno
    Do
        counter += 1
        If counter Mod bpb <> 0 Then
            Sound(100, 60)
            Color 10: Print "tick ";
        Else
            Sound(119, 60)
            Color 11: Print "TICK "
        End If
        Sleep(retardo)
    Loop
End Sub


package main

import (
	"fmt"
	"time"
)

func main() {
	var bpm = 72.0 // Beats Per Minute
	var bpb = 4    // Beats Per Bar

	d := time.Duration(float64(time.Minute) / bpm)
	fmt.Println("Delay:", d)
	t := time.NewTicker(d)
	i := 1
	for _ = range t.C {
		i--
		if i == 0 {
			i = bpb
			fmt.Printf("\nTICK ")
		} else {
			fmt.Printf("tick ")
		}
	}
}


import Control.Concurrent
import Control.Concurrent.MVar
import System.Process (runCommand)

-- This program works only on the GHC compiler because of the use of
-- threadDelay

data Beep = Stop | Hi | Low

type Pattern = [Beep]

type BeatsPerMinute = Int

minute = 60000000 -- 1 minute = 60,000,000 microseconds

-- give one of the following example patterns to the metronome function

pattern4_4 = [Hi, Low, Low, Low]
pattern2_4 = [Hi, Low]
pattern3_4 = [Hi, Low, Low]
pattern6_8 = [Hi, Low, Low, Low, Low, Low]

-- use this version if you can't play audio, use Windows or don't
-- have audio files to play
-- beep :: Beep -> IO ()
-- beep Stop = return ()
-- beep Hi = putChar 'H'
-- beep Low = putChar 'L'

-- use this version if you can and want to play audio on Linux using
-- Alsa. Change the name of the files to those of your choice

beep Stop = return ()
beep Hi = putChar 'H' >> runCommand "aplay hi.wav &> /dev/null" >> return ()
beep Low = putChar 'L' >> runCommand "aplay low.wav &> /dev/null" >> return ()

tick :: MVar Pattern -> BeatsPerMinute -> IO ()
tick b i = do
    t <- readMVar b
    case t of
        [Stop] -> return ()
        x -> do
            mapM_ (\v -> forkIO (beep v) >> threadDelay (minute `div` i)) t
            tick b i

metronome :: Pattern -> BeatsPerMinute -> IO ()
metronome p i = do
    putStrLn "Press any key to stop the metronome."
    b <- newMVar p
    _ <- forkIO $ tick b i
    _ <- getChar
    putMVar b [Stop]


MET=: _ _&$: :(4 : 0)

  'BEL BS LF CR'=. 7 8 10 13 { a.
  '`print stime delay'=. 1!:2&4`(6!:1)`(6!:3)
  ticker=. 2 2$'\  /'
  'small large'=. (BEL,2#BS) ; 5#BS
  clrln=. CR,(79#' '),CR

  x=. 2 ({.,) x
  y=. _1 |.&.> 2 ({.,) y
  'i j'=. 0
  print 'bpb \  bpm \ ' , 2#BS
  delay 1

  x=. ({. , ('ti t'=. stime'') + {:) x
  while. x *./@:> i,t do.

    'bpb bpm'=. {[email protected]> y=. 1 |.&.> y
    dl=. 60 % bpm

    print clrln,(":bpb),' ',(ticker {~ 2 | i=. >: i),' ',(":bpm),' '

    for. i. bpb do.
      print small ,~ ticker {~ 2 | j=. >: j
      delay 0 >. (t=. t + dl) - stime ''
    end.

  end.

  print clrln
  i , j , t - ti

)

NB. Basic tacit version; this is probably considered bad coding style. At least I removed the "magic constants". Sort of.
NB. The above version is by far superior.
'BEL BS LF'=: 7 8 10 { a.
'`print delay'=: 1!:2&4`(6!:3)
met=: _&$: :((] ({:@] [ LF [email protected][ ([email protected]{[email protected]] [ [email protected][ [email protected]] (BEL,2#BS) , (2 2$'\  /') {~ {[email protected]])^:({:@])) 1 , <[email protected]%) 60&% [ [email protected]('\ '"_))


class Metronome{
	double bpm;
	int measure, counter;
	public Metronome(double bpm, int measure){
		this.bpm = bpm;
		this.measure = measure;
	}
	public void start(){
		while(true){
			try {
				Thread.sleep((long)(1000*(60.0/bpm)));
			}catch(InterruptedException e) {
				e.printStackTrace();
			}
			counter++;
			if (counter%measure==0){
				 System.out.println("TICK");
			}else{
				 System.out.println("TOCK");
			}
		}
	}
}
public class test {
	public static void main(String[] args) {
		Metronome metronome1 = new Metronome(120,4);
		metronome1.start();
	}
}


function metronome(bpm::Real=72, bpb::Int=4)
    s = 60.0 / bpm
    counter = 0
    while true
        counter += 1
        if counter % bpb != 0
            println("tick")
        else
            println("TICK")
        end
        sleep(s)
    end
end


// version 1.1.2

fun metronome(bpm: Int, bpb: Int, maxBeats: Int = Int.MAX_VALUE) {
    val delay = 60_000L / bpm
    var beats = 0
    do {
        Thread.sleep(delay)
        if (beats % bpb == 0) print("\nTICK ")
        else print("tick ")
        beats++
    }
    while (beats < maxBeats)
    println()
}

fun main(args: Array<String>) = metronome(120, 4, 20) // limit to 20 beats


    WindowWidth  =230
    WindowHeight =220

    button #w.b1 "Start",   [start],   LR, 110, 90, 55, 20
    button #w.b2 "Tempo",   [tempo],   LR, 180, 90, 55, 20
    button #w.b3 "Pattern", [pattern], LR,  40, 90, 55, 20

    open "Metronome" for graphics_nsb_nf as #w

    #w "trapclose quit"
    #w "down"
    #w "fill darkblue ; backcolor darkblue ; color white"

    tempo    =   60              '   per minute
    interval =1000 /(tempo /60)  '   timer works in ms
    tickCount =   0              '   cycle counter
    running   =   1              '   flag for state
    bar$      = "HLLL"           '   initially strong-weak-weak-weak
    count     = len( bar$)

    wait

sub quit w$
    close #w$
    end
end sub

[start]
    if running =1 then
        running =0
        #w.b1 "Stop"
        #w.b2 "!disable"
        #w.b3 "!disable"
    else
        running =1
        #w.b1 "Start"
        #w.b2 "!enable"
        #w.b3 "!enable"
    end if
    if running =0 then timer interval, [tick] else timer 0
    wait

[tempo]
    prompt "New tempo 30...360"; tempo$
    tempo =val( tempo$)
    tempo =min( tempo, 360)
    tempo =max( tempo, 30)
    interval =int( 1000 /(tempo /60))
 wait

[pattern]
    prompt "New Pattern, eg 'HLLL' "; bar$
    count =len( bar$)
    if count <2 or count >8 then goto [pattern]

 wait

[tick]
    'beep and flash
    #w "place 115 40"

    if mid$( bar$, tickCount +1, 1) ="H" then
        playwave "mHi.wav", async
        #w "backcolor blue ; color white ; circlefilled "; 20 -tickCount *2
    else
        playwave "mLo.wav", async
        #w "backcolor cyan ; circlefilled "; 20 -tickCount *2
    end if

    #w "place 50 140 ; backcolor darkblue ; color white"
    #w "\  "; tempo; " beats /min."
    #w "place 85 160"
    #w "\"; bar$

    #w "place 85 120"
    #w "\Beat # "; tickCount +1

    #w "place 115 40"
    #w "color darkblue"

    tickCount =( tickCount +1) mod count

    #w "flush"

    wait


10 bpm=120:bpb=4
20 sleep=50*60/bpm
30 counter=0
40 every sleep gosub 100
50 goto 50
100 print counter+1;" ";
110 if counter=0 then print ">TICK<":sound 1,60,10,15 else print " tick ":sound 1,119,10
120 counter=counter+1
130 if counter=bpb then counter=0
140 return


s = Sound[Play[Sin[1000 t], {t, 0, 0.05}]];
ss = Sound[Play[Sin[2000 t], {t, 0, 0.05}]];
bpm = 180;
slp = 60/bpm;
color = White;
i = 0;
Dynamic[Graphics[{color, Disk[]}, ImageSize -> 50]]
While[True,
 i = Mod[i + 1, 4, 1];
 color = {Green, Red, [email protected], Red, [email protected]}[[i]];
 If[i == 1,
  EmitSound[ss]
  ,
  EmitSound[s]
  ];
 Pause[slp];
 ]


import os

proc metronome(tempo, pattern: Positive) =
  let delay = 60_000 div tempo    # In milliseconds.
  var beats = 0
  while true:
    stdout.write if beats mod pattern == 0: "\nTICK" else: " tick"
    stdout.flushFile
    inc beats
    sleep(delay)

metronome(72, 4)


use Time::HiRes qw(sleep gettimeofday);

local $| = 1;    # autoflush

my $beats_per_minute = shift || 72;
my $beats_per_bar    = shift || 4;

my $i         = 0;
my $duration  = 60 / $beats_per_minute;
my $base_time = gettimeofday() + $duration;

for (my $next_time = $base_time ; ; $next_time += $duration) {
    if ($i++ % $beats_per_bar == 0) {
        print "\nTICK";
    }
    else {
        print " tick";
    }
    sleep($next_time - gettimeofday());
}


(de metronome (Bpm)
   (if (fork)
      (let Pid @
         (for Pendulum '(" /" . ("^H^H\\ " "^H^H /" .))
            (tell Pid 'call "/usr/bin/beep" "-f" 440 "-l" 40)
            (prin Pendulum)
            (T (key (*/ 30000 Bpm)) (tell Pid 'bye)) )
         (prinl) )
      (wait) ) )


Structure METRONOMEs
  msPerBeat.i
  BeatsPerMinute.i
  BeatsPerCycle.i
  volume.i
  canvasGadget.i
  w.i
  h.i
  originX.i
  originY.i
  radius.i
  activityStatus.i
EndStructure

Enumeration       ;gadgets
  #TEXT_MSPB      ;milliseconds per beat
  #STRING_MSPB    ;milliseconds per beat
  #TEXT_BPM       ;beats per minute
  #STRING_BPM     ;beats per minute
  #TEXT_BPC       ;beats per cycle
  #STRING_BPC     ;beats per cycle
  #BUTTON_VOLM    ;volume -
  #BUTTON_VOLP    ;volume +
  #BUTTON_START   ;start
  #SPIN_BPM
  #CANVAS_METRONOME
EndEnumeration

Enumeration       ;sounds
  #SOUND_LOW
  #SOUND_HIGH
EndEnumeration

#WINDOW = 0       ;window

Procedure handleError(Value, text.s)
  If Not Value: MessageRequester("Error", text): End: EndIf
EndProcedure

Procedure drawMetronome(*m.METRONOMEs, Angle.f, cycleCount = 0)
  Protected CircleX, CircleY, circleColor
  If StartDrawing(CanvasOutput(*m\canvasGadget))
      Box(0, 0, *m\w, *m\h, RGB(0, 0, 0))
      CircleX = Int(*m\radius * Cos(Radian(Angle)))
      CircleY = Int(*m\radius * Sin(Radian(Angle)))
      If Angle = 90
        If cycleCount: circleColor = RGB(255, 0, 0): Else: circleColor = RGB(0, 255, 0): EndIf
        LineXY(*m\originX, *m\originY, *m\originX, *m\originY - CircleY, RGB(255, 255, 0))
        Circle(*m\originX + CircleX, *m\originY - CircleY - *m\radius * 0.15, 10, circleColor)
      Else
        LineXY(*m\originX, *m\originY - *m\radius * 1.02, *m\originX, *m\originY - *m\radius, RGB(255, 255, 0))
        LineXY(*m\originX, *m\originY, *m\originX + CircleX, *m\originY - CircleY, RGB(255, 255, 0))
      EndIf

    StopDrawing()

    ProcedureReturn 1
  EndIf
EndProcedure

Procedure.i Metronome(*m.METRONOMEs)
  Protected milliseconds = Int((60 * 1000) / *m\BeatsPerMinute)
  Protected msPerFrame, framesPerBeat
  Protected i, j, cycleCount, startTime, frameEndTime, delayTime, delayError, h.f

  ;calculate metronome angles for each frame of animation
  If *m\BeatsPerMinute < 60
    framesPerBeat = Round(milliseconds / 150, #PB_Round_Nearest)
  Else
    framesPerBeat = Round((*m\BeatsPerMinute - 420) / -60, #PB_Round_Nearest)
  EndIf

  If framesPerBeat < 1
    framesPerBeat = 1
    Dim metronomeFrameAngle.f(1, framesPerBeat)
    metronomeFrameAngle(0, 1) = 90
    metronomeFrameAngle(1, 1) = 90
  Else
    Dim metronomeFrameAngle.f(1, framesPerBeat * 2)
    For j = 1 To framesPerBeat
      h = 45 / framesPerBeat
      metronomeFrameAngle(0, j) = 90 - h * (j - 1)
      metronomeFrameAngle(0, framesPerBeat + j) = 45 + h * (j - 1)
      metronomeFrameAngle(1, j) = 90 + h * (j - 1)
      metronomeFrameAngle(1, framesPerBeat + j) = 135 - h * (j - 1)
    Next
    framesPerBeat * 2
  EndIf
  msPerFrame   = milliseconds / framesPerBeat

  PlaySound(#SOUND_HIGH)
  startTime = ElapsedMilliseconds()
  Repeat
    For i = 0 To 1
      frameEndTime = startTime + msPerFrame
      For j = 1 To framesPerBeat
        drawMetronome(*m, metronomeFrameAngle(i, j), cycleCount)

        ;check for thread exit
        If *m\activityStatus < 0
          *m\activityStatus = 0
          ProcedureReturn
        EndIf

        delayTime = frameEndTime - ElapsedMilliseconds()
        If (delayTime - delayError) >= 0
          Delay(frameEndTime - ElapsedMilliseconds() - delayError) ;wait the remainder of frame
        ElseIf delayTime < 0
          delayError = - delayTime
        EndIf
        frameEndTime + msPerFrame
      Next

      ;check for thread exit
      If *m\activityStatus < 0
        *m\activityStatus = 0
        ProcedureReturn
      EndIf

      While (ElapsedMilliseconds() - startTime) < milliseconds:  Wend

      SetGadgetText(*m\msPerBeat, Str(ElapsedMilliseconds() - startTime))
      cycleCount + 1: cycleCount % *m\BeatsPerCycle
      If cycleCount = 0
        PlaySound(#SOUND_HIGH)
      Else
        PlaySound(#SOUND_LOW)
      EndIf
      startTime + milliseconds
    Next
  ForEver
EndProcedure

Procedure startMetronome(*m.METRONOMEs, MetronomeThread) ;start up the thread with new values
  *m\BeatsPerMinute = Val(GetGadgetText(#STRING_BPM))
  *m\BeatsPerCycle  = Val(GetGadgetText(#STRING_BPC))
  *m\activityStatus = 1

  If *m\BeatsPerMinute
    MetronomeThread = CreateThread(@Metronome(), *m)
  EndIf
  ProcedureReturn MetronomeThread
EndProcedure

Procedure stopMetronome(*m.METRONOMEs, MetronomeThread) ;if the thread is running: stop it
  If IsThread(MetronomeThread)
    *m\activityStatus = -1 ;signal thread to stop
  EndIf
  drawMetronome(*m, 90)
EndProcedure

Define w = 360, h = 360, ourMetronome.METRONOMEs

;initialize the metronome
With ourMetronome
  \msPerBeat     = #STRING_MSPB
  \canvasGadget   = #CANVAS_METRONOME
  \volume        = 10
  \w             = w
  \h             = h
  \originX       = w / 2
  \originY       = h / 2
  \radius        = 100
EndWith

ourMetronome\canvasGadget = #CANVAS_METRONOME

;initialize sounds
handleError(InitSound(), "Sound system is Not available")
handleError(CatchSound(#SOUND_LOW, ?sClick, ?eClick - ?sClick), "Could Not CatchSound")
handleError(CatchSound(#SOUND_HIGH, ?sClick, ?eClick - ?sClick), "Could Not CatchSound")
SetSoundFrequency(#SOUND_HIGH, 50000)
SoundVolume(#SOUND_LOW, ourMetronome\volume)
SoundVolume(#SOUND_HIGH, ourMetronome\volume)

;setup window & GUI
Define Style, i, wp, gh

Style = #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget
handleError(OpenWindow(#WINDOW, 0, 0, w + 200 + 12, h + 4, "Metronome", Style), "Not OpenWindow")
SetWindowColor(#WINDOW, $505050)

If LoadFont(0, "tahoma", 9, #PB_Font_HighQuality | #PB_Font_Bold)
  SetGadgetFont(#PB_Default, FontID(0))
EndIf

i = 3: wp = 10: gh = 22
TextGadget(#TEXT_MSPB, w + wp, gh * i, 100, gh, "MilliSecs/Beat ", #PB_Text_Center)
StringGadget(#STRING_MSPB, w + wp + 108, gh * i, 90, gh, "0", #PB_String_ReadOnly): i + 2
TextGadget(#TEXT_BPM, w + wp, gh * i, 100, gh,"Beats/Min ", #PB_Text_Center)
StringGadget(#STRING_BPM, w + wp + 108, gh * i, 90, gh, "120", #PB_String_Numeric): i + 2
GadgetToolTip(#STRING_BPM, "Valid range is 20 -> 240")
TextGadget(#TEXT_BPC, w + wp, gh * i, 100, gh,"Beats/Cycle ", #PB_Text_Center)
StringGadget(#STRING_BPC, w + wp + 108, gh * i, 90, gh, "4", #PB_String_Numeric): i + 2
GadgetToolTip(#STRING_BPC, "Valid range is 1 -> BPM")
ButtonGadget(#BUTTON_START, w + wp, gh * i, 200, gh, "Start", #PB_Button_Toggle): i + 2
ButtonGadget(#BUTTON_VOLM, w + wp, gh * i, 100, gh, "-Volume")
ButtonGadget(#BUTTON_VOLP, w + wp + 100, gh * i, 100, gh, "+Volume")
CanvasGadget(ourMetronome\canvasGadget, 0, 0, ourMetronome\w, ourMetronome\h, #PB_Image_Border)
drawMetronome(ourMetronome, 90)

Define msg, GID, MetronomeThread, Value
Repeat ;the control loop for our application
  msg = WaitWindowEvent(1)
  GID = EventGadget()
  etp = EventType()

  If GetAsyncKeyState_(#VK_ESCAPE): End: EndIf ;remove when app is o.k.

  Select msg

    Case #PB_Event_CloseWindow
      End

    Case #PB_Event_Gadget
      Select GID

        Case #STRING_BPM
          If etp = #PB_EventType_LostFocus
            Value = Val(GetGadgetText(#STRING_BPM))
            If Value > 390
            Value = 390
            ElseIf Value < 20
            Value = 20
            EndIf
            SetGadgetText(#STRING_BPM, Str(Value))
          EndIf

        Case #STRING_BPC
          If etp = #PB_EventType_LostFocus
            Value = Val(GetGadgetText(#STRING_BPC))
            If Value > Val(GetGadgetText(#STRING_BPM))
              Value = Val(GetGadgetText(#STRING_BPM))
            ElseIf Value < 1
              Value = 1
            EndIf
            SetGadgetText(#STRING_BPC, Str(Value))
          EndIf

        Case #BUTTON_VOLP, #BUTTON_VOLM ;change volume
          If GID = #BUTTON_VOLP And ourMetronome\volume < 100
            ourMetronome\volume + 10
          ElseIf GID = #BUTTON_VOLM And ourMetronome\volume > 0
            ourMetronome\volume - 10
          EndIf
          SoundVolume(#SOUND_LOW, ourMetronome\volume)
          SoundVolume(#SOUND_HIGH, ourMetronome\volume)

        Case #BUTTON_START ;the toggle button for start/stop
          Select GetGadgetState(#BUTTON_START)
            Case 1
              stopMetronome(ourMetronome, MetronomeThread)
              MetronomeThread = startMetronome(ourMetronome, MetronomeThread)
              SetGadgetText(#BUTTON_START,"Stop")
            Case 0
              stopMetronome(ourMetronome, MetronomeThread)
              SetGadgetText(#BUTTON_START,"Start")
          EndSelect

      EndSelect
  EndSelect
ForEver
End

DataSection
  ;a small wav file saved as raw data
  sClick:
  Data.q $0000082E46464952,$20746D6645564157,$0001000100000010,$0000AC440000AC44
  Data.q $6174616400080001,$8484848300000602,$8B8A898886868585,$C0B3A9A29C95918E
  Data.q $31479BD3CED0CFCF,$3233323232323331,$BDAEC4C9A1423133,$D0CFCFD0CFD1CDD4
  Data.q $323232333770A9CB,$2E34313332333232,$CFD0CFCACFCFAF53,$9783AAD3CED0CFD0
  Data.q $3233313332448AA1,$4430333233323233,$CFD0CFAE7D7E9483,$B7B9C3B8BFD1CED0
  Data.q $3233313037476898,$3E48493D32333233,$85959187775C4338,$898A8F8D807A7978
  Data.q $737F898381888D8D,$3131435564717A77,$332F36413A343234,$827B7873695C4D37
  Data.q $9C9B949191908F8A,$4D50515A67758694,$5451484341414245,$7B83868782756559
  Data.q $565D5F616365676E,$7871675F57504B4E,$797C8083827E7C7B,$4D525E686C6D7176
  Data.q $4D4B4B474343464A,$8B82796F655D5953,$7B7C83888B909392,$5153595E666F767B
  Data.q $5A5A5B5B59575553,$696C6E6D67615E5B,$7879777573726F6B,$71727376797C7B79
  Data.q $505352505159646C,$6B6153463C3B414A,$A09B908379706D6E,$6F767A7E858C949C
  Data.q $4D4D4845484E5662,$80796F645B544E4C,$8487888885828283,$555A5D606369737D
  Data.q $6A665F58524E4E51,$878E8F8B867D736D,$54606B72797F8081,$5852504F4E4E4C4D
  Data.q $7E7B7A79756F675F,$6B6C6F757C7F8182,$6D6865676C6F6E6C,$6E6B6C7074777773
  Data.q $615E5D60676F7372,$7069636061636463,$81817F7C7A797976,$65676B6E72797E80
  Data.q $65625F5E5D5D5F62,$7D7C7B7875716E6A,$6F74777B7E7F7F7E,$454950565D63676A
  Data.q $605A55504B464343,$9E9F9D978E817469,$6E7D8A93989A9B9C,$444546494C505861
  Data.q $7B756F665C534C46,$7E82858788888580,$5C5D61666B70757A,$6A6B6B6B6965615E
  Data.q $646B717676736F6B,$727272716D676261,$8285878885817A74,$5F5F636A72797D80
  Data.q $645D58585A5E6060,$827D79777877746D,$7878797C80848685,$6A686664666B7075
  Data.q $76726C666364686B,$807E7B7878787878,$656A6F74797B7D7F,$59585A5C5D5F6163
  Data.q $84807C79746D665E,$777C81878B8C8B89,$555352555B636B72,$82776B625C595957
  Data.q $989B9A979493918B,$656A6E7277818A92,$535457575656585E,$6E6E6F6D675E5753
  Data.q $898C9398968D7F74,$69717E8C9697918B,$3B39414F5D656767,$695B56565A595145
  Data.q $8986878A8F90897B,$7A7875757B848A8C,$747168605E636D76,$7B7365585257636F
  Data.q $8C8981777272777C,$70757676767A8188,$6A6D6D68625F6269,$8687847D746C6868
  Data.q $8485888A89868484,$585A616B747B8083,$5B555355595C5C5A,$8C898786847D7265
  Data.q $888C9096999A9892,$6163666C72797F83,$5E554E4B4C52595E,$91887C7169676663
  Data.q $8E8E8A88888C9193,$656666676A737E88,$655F585352555B62,$8B88837C756F6B69
  Data.q $7E858B8E8E8B898B,$62676B6D6D6C6E74,$6C6C6B6A6764605F,$7C7978787775736F
  Data.q $8E8C8C8C8D8D8982,$686D747C858C9091,$625C58585B5E6265,$908A837C75706C68
  Data.q $848A8E9396989896,$545960676E757A7F,$65605E5D5B575352,$A19D9890877C746C
  Data.q $8992979A9C9FA1A2,$525355575C64707E,$736D665D56514F50,$8D8D8B8986827E79
  Data.q $7777797B7F84898C,$78746F6A6A6E7376,$7B79767372747879,$6C6B69686A6F757A
  Data.q $7C78746F6D6C6C6D,$888B8C8B88858280,$6F75797B7D7F8184,$6F6D6B686565676A
  Data.q $8785817D79747270,$868B8D8D8C8A8988,$6F73777A7C7D7F82,$6F6B68656465666A
  Data.q $8A837D7976757472,$76787A7D82888C8D,$6562606064696F73,$8E8A847C756F6B68
  Data.q $8D90939494929190,$606264686F788088,$73685D58585A5D5F,$9B96918C8987837D
  Data.q $71767B838C959B9D,$5B5756585D63686D,$8C86817B756F6962,$888F939597979591
  Data.q $5C606366696F7780,$7A756D6259535458,$9EA2A0988D837E7C,$79858D8F8F8E9097
  Data.q $656B6E6D6865666E,$797A79746C656060,$7F7F7F7F7E7C7978,$8381828384848280
  Data.q $7F82888E92918D88,$59606A757C7F7F7F,$655E5A5A59585656,$A59F97918A82796E
  Data.q $7E848A939CA6ABAA,$48454548515E6B76,$8A7C6E6057514E4B,$A9ACABA8A4A09B94
  Data.q $5A626A737F8C98A3,$60554D49484A4E54,$A9A19A928A81776B,$848C969FA7ADAFAD
  Data.q $4B494C525C67717B,$8A7D7167605A544F,$A2A4A5A6A6A49F96,$626970777F89949C
  Data.q $6B655E56504F545A,$A19F988F8379736E,$848C9296989A9C9F,$61626465676B717A
  Data.q $807E79736D676261,$86898B8C8A888583,$797A7E8284848484,$77777A7C7E7E7C7A
  Data.q $7979797B7D7E7C79,$7D7C7B7B7C7C7B7A,$7D7D7C7B7A7B7C7D,$797978777677797B
  Data.q $787A7A7976757678,$415380817C777576,$2C31000002005255,$30202C36202C3020
  eClick:
EndDataSection


#lang Python
import time

def main(bpm = 72, bpb = 4):
    sleep = 60.0 / bpm
    counter = 0
    while True:
        counter += 1
        if counter % bpb:
            print 'tick'
        else:
            print 'TICK'
        time.sleep(sleep)

main()


#lang racket

(require racket/gui)

(define msec 500)
(define sounds '("hi.wav" "lo.wav"))
(define colors '("red" "green"))

(define f
  (new frame% [label "Metronome"] [width 200] [height 200]))
(define c
  (new (class canvas%
         (define brushes
           (map (λ(c) (new brush% [color c] [style 'solid])) colors))
         (define cur 0)
         (define/override (on-paint)
           (send* (send this get-dc)
                  (clear)
                  (set-brush (list-ref brushes cur))
                  (draw-rectangle 0 0 200 200)))
         (define/public (flip!)
           (set! cur (modulo (add1 cur) (length sounds)))
           (play-sound (list-ref sounds cur) #f)
           (on-paint))
         (super-new))
       [parent f]))

(define (flip)
  (define init (current-inexact-milliseconds))
  (define next (+ msec init))
  (define ticks 1)
  (let loop ()
    (when (> (current-inexact-milliseconds) next)
      (set! ticks (add1 ticks))
      (set! next (+ init (* msec ticks)))
      (queue-callback (λ() (send c flip!))))
    (sleep 0.01)
    (loop)))

(send* f (center) (show #t))
(void (thread flip))


sub MAIN ($beats-per-minute = 72, $beats-per-bar = 4) {
    my $duration = 60 / $beats-per-minute;
    my $base-time = now + $duration;
    my $i;

    for $base-time, $base-time + $duration ... * -> $next-time {
        if $i++ %% $beats-per-bar {
            print "\nTICK";
        }
        else {
            print  " tick";
        }
        sleep $next-time - now;
    }
}


/*REXX program simulates a visual (textual)  metronome  (with no sound).                */
parse arg bpm bpb dur .                          /*obtain optional arguments from the CL*/
if bpm=='' | bpm==","  then bpm=72               /*the number of  beats  per minute.    */
if bpb=='' | bpb==","  then bpb= 4               /* "     "    "    "     "   bar.      */
if dur=='' | dur==","  then dur= 5               /*duration of the  run  in seconds.    */
call time 'Reset'                                /*reset the REXX elapsed timer.        */
bt=1/bpb                                         /*calculate a   tock-time   interval.  */

  do until et>=dur;    et=time('Elasped')        /*process  tick-tocks  for the duration*/
  say; call charout ,'TICK'                      /*show the first tick for the period.  */
  es=et+1                                        /*bump the elapsed time  "limiter".    */
  $t=et+bt
                        do until e>=es;        e=time('Elapsed')
                        if e<$t then iterate                       /*time for tock?     */
                        call charout , ' tock'                     /*show a  "tock".    */
                        $t=$t+bt                                   /*bump the TOCK time.*/
                         end   /*until e≥es*/
  end   /*until et≥dur*/
                                                 /*stick a fork in it,  we're all done. */


#!/usr/bin/ruby

bpm = Integer(ARGV[0]) rescue 60 # sets BPM by the first command line argument, set to 60 if none provided
msr = Integer(ARGV[1]) rescue 4 # sets number of beats in a measure by the second command line argument, set to 4 if none provided
i = 0

loop do
  (msr-1).times do
    puts "\a"
    sleep(60.0/bpm)
  end
  puts "\aAND #{i += 1}"
  sleep(60.0/bpm)
end


def metronome(bpm: Int, bpb: Int, maxBeats: Int = Int.MaxValue) {
  val delay = 60000L / bpm
  var beats = 0
  do {
    Thread.sleep(delay)
    if (beats % bpb == 0) print("\nTICK ")
    else print("tick ")
    beats+=1
  }
  while (beats < maxBeats)
  println()
}

metronome(120, 4, 20) // limit to 20


func metronome (beats_per_minute = 72, beats_per_bar = 4) {

    var counter   = 0
    var duration  = 60/beats_per_minute
    var base_time = Time.micro+duration

    STDOUT.autoflush(true)

    for next_time in (base_time..Inf `by` duration) {
        if (counter++ %% beats_per_bar) {
            print "\nTICK"
        }
        else {
            print " tick"
        }
        Sys.sleep(next_time - Time.micro)
    }
}

say metronome(ARGV.map{ Num(_) }...)


package require Tcl 8.5

lassign $argv bpm bpb
if {$argc < 2} {set bpb 4}
if {$argc < 1} {set bpm 60}

fconfigure stdout -buffering none
set intervalMS [expr {round(60000.0 / $bpm)}]
set ctr 0

proc beat {} {
    global intervalMS ctr bpb
    after $intervalMS beat      ;# Reschedule first, to encourage minimal drift
    if {[incr ctr] == 1} {
	puts -nonewline "\r\a[string repeat { } [expr {$bpb+4}]]\rTICK"
    } else {
	puts -nonewline "\rtick[string repeat . [expr {$ctr-1}]]"
    }
    if {$ctr >= $bpb} {
	set ctr 0
    }
}

# Run the metronome until the user uses Ctrl+C...
beat
vwait forever


import "timer" for Timer
import "io" for Stdout

var metronome = Fn.new { |bpm, bpb, maxBeats|
    var delay = (60000/bpm).floor
    var beats = 0
    while (true) {
        Timer.sleep(delay)
        System.write((beats % bpb == 0) ? "\n\aTICK " : "\atick ")
        Stdout.flush()
        beats = beats + 1
        if (beats == maxBeats) break
    }
    System.print()
}

metronome.call(120, 4, 20) // limit to 20 beats


using static System.Math;
using static System.Console;
using BI = System.Numerics.BigInteger;

class Program {

    static BI IntSqRoot(BI v, BI res) { // res is the initial guess
        BI term = 0, d = 0, dl = 1; while (dl != d) { term = v / res; res = (res + term) >> 1;
            dl = d; d = term - res; } return term; }

    static string doOne(int b, int digs) { // calculates result via square root, not iterations
        int s = b * b + 4; BI g = (BI)(Sqrt((double)s) * Pow(10, ++digs)),
            bs = IntSqRoot(s * BI.Parse('1' + new string('0', digs << 1)), g);
        bs += b * BI.Parse('1' + new string('0', digs));
        bs >>= 1; bs += 4; string st = bs.ToString();
        return string.Format("{0}.{1}", st[0], st.Substring(1, --digs)); }

    static string divIt(BI a, BI b, int digs) { // performs division
        int al = a.ToString().Length, bl = b.ToString().Length;
        a *= BI.Pow(10, ++digs << 1); b *= BI.Pow(10, digs);
        string s = (a / b + 5).ToString(); return s[0] + "." + s.Substring(1, --digs); }

    // custom formating
    static string joined(BI[] x) { int[] wids = {1, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13};
        string res = ""; for (int i = 0; i < x.Length; i++) res +=
            string.Format("{0," + (-wids[i]).ToString() + "} ", x[i]); return res; }

    static void Main(string[] args) { // calculates and checks each "metal"
        WriteLine("Metal B Sq.Rt Iters /---- 32 decimal place value ----\\  Matches Sq.Rt Calc");
        int k; string lt, t = ""; BI n, nm1, on; for (int b = 0; b < 10; b++) {
            BI[] lst = new BI[15]; lst[0] = lst[1] = 1;
            for (int i = 2; i < 15; i++) lst[i] = b * lst[i - 1] + lst[i - 2];
            // since all the iterations (except Pt) are > 15, continue iterating from the end of the list of 15
            n = lst[14]; nm1 = lst[13]; k = 0; for (int j = 13; k == 0; j++) {
                lt = t; if (lt == (t = divIt(n, nm1, 32))) k = b == 0 ? 1 : j;
                on = n; n = b * n + nm1; nm1 = on; }
            WriteLine("{0,4}  {1}   {2,2}    {3, 2}  {4}  {5}\n{6,19} {7}", "Pt Au Ag CuSn Cu Ni Al Fe Sn Pb"
                .Split(' ')[b], b, b * b + 4, k, t, t == doOne(b, 32), "", joined(lst)); }
        // now calculate and check big one
        n = nm1 =1; k = 0; for (int j = 1; k == 0; j++) {
            lt = t; if (lt == (t = divIt(n, nm1, 256))) k = j;
                on = n; n += nm1; nm1 = on; }
        WriteLine("\nAu to 256 digits:"); WriteLine(t);
        WriteLine("Iteration count: {0}  Matched Sq.Rt Calc: {1}", k, t == doOne(1, 256)); }
}


#include <boost/multiprecision/cpp_dec_float.hpp>
#include <iostream>

const char* names[] = { "Platinum", "Golden", "Silver", "Bronze", "Copper", "Nickel", "Aluminium", "Iron", "Tin", "Lead" };

template<const uint N>
void lucas(ulong b) {
    std::cout << "Lucas sequence for " << names[b] << " ratio, where b = " << b << ":\nFirst " << N << " elements: ";
    auto x0 = 1L, x1 = 1L;
    std::cout << x0 << ", " << x1;
    for (auto i = 1u; i <= N - 1 - 1; i++) {
        auto x2 = b * x1 + x0;
        std::cout << ", " << x2;
        x0 = x1;
        x1 = x2;
    }
    std::cout << std::endl;
}

template<const ushort P>
void metallic(ulong b) {
    using namespace boost::multiprecision;
    using bfloat = number<cpp_dec_float<P+1>>;
    bfloat x0(1), x1(1);
    auto prev = bfloat(1).str(P+1);
    for (auto i = 0u;;) {
        i++;
        bfloat x2(b * x1 + x0);
        auto thiz = bfloat(x2 / x1).str(P+1);
        if (prev == thiz) {
            std::cout << "Value after " << i << " iteration" << (i == 1 ? ": " : "s: ") << thiz << std::endl << std::endl;
            break;
        }
        prev = thiz;
        x0 = x1;
        x1 = x2;
    }
}

int main() {
    for (auto b = 0L; b < 10L; b++) {
        lucas<15>(b);
        metallic<32>(b);
    }
    std::cout << "Golden ratio, where b = 1:" << std::endl;
    metallic<256>(1);

    return 0;
}


package Semaphores is
   protected type Counting_Semaphore(Max : Positive) is
      entry Acquire;
      procedure Release;
      function Count return Natural;
   private
      Lock_Count : Natural := 0;
   end Counting_Semaphore;
end Semaphores;


// Metallic Ration. Nigel Galloway: September 16th., 2020
let rec fN i g (e,l)=match i with 0->g |_->fN (i-1) (int(l/e)::g) (e,(l%e)*10I)
let     fI(P:int)=Seq.unfold(fun(n,g)->Some(g,((bigint P)*n+g,n)))(1I,1I)
let     fG fI fN=let _,(n,g)=fI|>Seq.pairwise|>Seq.mapi(fun n g->(n,fN g))|>Seq.pairwise|>Seq.find(fun((_,n),(_,g))->n=g) in (n,List.rev g)
let     mR n g=printf "First 15 elements when P = %d -> " n; fI n|>Seq.take 15|>Seq.iter(printf "%A "); printf "\n%d decimal places " g
               let Σ,n=fG(fI n)(fN (g+1) []) in printf "required %d iterations -> %d." Σ n.Head; List.iter(printf "%d")n.Tail ;printfn ""
[0..9]|>Seq.iter(fun n->mR n 32; printfn ""); mR 1 256


USING: combinators decimals formatting generalizations io kernel
math prettyprint qw sequences ;
IN: rosetta-code.metallic-ratios

: lucas ( n a b -- n a' b' ) tuck reach * + ;

: lucas. ( n -- )
    1 pprint bl 1 1 14 [ lucas over pprint bl ] times 3drop nl ;

: approx ( a b -- d ) swap [ 0 <decimal> ] [email protected] 32 D/ ;

: approximate ( n -- value iter )
    -1 swap 1 1 0 1 [ 2dup = ]
    [ [ 1 + ] 5 ndip [ lucas 2dup approx ] 2dip drop ] until
    4nip decimal>ratio swap ;

qw{
    Platinum Golden Silver Bronze Copper Nickel Aluminum Iron
    Tin Lead
}
[
    dup dup approximate {
        [ "Lucas sequence for %s ratio " printf ]
        [ "where b = %d:\n" printf ]
        [ "First 15 elements: " write lucas. ]
        [ "Approximated value: %.32f " printf ]
        [ "- reached after  %d  iteration(s)\n\n" printf ]
    } spread
] each-index


package main

import (
    "fmt"
    "math/big"
)

var names = [10]string{"Platinum", "Golden", "Silver", "Bronze", "Copper",
    "Nickel", "Aluminium", "Iron", "Tin", "Lead"}

func lucas(b int64) {
    fmt.Printf("Lucas sequence for %s ratio, where b = %d:\n", names[b], b)
    fmt.Print("First 15 elements: ")
    var x0, x1 int64 = 1, 1
    fmt.Printf("%d, %d", x0, x1)
    for i := 1; i <= 13; i++ {
        x2 := b*x1 + x0
        fmt.Printf(", %d", x2)
        x0, x1 = x1, x2
    }
    fmt.Println()
}

func metallic(b int64, dp int) {
    x0, x1, x2, bb := big.NewInt(1), big.NewInt(1), big.NewInt(0), big.NewInt(b)
    ratio := big.NewRat(1, 1)
    iters := 0
    prev := ratio.FloatString(dp)
    for {
        iters++
        x2.Mul(bb, x1)
        x2.Add(x2, x0)
        this := ratio.SetFrac(x2, x1).FloatString(dp)
        if prev == this {
            plural := "s"
            if iters == 1 {
                plural = " "
            }
            fmt.Printf("Value to %d dp after %2d iteration%s: %s\n\n", dp, iters, plural, this)
            return
        }
        prev = this
        x0.Set(x1)
        x1.Set(x2)
    }
}

func main() {
    for b := int64(0); b < 10; b++ {
        lucas(b)
        metallic(b, 32)
    }
    fmt.Println("Golden ratio, where b = 1:")
    metallic(1, 256)
}


SEMA sem = LEVEL 1;

PROC job = (INT n)VOID: (
   printf(($" Job "d" acquired Semaphore ..."$,n));
   TO 10000000 DO SKIP OD;
   printf(($" Job "d" releasing Semaphore"l$,n))
);

PAR (
  ( DOWN sem ; job(1) ; UP sem ) ,
  ( DOWN sem ; job(2) ; UP sem ) ,
  ( DOWN sem ; job(3) ; UP sem )
)


      INSTALL @lib$+"TIMERLIB"
      DIM tID%(6)

      REM Two workers may be concurrent
      DIM Semaphore%(2)

      tID%(6) = FN_ontimer(11, PROCtimer6, 1)
      tID%(5) = FN_ontimer(10, PROCtimer5, 1)
      tID%(4) = FN_ontimer(11, PROCtimer4, 1)
      tID%(3) = FN_ontimer(10, PROCtimer3, 1)
      tID%(2) = FN_ontimer(11, PROCtimer2, 1)
      tID%(1) = FN_ontimer(10, PROCtimer1, 1)

      ON CLOSE PROCcleanup : QUIT
      ON ERROR PRINT REPORT$ : PROCcleanup : END

      sc% = 0
      REPEAT
        oldsc% = sc%
        sc% = -SUM(Semaphore%())
        IF sc%<>oldsc% PRINT "Semaphore count now ";sc%
        WAIT 0
      UNTIL FALSE

      DEF PROCtimer1 : PROCtask(1) : ENDPROC
      DEF PROCtimer2 : PROCtask(2) : ENDPROC
      DEF PROCtimer3 : PROCtask(3) : ENDPROC
      DEF PROCtimer4 : PROCtask(4) : ENDPROC
      DEF PROCtimer5 : PROCtask(5) : ENDPROC
      DEF PROCtimer6 : PROCtask(6) : ENDPROC

      DEF PROCtask(n%)
      LOCAL i%, temp%
      PRIVATE delay%(), sem%()
      DIM delay%(6), sem%(6)
      IF delay%(n%) THEN
        delay%(n%) -= 1
        IF delay%(n%) = 0 THEN
          SWAP Semaphore%(sem%(n%)),temp%
          delay%(n%) = -1
          PRINT "Task " ; n% " released semaphore"
        ENDIF
        ENDPROC
      ENDIF
      FOR i% = 1 TO DIM(Semaphore%(),1)
        temp% = TRUE
        SWAP Semaphore%(i%),temp%
        IF NOT temp% EXIT FOR
      NEXT
      IF temp% THEN ENDPROC : REM Waiting to acquire semaphore
      sem%(n%) = i%
      delay%(n%) = 200
      PRINT "Task "; n% " acquired semaphore"
      ENDPROC

      DEF PROCcleanup
      LOCAL i%
      FOR i% = 1 TO 6
        PROC_killtimer(tID%(i%))
      NEXT
      ENDPROC


#include <semaphore.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>

sem_t sem;
int count = 3;

/* the whole point of a semaphore is that you don't count it:
 * p/v are atomic.  Unless it's locked while you are doing
 * something with the count, the value is only informative */
#define getcount() count
void acquire()
{
	sem_wait(&sem);
	count--;
}

void release()
{
	count++;
	sem_post(&sem);
}

void* work(void * id)
{
	int i = 10;
	while (i--) {
		acquire();
		printf("#%d acquired sema at %d\n", *(int*)id, getcount());
		usleep(rand() % 4000000); /* sleep 2 sec on average */
		release();
		usleep(0);  /* effectively yield */
	}
	return 0;
}

int main()
{
	pthread_t th[4];
	int i, ids[] = {1, 2, 3, 4};

	sem_init(&sem, 0, count);

	for (i = 4; i--;) pthread_create(th + i, 0, work, ids + i);
	for (i = 4; i--;) pthread_join(th[i], 0);
	printf("all workers done\n");

	return sem_destroy(&sem);
}


class MetallicRatios {
    private static List<String> names = new ArrayList<>()
    static {
        names.add("Platinum")
        names.add("Golden")
        names.add("Silver")
        names.add("Bronze")
        names.add("Copper")
        names.add("Nickel")
        names.add("Aluminum")
        names.add("Iron")
        names.add("Tin")
        names.add("Lead")
    }

    private static void lucas(long b) {
        printf("Lucas sequence for %s ratio, where b = %d\n", names[b], b)
        print("First 15 elements: ")
        long x0 = 1
        long x1 = 1
        printf("%d, %d", x0, x1)
        for (int i = 1; i < 13; ++i) {
            long x2 = b * x1 + x0
            printf(", %d", x2)
            x0 = x1
            x1 = x2
        }
        println()
    }

    private static void metallic(long b, int dp) {
        BigInteger x0 = BigInteger.ONE
        BigInteger x1 = BigInteger.ONE
        BigInteger x2
        BigInteger bb = BigInteger.valueOf(b)
        BigDecimal ratio = BigDecimal.ONE.setScale(dp)
        int iters = 0
        String prev = ratio.toString()
        while (true) {
            iters++
            x2 = bb * x1 + x0
            String thiz = (x2.toBigDecimal().setScale(dp) / x1.toBigDecimal().setScale(dp)).toString()
            if (prev == thiz) {
                String plural = "s"
                if (iters == 1) {
                    plural = ""
                }
                printf("Value after %d iteration%s: %s\n\n", iters, plural, thiz)
                return
            }
            prev = thiz
            x0 = x1
            x1 = x2
        }
    }

    static void main(String[] args) {
        for (int b = 0; b < 10; ++b) {
            lucas(b)
            metallic(b, 32)
        }
        println("Golden ratio, where b = 1:")
        metallic(1, 256)
    }
}


using System;
using System.Threading;
using System.Threading.Tasks;

namespace RosettaCode
{
  internal sealed class Program
  {
    private static void Worker(object arg, int id)
    {
      var sem = arg as SemaphoreSlim;
      sem.Wait();
      Console.WriteLine("Thread {0} has a semaphore & is now working.", id);
      Thread.Sleep(2*1000);
      Console.WriteLine("#{0} done.", id);
      sem.Release();
    }

    private static void Main()
    {
      var semaphore = new SemaphoreSlim(Environment.ProcessorCount*2, int.MaxValue);

      Console.WriteLine("You have {0} processors availiabe", Environment.ProcessorCount);
      Console.WriteLine("This program will use {0} semaphores.\n", semaphore.CurrentCount);

      Parallel.For(0, Environment.ProcessorCount*3, y => Worker(semaphore, y));
    }
  }
}


#include <chrono>
#include <iostream>
#include <format>
#include <semaphore>
#include <thread>

using namespace std::literals;

void Worker(std::counting_semaphore<>& semaphore, int id)
{
    semaphore.acquire();
    std::cout << std::format("Thread {} has a semaphore & is now working.\n", id); // response message
    std::this_thread::sleep_for(2s);
    std::cout << std::format("Thread {} done.\n", id);
    semaphore.release();
}

int main()
{
    const auto numOfThreads = static_cast<int>( std::thread::hardware_concurrency() );
    std::counting_semaphore<> semaphore{numOfThreads / 2};

    std::vector<std::jthread> tasks;
    for (int id = 0; id < numOfThreads; ++id)
	tasks.emplace_back(Worker, std::ref(semaphore), id);

    return 0;
}


module meteredconcurrency ;
import std.stdio ;
import std.thread ;
import std.c.time ;

class Semaphore {
  private int lockCnt, maxCnt ;
  this(int count) { maxCnt = lockCnt = count ;}
  void acquire() {
    if(lockCnt < 0 || maxCnt <= 0)
      throw new Exception("Negative Lock or Zero init. Lock") ;
    while(lockCnt == 0)
      Thread.getThis.yield ; // let other threads release lock
    synchronized lockCnt-- ;
  }
  void release() {
    synchronized
      if (lockCnt < maxCnt)
        lockCnt++ ;
      else
        throw new Exception("Release lock before acquire") ;
  }
  int getCnt() { synchronized return lockCnt ; }
}

class Worker : Thread {
  private static int Id = 0 ;
  private Semaphore lock ;
  private int myId ;
  this (Semaphore l) { super() ; lock = l ; myId = Id++ ; }
  override int run() {
    lock.acquire ;
    writefln("Worker %d got a lock(%d left).", myId, lock.getCnt) ;
    msleep(2000) ;  // wait 2.0 sec
    lock.release ;
    writefln("Worker %d released a lock(%d left).", myId, lock.getCnt) ;
    return 0 ;
  }
}

void main() {
  Worker[10] crew ;
  Semaphore lock = new Semaphore(4) ;

  foreach(inout c ; crew)
    (c = new Worker(lock)).start ;
  foreach(inout c ; crew)
    c.wait ;
}


import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.MathContext;
import java.util.ArrayList;
import java.util.List;

public class MetallicRatios {

    private static String[] ratioDescription = new String[] {"Platinum", "Golden", "Silver", "Bronze", "Copper", "Nickel", "Aluminum", "Iron", "Tin", "Lead"};

    public static void main(String[] args) {
        int elements = 15;
        for ( int b = 0 ; b < 10 ; b++ ) {
            System.out.printf("Lucas sequence for %s ratio, where b = %d:%n", ratioDescription[b], b);
            System.out.printf("First %d elements: %s%n", elements, lucasSequence(1, 1, b, elements));
            int decimalPlaces = 32;
            BigDecimal[] ratio = lucasSequenceRatio(1, 1, b, decimalPlaces+1);
            System.out.printf("Value to %d decimal places after %s iterations : %s%n", decimalPlaces, ratio[1], ratio[0]);
            System.out.printf("%n");
        }
        int b = 1;
        int decimalPlaces = 256;
        System.out.printf("%s ratio, where b = %d:%n", ratioDescription[b], b);
        BigDecimal[] ratio = lucasSequenceRatio(1, 1, b, decimalPlaces+1);
        System.out.printf("Value to %d decimal places after %s iterations : %s%n", decimalPlaces, ratio[1], ratio[0]);
    }

    private static BigDecimal[] lucasSequenceRatio(int x0, int x1, int b, int digits) {
        BigDecimal x0Bi = BigDecimal.valueOf(x0);
        BigDecimal x1Bi = BigDecimal.valueOf(x1);
        BigDecimal bBi = BigDecimal.valueOf(b);
        MathContext mc = new MathContext(digits);
        BigDecimal fractionPrior = x1Bi.divide(x0Bi, mc);
        int iterations = 0;
        while ( true ) {
            iterations++;
            BigDecimal x = bBi.multiply(x1Bi).add(x0Bi);
            BigDecimal fractionCurrent = x.divide(x1Bi, mc);
            if ( fractionCurrent.compareTo(fractionPrior) == 0 ) {
                break;
            }
            x0Bi = x1Bi;
            x1Bi = x;
            fractionPrior = fractionCurrent;
        }
        return new BigDecimal[] {fractionPrior, BigDecimal.valueOf(iterations)};
    }

    private static List<BigInteger> lucasSequence(int x0, int x1, int b, int n) {
        List<BigInteger> list = new ArrayList<>();
        BigInteger x0Bi = BigInteger.valueOf(x0);
        BigInteger x1Bi = BigInteger.valueOf(x1);
        BigInteger bBi = BigInteger.valueOf(b);
        if ( n > 0 ) {
            list.add(x0Bi);
        }
        if ( n > 1 ) {
            list.add(x1Bi);
        }
        while ( n > 2 ) {
            BigInteger x = bBi.multiply(x1Bi).add(x0Bi);
            list.add(x);
            n--;
            x0Bi = x1Bi;
            x1Bi = x;
        }
        return list;
    }

}


def makeSemaphore(maximum :(int > 0)) {
    var current := 0
    def waiters := <elib:vat.makeQueue>()
    def notify() {
        while (current < maximum && waiters.hasMoreElements()) {
            current += 1
            waiters.optDequeue().resolve(def released)
            when (released) -> {
                current -= 1
                notify()
            }
        }
    }
    def semaphore {
        to acquire() {
            waiters.enqueue(def response)
            notify()
            return response
        }
        to count() { return current }
    }
    return semaphore
}

def work(label, interval, semaphore, timer, println) {
    when (def releaser := semaphore <- acquire()) -> {
        println(`$label: I have acquired the lock.`)
        releaser.resolve(
            timer.whenPast(timer.now() + interval, fn {
                println(`$label: I will have released the lock.`)
            })
        )
    }
}

def semaphore := makeSemaphore(3)
for i in 1..5 {
    work(i, 2000, semaphore, timer, println)
}


(require 'tasks) ;; tasks library

(define (task id)
	(wait S) ;; acquire, p-op
	(printf "task %d acquires semaphore @ %a" id (date->time-string (current-date)))
	(sleep 2000)
	(signal S) ;; release, v-op
	id)

(define S (make-semaphore 4)) ;; semaphore with init count 4

;; run 10 // tasks
(for ([i 10]) (task-run (make-task task i ) (random 500)))


using Formatting
import Base.iterate, Base.IteratorSize, Base.IteratorEltype, Base.Iterators.take

const metallicnames = ["Platinum", "Golden", "Silver", "Bronze", "Copper", "Nickel",
    "Aluminium", "Iron", "Tin", "Lead"]

struct Lucas b::Int end
Base.IteratorSize(s::Lucas) = Base.IsInfinite()
Base.IteratorEltype(s::Lucas) = BigInt
Base.iterate(s::Lucas, (x1, x2) = (big"1", big"1")) = (t = x2 * s.b + x1; (x1, (x2, t)))

printlucas(b, len=15) = (for i in take(Lucas(b), len) print(i, ", ") end; println("..."))

function lucasratios(b, len)
	iter = BigFloat.(collect(take(Lucas(b), len + 1)))
	return map(i -> iter[i + 1] / iter[i], 1:length(iter)-1)
end

function metallic(b, dplaces=32)
    setprecision(dplaces * 5)
    ratios, err = lucasratios(b, dplaces * 50), BigFloat(10)^(-dplaces)
    errors = map(i -> abs(ratios[i + 1] - ratios[i]), 1:length(ratios)-1)
    iternum = findfirst(x -> x < err, errors)
    println("After $(iternum + 1) iterations, the value of ",
		format(ratios[iternum + 1], precision=dplaces),
		" is stable to $dplaces decimal places.\n")
end

for (b, name) in enumerate(metallicnames)
    println("The first 15 elements of the Lucas sequence named ",
            metallicnames[b], " and b of $(b - 1) are:")
    printlucas(b - 1)
    metallic(b - 1)
end
println("Golden ratio to 256 decimal places:")
metallic(1, 256)


import java.math.BigDecimal
import java.math.BigInteger

val names = listOf("Platinum", "Golden", "Silver", "Bronze", "Copper", "Nickel", "Aluminium", "Iron", "Tin", "Lead")

fun lucas(b: Long) {
    println("Lucas sequence for ${names[b.toInt()]} ratio, where b = $b:")
    print("First 15 elements: ")
    var x0 = 1L
    var x1 = 1L
    print("$x0, $x1")
    for (i in 1..13) {
        val x2 = b * x1 + x0
        print(", $x2")
        x0 = x1
        x1 = x2
    }
    println()
}

fun metallic(b: Long, dp:Int) {
    var x0 = BigInteger.ONE
    var x1 = BigInteger.ONE
    var x2: BigInteger
    val bb = BigInteger.valueOf(b)
    val ratio = BigDecimal.ONE.setScale(dp)
    var iters = 0
    var prev = ratio.toString()
    while (true) {
        iters++
        x2 = bb * x1 + x0
        val thiz = (x2.toBigDecimal(dp) / x1.toBigDecimal(dp)).toString()
        if (prev == thiz) {
            var plural = "s"
            if (iters == 1) {
                plural = ""
            }
            println("Value after $iters iteration$plural: $thiz\n")
            return
        }
        prev = thiz
        x0 = x1
        x1 = x2
    }
}

fun main() {
    for (b in 0L until 10L) {
        lucas(b)
        metallic(b, 32)
    }
    println("Golden ration, where b = 1:")
    metallic(1, 256)
}


ClearAll[FindMetallicRatio]
FindMetallicRatio[b_, digits_] :=
 Module[{n, m, data, acc, old, done = False},
  {n, m} = {1, 1};
  old = -100;
  data = {};
  While[done == False,
   {n, m} = {m, b m + n};
   AppendTo[data, {m, m/n}];
   If[Length[data] > 15,
    If[-N[Log10[Abs[data[[-1, 2]] - data[[-2, 2]]]]] > digits,
     done = True
     ]
    ]
   ];
  acc = -N[Log10[Abs[data[[-1, 2]] - data[[-2, 2]]]]];
  <|"sequence" -> Join[{1, 1}, data[[All, 1]]],
   "ratio" -> data[[All, 2]], "acc" -> acc,
   "steps" -> Length[data]|>
  ]
Do[
 out = FindMetallicRatio[b, 32];
 Print["b=", b];
 Print["b=", b, " first 15=", Take[out["sequence"], 15]];
 Print["b=", b, " ratio=", N[Last[out["ratio"]], {\[Infinity], 33}]];
 Print["b=", b, " Number of steps=", out["steps"]];
 ,
 {b, 0, 9}
 ]
out = FindMetallicRatio[1, 256];
out["steps"]
N[out["ratio"][[-1]], 256]


-module(metered).
-compile(export_all).

create_semaphore(N) ->
    spawn(?MODULE, sem_loop, [N,N]).

sem_loop(0,Max) ->
    io:format("Resources exhausted~n"),
    receive
        {release, PID} ->
            PID ! released,
            sem_loop(1,Max);
        {stop, _PID} ->
            ok
    end;
sem_loop(N,N) ->
    receive
        {acquire, PID} ->
            PID ! acquired,
            sem_loop(N-1,N);
        {stop, _PID} ->
            ok
    end;
sem_loop(N,Max) ->
    receive
        {release, PID} ->
            PID ! released,
            sem_loop(N+1,Max);
        {acquire, PID} ->
            PID ! acquired,
            sem_loop(N-1,Max);
        {stop, _PID} ->
            ok
    end.

release(Sem) ->
    Sem ! {release, self()},
    receive
        released ->
            ok
    end.
acquire(Sem) ->
    Sem ! {acquire, self()},
    receive
        acquired ->
            ok
    end.

start() -> create_semaphore(10).

stop(Sem) -> Sem ! {stop, self()}.

worker(P,N,Sem) ->
    acquire(Sem),
    io:format("Worker ~b has the acquired semaphore~n",[N]),
    timer:sleep(500 * random:uniform(4)),
    release(Sem),
    io:format("Worker ~b has released the semaphore~n",[N]),
    P ! {done, self()}.

test() ->
    Sem = start(),
    Pids = lists:map(fun (N) ->
                             spawn(?MODULE, worker, [self(),N,Sem])
                     end, lists:seq(1,20)),
    lists:foreach(fun (P) -> receive {done, P} -> ok end end, Pids),
    stop(Sem).


import strformat
import bignum

type Metal {.pure.} = enum platinum, golden, silver, bronze, copper, nickel, aluminium, iron, tin, lead

iterator sequence(b: int): Int =
  ## Yield the successive terms if a “Lucas” sequence.
  ## The first two terms are ignored.
  var x, y = newInt(1)
  while true:
    x += b * y
    swap x, y
    yield y

template plural(n: int): string =
  if n >= 2: "s" else: ""

proc computeRatio(b: Natural; digits: Positive) =
  ## Compute the ratio for the given "n" with the required number of digits.

  let M = 10^culong(digits)

  var niter = 0           # Number of iterations.
  var prevN = newInt(1)   # Previous value of "n".
  var ratio = M           # Current value of ratio.

  for n in sequence(b):
    inc niter
    let nextRatio = n * M div prevN
    if nextRatio == ratio: break
    prevN = n.clone
    ratio = nextRatio

  var str = $ratio
  str.insert(".", 1)
  echo &"Value to {digits} decimal places after {niter} iteration{plural(niter)}: ", str

when isMainModule:

  for b in 0..9:
    echo &"“Lucas” sequence for {Metal(b)} ratio where b = {b}:"
    stdout.write "First 15 elements: 1 1"
    var count = 2
    for n in sequence(b):
      stdout.write ' ', n
      inc count
      if count == 15: break
    echo ""
    computeRatio(b, 32)
    echo ""

  echo "Golden ratio where b = 1:"
  computeRatio(1, 256)


use strict;
use warnings;
use feature qw(say state);
use Math::AnyNum qw<:overload as_dec>;

sub gen_lucas {
    my $b = shift;
    my $i = 0;
    return sub {
        state @seq = (state $v1 = 1, state $v2 = 1);
        ($v2, $v1) = ($v1, $v2 + $b*$v1) and push(@seq, $v1) unless defined $seq[$i+1];
        return $seq[$i++];
    }
}

sub metallic {
    my $lucas  = shift;
    my $places = shift || 32;
    my $n = my $last = 0;
    my @seq = $lucas->();
    while (1) {
        push @seq, $lucas->();
        my $this = as_dec( $seq[-1]/$seq[-2], $places+1 );
        last if $this eq $last;
        $last = $this;
        $n++;
    }
    $last, $n
}

my @name = <Platinum Golden Silver Bronze Copper Nickel Aluminum Iron Tin Lead>;

for my $b (0..$#name) {
    my $lucas = gen_lucas($b);
    printf "\n'Lucas' sequence for $name[$b] ratio, where b = $b:\nFirst 15 elements: " . join ', ', map { $lucas->() } 1..15;
    printf "Approximated value %s reached after %d iterations\n", metallic(gen_lucas($b));
}

printf "\nGolden ratio to 256 decimal places %s reached after %d iterations", metallic(gen_lucas(1),256);


sequence sems
sems = {}
constant COUNTER = 1, QUEUE = 2

function semaphore(integer n)
    if n > 0 then
        sems = append(sems,{n,{}})
        return length(sems)
    else
        return 0
    end if
end function

procedure acquire(integer id)
    if sems[id][COUNTER] = 0 then
        task_suspend(task_self())
        sems[id][QUEUE] &= task_self()
        task_yield()
    end if
    sems[id][COUNTER] -= 1
end procedure

procedure release(integer id)
    sems[id][COUNTER] += 1
    if length(sems[id][QUEUE])>0 then
        task_schedule(sems[id][QUEUE][1],1)
        sems[id][QUEUE] = sems[id][QUEUE][2..$]
    end if
end procedure

function count(integer id)
    return sems[id][COUNTER]
end function

procedure delay(atom delaytime)
    atom t
    t = time()
    while time() - t < delaytime do
        task_yield()
    end while
end procedure

integer sem

procedure worker()
    acquire(sem)
        printf(1,"- Task %d acquired semaphore.\n",task_self())
        delay(2)
    release(sem)
    printf(1,"+ Task %d released semaphore.\n",task_self())
end procedure

integer task

sem = semaphore(4)

for i = 1 to 10 do
    task = task_create(routine_id("worker"),{})
    task_schedule(task,1)
    task_yield()
end for

while length(task_list())>1 do
    task_yield()
end while


USING: calendar calendar.format concurrency.combinators
concurrency.semaphores formatting kernel sequences threads ;

10 <iota> 2 <semaphore>
[
    [
        dup now timestamp>hms
        "task %d acquired semaphore at %s\n" printf
        2 seconds sleep
    ] with-semaphore
    "task %d released\n" printf
] curry parallel-each


with javascript_semantics
include mpfr.e

constant names = {"Platinum", "Golden", "Silver", "Bronze", "Copper",
                  "Nickel", "Aluminium", "Iron", "Tin", "Lead"}

procedure lucas(integer b)
    printf(1,"Lucas sequence for %s ratio, where b = %d:\n", {names[b+1], b})
    atom x0 = 1, x1 = 1, x2
    printf(1,"First 15 elements: %d, %d", {x0, x1})
    for i=1 to 13 do
        x2 = b*x1 + x0
        printf(1,", %d", x2)
        x0 = x1
        x1 = x2
    end for
    printf(1,"\n")
end procedure

procedure metallic(integer b, dp)
    mpz {x0, x1, x2, bb} = mpz_inits(4,{1,1,0,b})
    mpfr ratio = mpfr_init(1,-(dp+2))
    integer iterations = 0
    string prev = mpfr_get_fixed(ratio,dp)
    while true do
        iterations += 1
        mpz_mul(x2,bb,x1)
        mpz_add(x2,x2,x0)
        mpfr_set_z(ratio,x2)
        mpfr_div_z(ratio,ratio,x1)
        string curr = mpfr_get_fixed(ratio,dp)
        if prev == curr then
            string plural = iff(iterations=1?"":"s")
            curr = shorten(curr)
            printf(1,"Value to %d dp after %2d iteration%s: %s\n\n", {dp, iterations, plural, curr})
            exit
        end if
        prev = curr
        mpz_set(x0,x1)
        mpz_set(x1,x2)
    end while
end procedure

procedure main()
    for b=0 to 9 do
        lucas(b)
        metallic(b, 32)
    end for
    printf(1,"Golden ratio, where b = 1:\n")
    metallic(1, 256)
end procedure
main()


#define MaxThreads  10

Dim Shared As Any Ptr ttylock

' Teletype unfurls some text across the screen at a given location
Sub teletype(Byref texto As String, Byval x As Integer, Byval y As Integer)
    ' This MutexLock makes simultaneously running threads wait for each other,
    ' so only one at a time can continue and print output.
    ' Otherwise, their Locates would interfere, since there is only one cursor.
    '
    ' It's impossible to predict the order in which threads will arrive here and
    ' which one will be the first to acquire the lock thus causing the rest to wait.

    Mutexlock ttylock

    For i As Integer = 0 To (Len(texto) - 1)
        Locate x, y + i : Print Chr(texto[i])
        Sleep 25, 1
    Next i

    ' MutexUnlock releases the lock and lets other threads acquire it.
    Mutexunlock ttylock
End Sub

Sub thread(Byval userdata As Any Ptr)
    Dim As Integer id = Cint(userdata)
    teletype "Thread #" & id & " .........", 1 + id, 1
End Sub

' Create a mutex to syncronize the threads
ttylock = Mutexcreate()

' Create child threads
Dim As Any Ptr handles(0 To MaxThreads-1)
For i As Integer = 0 To MaxThreads-1
    handles(i) = Threadcreate(@thread, Cptr(Any Ptr, i))
    If handles(i) = 0 Then Print "Error creating thread:"; i : Exit For
Next i

' This is the main thread. Now wait until all child threads have finished.
For i As Integer = 0 To MaxThreads-1
    If handles(i) <> 0 Then Threadwait(handles(i))
Next i

' Clean up when finished
Mutexdestroy(ttylock)
Sleep


package main

import (
    "log"
    "os"
    "sync"
    "time"
)

// counting semaphore implemented with a buffered channel
type sem chan struct{}

func (s sem) acquire()   { s <- struct{}{} }
func (s sem) release()   { <-s }
func (s sem) count() int { return cap(s) - len(s) }

// log package serializes output
var fmt = log.New(os.Stdout, "", 0)

// library analogy per WP article
const nRooms = 10
const nStudents = 20

func main() {
    rooms := make(sem, nRooms)
    // WaitGroup used to wait for all students to have studied
    // before terminating program
    var studied sync.WaitGroup
    studied.Add(nStudents)
    // nStudents run concurrently
    for i := 0; i < nStudents; i++ {
        go student(rooms, &studied)
    }
    studied.Wait()
}

func student(rooms sem, studied *sync.WaitGroup) {
    rooms.acquire()
    // report per task descrption.  also exercise count operation
    fmt.Printf("Room entered.  Count is %d.  Studying...\n",
        rooms.count())
    time.Sleep(2 * time.Second) // sleep per task description
    rooms.release()
    studied.Done() // signal that student is done
}


from itertools import count, islice
from _pydecimal import getcontext, Decimal

def metallic_ratio(b):
    m, n = 1, 1
    while True:
        yield m, n
        m, n = m*b + n, m

def stable(b, prec):
    def to_decimal(b):
        for m,n in metallic_ratio(b):
            yield Decimal(m)/Decimal(n)

    getcontext().prec = prec
    last = 0
    for i,x in zip(count(), to_decimal(b)):
        if x == last:
            print(f'after {i} iterations:\n\t{x}')
            break
        last = x

for b in range(4):
    coefs = [n for _,n in islice(metallic_ratio(b), 15)]
    print(f'\nb = {b}: {coefs}')
    stable(b, 32)

print(f'\nb = 1 with 256 digits:')
stable(1, 256)


use Rat::Precise;
use Lingua::EN::Numbers;

sub lucas ($b) { 1, 1, * + $b * * … * }

sub metallic ($seq, $places = 32) {
    my $n = 0;
    my $last = 0;
    loop {
        my $approx = FatRat.new($seq[$n + 1], $seq[$n]);
        my $this = $approx.precise($places, :z);
        last if $this eq $last;
        $last = $this;
        $n++;
    }
    $last, $n
}

sub display ($value, $n) {
    "Approximated value:", $value, "Reached after {$n} iterations: " ~
    "{ordinal-digit $n}/{ordinal-digit $n - 1} element."
}

for <Platinum Golden Silver Bronze Copper Nickel Aluminum Iron Tin Lead>.kv
  -> \b, $name {
    my $lucas = lucas b;
    print "\nLucas sequence for $name ratio; where b = {b}:\nFirst 15 elements: ";
    say join ', ', $lucas[^15];
    say join ' ', display |metallic($lucas);
}

# Stretch goal
say join "\n", "\nGolden ratio to 256 decimal places:", display |metallic lucas(1), 256;


class CountingSemaphore {
    private int count = 0
    private final int max

    CountingSemaphore(int max) { this.max = max }

    synchronized int acquire() {
        while (count >= max) { wait() }
        ++count
    }

    synchronized int release() {
        if (count) { count--; notifyAll() }
        count
    }

    synchronized int getCount() { count }
}


import Control.Concurrent
    ( newQSem,
      signalQSem,
      waitQSem,
      threadDelay,
      forkIO,
      newEmptyMVar,
      putMVar,
      takeMVar,
      QSem,
      MVar )
import Control.Monad ( replicateM_ )

worker :: QSem -> MVar String -> Int -> IO ()
worker q m n = do
  waitQSem q
  putMVar m $ "Worker " <> show n <> " has acquired the lock."
  threadDelay 2000000 -- microseconds!
  signalQSem q
  putMVar m $ "Worker " <> show n <> " has released the lock."

main :: IO ()
main = do
  q <- newQSem 3
  m <- newEmptyMVar
  let workers = 5
      prints = 2 * workers
  mapM_ (forkIO . worker q m) [1 .. workers]
  replicateM_ prints $ takeMVar m >>= putStrLn