using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using IntMap = System.Collections.Generic.Dictionary<int, int>;

public static class CyclotomicPolynomial
{
    public static void Main2() {
        Console.WriteLine("Task 1: Cyclotomic polynomials for n <= 30:");
        for (int i = 1; i <= 30; i++) {
            var p = GetCyclotomicPolynomial(i);
            Console.WriteLine($"CP[{i}] = {p.ToString()}");
        }
        Console.WriteLine();

        Console.WriteLine("Task 2: Smallest cyclotomic polynomial with n or -n as a coefficient:");
        for (int i = 1, n = 0; i <= 10; i++) {
            while (true) {
                n++;
                var p = GetCyclotomicPolynomial(n);
                if (p.Any(t => Math.Abs(t.Coefficient) == i)) {
                    Console.WriteLine($"CP[{n}] has coefficient with magnitude = {i}");
                    n--;
                    break;
                }
            }
        }
    }

    private const int MaxFactors = 100_000;
    private const int Algorithm = 2;
    private static readonly Term x = new Term(1, 1);
    private static readonly Dictionary<int, Polynomial> polyCache =
        new Dictionary<int, Polynomial> { [1] = x - 1 };
    private static readonly Dictionary<int, IntMap> factorCache =
        new Dictionary<int, IntMap> { [2] = new IntMap { [2] = 1 } };

    private static Polynomial GetCyclotomicPolynomial(in int n) {
        if (polyCache.TryGetValue(n, out var result)) return result;

        var factors = GetFactors(n);
        if (factors.ContainsKey(n)) { //n is prime
            result = new Polynomial(from exp in ..n select x[exp]);
        } else if (factors.Count == 2 && factors.Contains(2, 1) && factors.Contains(n/2, 1)) { //n = 2p
            result = new Polynomial(from i in ..(n/2) select (IsOdd(i) ? -x : x)[i]);
        } else if (factors.Count == 1 && factors.TryGetValue(2, out int h)) { //n = 2^h
            result = x[1<<(h-1)] + 1;
        } else if (factors.Count == 1 && !factors.ContainsKey(n)) { // n = p^k
            (int p, int k) = factors.First();
            result = new Polynomial(from i in ..p select x[i * (int)Math.Pow(p, k-1)]);
        } else if (factors.Count == 2 && factors.ContainsKey(2)) { //n = 2^h * p^k
            (int p, int k) = factors.First(entry => entry.Key != 2);
            int twoExp = 1 << (factors[2] - 1);
            result = new Polynomial(from i in ..p select (IsOdd(i) ? -x : x)[i * twoExp * (int)Math.Pow(p, k-1)]);
        } else if (factors.ContainsKey(2) && IsOdd(n/2) && n/2 > 1) { // CP(2m)[x] = CP[-m][x], n is odd > 1
            Polynomial cycloDiv2 = GetCyclotomicPolynomial(n/2);
            result = new Polynomial(from term in cycloDiv2 select IsOdd(term.Exponent) ? -term : term);
            #pragma warning disable CS0162
        } else if (Algorithm == 0) {
            var divisors = GetDivisors(n);
            result = x[n] - 1;
            foreach (int d in divisors) result /= GetCyclotomicPolynomial(d);
        } else if (Algorithm == 1) {
            var divisors = GetDivisors(n).ToList();
            int maxDivisor = divisors.Max();
            result = (x[n] - 1) / (x[maxDivisor] - 1);
            foreach (int d in divisors.Where(div => maxDivisor % div == 0)) {
                result /= GetCyclotomicPolynomial(d);
            }
        } else if (Algorithm == 2) {
            int m = 1;
            result = GetCyclotomicPolynomial(m);
            var primes = factors.Keys.ToList();
            primes.Sort();
            foreach (int prime in primes) {
                var cycloM = result;
                result = new Polynomial(from term in cycloM select term.Coefficient * x[term.Exponent * prime]);
                result /= cycloM;
                m *= prime;
            }
            int s = n / m;
            result = new Polynomial(from term in result select term.Coefficient * x[term.Exponent * s]);
            #pragma warning restore CS0162
        } else {
            throw new InvalidOperationException("Invalid algorithm");
        }
        polyCache[n] = result;
        return result;
    }

    private static bool IsOdd(int i) => (i & 1) != 0;
    private static bool Contains(this IntMap map, int key, int value) => map.TryGetValue(key, out int v) && v == value;
    private static int GetOrZero(this IntMap map, int key) => map.TryGetValue(key, out int v) ? v : 0;
    private static IEnumerable<T> Select<T>(this Range r, Func<int, T> f) => Enumerable.Range(r.Start.Value, r.End.Value - r.Start.Value).Select(f);

    private static IntMap GetFactors(in int n) {
        if (factorCache.TryGetValue(n, out var factors)) return factors;

        factors = new IntMap();
        if (!IsOdd(n)) {
            foreach (var entry in GetFactors(n/2)) factors.Add(entry.Key, entry.Value);
            factors[2] = factors.GetOrZero(2) + 1;
            return Cache(n, factors);
        }
        for (int i = 3; i * i <= n; i+=2) {
            if (n % i == 0) {
                foreach (var entry in GetFactors(n/i)) factors.Add(entry.Key, entry.Value);
                factors[i] = factors.GetOrZero(i) + 1;
                return Cache(n, factors);
            }
        }
        factors[n] = 1;
        return Cache(n, factors);
    }

    private static IntMap Cache(int n, IntMap factors) {
        if (n < MaxFactors) factorCache[n] = factors;
        return factors;
    }

    private static IEnumerable<int> GetDivisors(int n) {
        for (int i = 1; i * i <= n; i++) {
            if (n % i == 0) {
                yield return i;
                int div = n / i;
                if (div != i && div != n) yield return div;
            }
        }
    }

    public sealed class Polynomial : IEnumerable<Term>
    {
        public Polynomial() { }
        public Polynomial(params Term[] terms) : this(terms.AsEnumerable()) { }

        public Polynomial(IEnumerable<Term> terms) {
            Terms.AddRange(terms);
            Simplify();
        }

        private List<Term>? terms;
        private List<Term> Terms => terms ??= new List<Term>();

        public int Count => terms?.Count ?? 0;
        public int Degree => Count == 0 ? -1 : Terms[0].Exponent;
        public int LeadingCoefficient => Count == 0 ? 0 : Terms[0].Coefficient;

        public IEnumerator<Term> GetEnumerator() => Terms.GetEnumerator();
        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();

        public override string ToString() => Count == 0 ? "0" : string.Join(" + ", Terms).Replace("+ -", "- ");

        public static Polynomial operator *(Polynomial p, Term t) => new Polynomial(from s in p select s * t);
        public static Polynomial operator +(Polynomial p, Polynomial q) => new Polynomial(p.Terms.Concat(q.Terms));
        public static Polynomial operator -(Polynomial p, Polynomial q) => new Polynomial(p.Terms.Concat(q.Terms.Select(t => -t)));
        public static Polynomial operator *(Polynomial p, Polynomial q) => new Polynomial(from s in p from t in q select s * t);
        public static Polynomial operator /(Polynomial p, Polynomial q) => p.Divide(q).quotient;

        public (Polynomial quotient, Polynomial remainder) Divide(Polynomial divisor) {
            if (Degree < 0) return (new Polynomial(), this);
            Polynomial quotient = new Polynomial();
            Polynomial remainder = this;
            int lcv = divisor.LeadingCoefficient;
            int dv = divisor.Degree;
            while (remainder.Degree >= divisor.Degree) {
                int lcr = remainder.LeadingCoefficient;
                Term div = new Term(lcr / lcv, remainder.Degree - dv);
                quotient.Terms.Add(div);
                remainder += divisor * -div;
            }
            quotient.Simplify();
            remainder.Simplify();
            return (quotient, remainder);
        }

        private void Simplify() {
            if (Count < 2) return;
            Terms.Sort((a, b) => -a.CompareTo(b));
            for (int i = Terms.Count - 1; i > 0; i--) {
                Term s = Terms[i-1];
                Term t = Terms[i];
                if (t.Exponent == s.Exponent) {
                    Terms[i-1] = new Term(s.Coefficient + t.Coefficient, s.Exponent);
                    Terms.RemoveAt(i);
                }
            }
            Terms.RemoveAll(t => t.IsZero);
        }

    }

    public readonly struct Term : IEquatable<Term>, IComparable<Term>
    {
        public Term(int coefficient, int exponent = 0) => (Coefficient, Exponent) = (coefficient, exponent);

        public Term this[int exponent] => new Term(Coefficient, exponent); //Using x[exp] because x^exp has low precedence
        public int Coefficient { get; }
        public int Exponent { get; }
        public bool IsZero => Coefficient == 0;

        public static Polynomial operator +(Term left, Term right) => new Polynomial(left, right);
        public static Polynomial operator -(Term left, Term right) => new Polynomial(left, -right);
        public static implicit operator Term(int coefficient) => new Term(coefficient);
        public static Term operator -(Term t) => new Term(-t.Coefficient, t.Exponent);
        public static Term operator *(Term left, Term right) => new Term(left.Coefficient * right.Coefficient, left.Exponent + right.Exponent);

        public static bool operator ==(Term left, Term right) => left.Equals(right);
        public static bool operator !=(Term left, Term right) => !left.Equals(right);
        public static bool operator  <(Term left, Term right) => left.CompareTo(right)  < 0;
        public static bool operator  >(Term left, Term right) => left.CompareTo(right)  > 0;
        public static bool operator <=(Term left, Term right) => left.CompareTo(right) <= 0;
        public static bool operator >=(Term left, Term right) => left.CompareTo(right) >= 0;

        public bool Equals(Term other) => Exponent == other.Exponent && Coefficient == other.Coefficient;
        public override bool Equals(object? obj) => obj is Term t && Equals(t);
        public override int GetHashCode() => Coefficient.GetHashCode() * 31 + Exponent.GetHashCode();

        public int CompareTo(Term other) {
            int c = Exponent.CompareTo(other.Exponent);
            if (c != 0) return c;
            return Coefficient.CompareTo(other.Coefficient);
        }

        public override string ToString() => (Coefficient, Exponent) switch {
            (0,  _) => "0",
            (_,  0) => $"{Coefficient}",
            (1,  1) => "x",
            (-1, 1) => "-x",
            (_,  1) => $"{Coefficient}x",
            (1,  _) => $"x^{Exponent}",
            (-1, _) => $"-x^{Exponent}",
                    _ => $"{Coefficient}x^{Exponent}"
        };
    }
}


# cusip.icn -- Committee on Uniform Security Identification Procedures

procedure main()
   local code, codes
   codes := ["037833100", "17275R102", "38259P508",
            "594918104", "68389X106", "68389X105"]
   while code := pop(codes) do {
      writes(code, " : ")
      if check_code(code) then
         write("valid.")
      else write("not valid.")
      }
end

procedure check_code(c)
   local p, sum, value
   static codetable
   initial codetable := buildtable()

   sum   := 0
   value := 0
   every p := 1 to 8 do {
      if p % 2 = 1 then    # odd position
         value := codetable[c[p]]
      else                 # even position
         value := 2 * codetable[c[p]]
      sum +:= (value / 10) + (value % 10)
      }
   sum := (10 - (sum % 10)) % 10
   if sum = c[9] then return else fail
end

procedure buildtable()
   local chars, n, t
   t := table()
   chars := &digits || &ucase || "*@#"
   every n := 1 to *chars do
      t[chars[n]] := (n - 1)
   return t
end


class CubanPrimes {
    private static int MAX = 1_400_000
    private static boolean[] primes = new boolean[MAX]

    static void main(String[] args) {
        preCompute()
        cubanPrime(200, true)
        for (int i = 1; i <= 5; i++) {
            int max = (int) Math.pow(10, i)
            printf("%,d-th cuban prime = %,d%n", max, cubanPrime(max, false))
        }
    }

    private static long cubanPrime(int n, boolean display) {
        int count = 0
        long result = 0
        for (long i = 0; count < n; i++) {
            long test = 1l + 3 * i * (i + 1)
            if (isPrime(test)) {
                count++
                result = test
                if (display) {
                    printf("%10s%s", String.format("%,d", test), count % 10 == 0 ? "\n" : "")
                }
            }
        }
        return result
    }

    private static boolean isPrime(long n) {
        if (n < MAX) {
            return primes[(int) n]
        }
        int max = (int) Math.sqrt(n)
        for (int i = 3; i <= max; i++) {
            if (primes[i] && n % i == 0) {
                return false
            }
        }
        return true
    }

    private static final void preCompute() {
        //  primes
        for (int i = 2; i < MAX; i++) {
            primes[i] = true
        }
        for (int i = 2; i < MAX; i++) {
            if (primes[i]) {
                for (int j = 2 * i; j < MAX; j += i) {
                    primes[j] = false
                }
            }
        }
    }
}


import std.algorithm;
import std.exception;
import std.format;
import std.functional;
import std.math;
import std.range;
import std.stdio;

immutable MAX_ALL_FACTORS = 100_000;
immutable ALGORITHM = 2;

//Note: Cyclotomic Polynomials have small coefficients.  Not appropriate for general polynomial usage.

struct Term {
    private long m_coefficient;
    private long m_exponent;

    public this(long c, long e) {
        m_coefficient = c;
        m_exponent = e;
    }

    public long coefficient() const {
        return m_coefficient;
    }

    public long exponent() const {
        return m_exponent;
    }

    public Term opUnary(string op)() const {
        static if (op == "-") {
            return Term(-m_coefficient, m_exponent);
        } else {
            assert(false, "Not implemented");
        }
    }

    public Term opBinary(string op)(Term term) const {
        static if (op == "+") {
            if (exponent() != term.exponent()) {
                assert(false, "Error 102: Exponents not equals.");
            }
            return Term(coefficient() + term.coefficient(), exponent());
        } else if (op == "*") {
            return Term(coefficient() * term.coefficient(), exponent() + term.exponent());
        } else {
            assert(false, "Not implemented: " ~ op);
        }
    }

    public void toString(scope void delegate(const(char)[]) sink) const {
        auto spec = singleSpec("%s");
        if (m_coefficient == 0) {
            sink("0");
        } else if (m_exponent == 0) {
            formatValue(sink, m_coefficient, spec);
        } else if (m_coefficient == 1) {
            if (m_exponent == 1) {
                sink("x");
            } else {
                sink("x^");
                formatValue(sink, m_exponent, spec);
            }
        } else if (m_coefficient == -1) {
            if (m_exponent == 1) {
                sink("-x");
            } else {
                sink("-x^");
                formatValue(sink, m_exponent, spec);
            }
        } else if (m_exponent == 1) {
            formatValue(sink, m_coefficient, spec);
            sink("x");
        } else {
            formatValue(sink, m_coefficient, spec);
            sink("x^");
            formatValue(sink, m_exponent, spec);
        }
    }
}

struct Polynomial {
    private Term[] terms;

    public this(const Term[] ts...) {
        terms = ts.dup;
        terms.sort!"b.exponent < a.exponent";
    }

    bool hasCoefficientAbs(int coeff) const {
        foreach (term; terms) {
            if (abs(term.coefficient) == coeff) {
                return true;
            }
        }
        return false;
    }

    public long leadingCoefficient() const {
        return terms[0].coefficient();
    }

    public long degree() const {
        if (terms.empty) {
            return -1;
        }
        return terms[0].exponent();
    }

    public Polynomial opBinary(string op)(Term term) const {
        static if (op == "+") {
            Term[] newTerms;
            auto added = false;
            foreach (currentTerm; terms) {
                if (currentTerm.exponent() == term.exponent()) {
                    added = true;
                    if (currentTerm.coefficient() + term.coefficient() != 0) {
                        newTerms ~= currentTerm + term;
                    }
                } else {
                    newTerms ~= currentTerm;
                }
            }
            if (!added) {
                newTerms ~= term;
            }
            return Polynomial(newTerms);
        } else if (op == "*") {
            Term[] newTerms;
            foreach (currentTerm; terms) {
                newTerms ~= currentTerm * term;
            }
            return Polynomial(newTerms);
        } else {
            assert(false, "Not implemented: " ~ op);
        }
    }

    public Polynomial opBinary(string op)(Polynomial rhs) const {
        static if (op == "+") {
            Term[] newTerms;
            auto thisCount = terms.length;
            auto polyCount = rhs.terms.length;
            while (thisCount > 0 || polyCount > 0) {
                if (thisCount == 0) {
                    newTerms ~= rhs.terms[polyCount - 1];
                    polyCount--;
                } else if (polyCount == 0) {
                    newTerms ~= terms[thisCount - 1];
                    thisCount--;
                } else {
                    auto thisTerm = terms[thisCount - 1];
                    auto polyTerm = rhs.terms[polyCount - 1];
                    if (thisTerm.exponent() == polyTerm.exponent()) {
                        auto t = thisTerm + polyTerm;
                        if (t.coefficient() != 0) {
                            newTerms ~= t;
                        }
                        thisCount--;
                        polyCount--;
                    } else if (thisTerm.exponent() < polyTerm.exponent()) {
                        newTerms ~= thisTerm;
                        thisCount--;
                    } else {
                        newTerms ~= polyTerm;
                        polyCount--;
                    }
                }
            }
            return Polynomial(newTerms);
        } else if (op == "/") {
            Polynomial q;
            auto r = Polynomial(terms);
            auto lcv = rhs.leadingCoefficient();
            auto dv = rhs.degree();
            while (r.degree() >= rhs.degree()) {
                auto lcr = r.leadingCoefficient();
                auto s = lcr / lcv;
                auto term = Term(s, r.degree() - dv);
                q = q + term;
                r = r + rhs * -term;
            }
            return q;
        } else {
            assert(false, "Not implemented: " ~ op);
        }
    }

    public int opApply(int delegate(Term) dg) const {
        foreach (term; terms) {
            auto rv = dg(term);
            if (rv != 0) {
                return rv;
            }
        }
        return 0;
    }

    public void toString(scope void delegate(const(char)[]) sink) const {
        auto spec = singleSpec("%s");
        if (!terms.empty) {
            formatValue(sink, terms[0], spec);
            foreach (t; terms[1..$]) {
                if (t.coefficient > 0) {
                    sink(" + ");
                    formatValue(sink, t, spec);
                } else {
                    sink(" - ");
                    formatValue(sink, -t, spec);
                }
            }
        }
    }
}

void putAll(K, V)(ref V[K] a, V[K] b) {
    foreach (k, v; b) {
        a[k] = v;
    }
}

void merge(K, V, F)(ref V[K] a, K k, V v, F f) {
    if (k in a) {
        a[k] = f(a[k], v);
    } else {
        a[k] = v;
    }
}

int sum(int a, int b) {
    return a + b;
}

int[int] getFactorsImpl(int number) {
    int[int] factors;
    if (number % 2 == 0) {
        if (number > 2) {
            auto factorsDivTwo = memoize!getFactorsImpl(number / 2);
            factors.putAll(factorsDivTwo);
        }
        factors.merge(2, 1, &sum);
        return factors;
    }
    auto root = sqrt(cast(real) number);
    auto i = 3;
    while (i <= root) {
        if (number % i == 0) {
            factors.putAll(memoize!getFactorsImpl(number / i));
            factors.merge(i, 1, &sum);
            return factors;
        }
        i += 2;
    }
    factors[number] = 1;
    return factors;
}
alias getFactors = memoize!getFactorsImpl;

int[] getDivisors(int number) {
    int[] divisors;
    auto root = cast(int)sqrt(cast(real) number);
    foreach (i; 1..root) {
        if (number % i == 0) {
            divisors ~= i;
        }
        auto div = number / i;
        if (div != i && div != number) {
            divisors ~= div;
        }
    }
    return divisors;
}

Polynomial cyclotomicPolynomialImpl(int n) {
    if (n == 1) {
        //  Polynomial:  x - 1
        return Polynomial(Term(1, 1), Term(-1, 0));
    }
    auto factors = getFactors(n);
    if (n in factors) {
        // n prime
        Term[] terms;
        foreach (i; 0..n) {
            terms ~= Term(1, i);
        }
        return Polynomial(terms);
    } else if (factors.length == 2 && 2 in factors && factors[2] == 1 && (n / 2) in factors && factors[n / 2] == 1) {
        //  n = 2p
        auto prime = n / 2;
        Term[] terms;
        auto coeff = -1;
        foreach (i; 0..prime) {
            coeff *= -1;
            terms ~= Term(coeff, i);
        }
        return Polynomial(terms);
    } else if (factors.length == 1 && 2 in factors) {
        //  n = 2^h
        auto h = factors[2];
        Term[] terms;
        terms ~= Term(1, 2 ^^ (h - 1));
        terms ~= Term(1, 0);
        return Polynomial(terms);
    } else if (factors.length == 1 && n !in factors) {
        // n = p^k
        auto p = 0;
        auto k = 0;
        foreach (prime, v; factors) {
            if (prime > p) {
                p = prime;
                k = v;
            }
        }
        Term[] terms;
        foreach (i; 0..p) {
            terms ~= Term(1, (i * p) ^^ (k - 1));
        }
        return Polynomial(terms);
    } else if (factors.length == 2 && 2 in factors) {
        // n = 2^h * p^k
        auto p = 0;
        auto k = 0;
        foreach (prime, v; factors) {
            if (prime != 2 && prime > p) {
                p = prime;
                k = v;
            }
        }
        Term[] terms;
        auto coeff = -1;
        auto twoExp = 2 ^^ (factors[2] - 1);
        foreach (i; 0..p) {
            coeff *= -1;
            auto exponent = i * twoExp * p ^^ (k - 1);
            terms ~= Term(coeff, exponent);
        }
        return Polynomial(terms);
    } else if (2 in factors && n / 2 % 2 == 1 && n / 2 > 1) {
        //  CP(2m)[x] = CP(-m)[x], n odd integer > 1
        auto cycloDiv2 = memoize!cyclotomicPolynomialImpl(n / 2);
        Term[] terms;
        foreach (term; cycloDiv2) {
            if (term.exponent() % 2 == 0) {
                terms ~= term;
            } else {
                terms ~= -term;
            }
        }
        return Polynomial(terms);
    }

    if (ALGORITHM == 0) {
        //  Slow - uses basic definition.
        auto divisors = getDivisors(n);
        //  Polynomial:  ( x^n - 1 )
        auto cyclo = Polynomial(Term(1, n), Term(-1, 0));
        foreach (i; divisors) {
            auto p = memoize!cyclotomicPolynomialImpl(i);
            cyclo = cyclo / p;
        }
        return cyclo;
    }
    if (ALGORITHM == 1) {
        //  Faster.  Remove Max divisor (and all divisors of max divisor) - only one divide for all divisors of Max Divisor
        auto divisors = getDivisors(n);
        auto maxDivisor = int.min;
        foreach (div; divisors) {
            maxDivisor = max(maxDivisor, div);
        }
        int[] divisorsExceptMax;
        foreach (div; divisors) {
            if (maxDivisor % div != 0) {
                divisorsExceptMax ~= div;
            }
        }

        //  Polynomial:  ( x^n - 1 ) / ( x^m - 1 ), where m is the max divisor
        auto cyclo = Polynomial(Term(1, n), Term(-1, 0)) / Polynomial(Term(1, maxDivisor), Term(-1, 0));
        foreach (i; divisorsExceptMax) {
            auto p = memoize!cyclotomicPolynomialImpl(i);
            cyclo = cyclo / p;
        }
        return cyclo;
    }
    if (ALGORITHM == 2) {
        //  Fastest
        //  Let p ; q be primes such that p does not divide n, and q q divides n.
        //  Then CP(np)[x] = CP(n)[x^p] / CP(n)[x]
        auto m = 1;
        auto cyclo = memoize!cyclotomicPolynomialImpl(m);
        auto primes = factors.keys;
        primes.sort;
        foreach (prime; primes) {
            //  CP(m)[x]
            auto cycloM = cyclo;
            //  Compute CP(m)[x^p].
            Term[] terms;
            foreach (term; cycloM) {
                terms ~= Term(term.coefficient(), term.exponent() * prime);
            }
            cyclo = Polynomial(terms) / cycloM;
            m *= prime;
        }
        //  Now, m is the largest square free divisor of n
        auto s = n / m;
        //  Compute CP(n)[x] = CP(m)[x^s]
        Term[] terms;
        foreach (term; cyclo) {
            terms ~= Term(term.coefficient(), term.exponent() * s);
        }
        return Polynomial(terms);
    }
    assert(false, "Error 103: Invalid algorithm");
}
alias cyclotomicPolynomial = memoize!cyclotomicPolynomialImpl;

void main() {
    writeln("Task 1:  cyclotomic polynomials for n <= 30:");
   foreach (i; 1 .. 31) {
        auto p = cyclotomicPolynomial(i);
        writefln("CP[%d] = %s", i, p);
   }
    writeln;

    writeln("Task 2:  Smallest cyclotomic polynomial with n or -n as a coefficient:");
    auto n = 0;
    foreach (i; 1 .. 11) {
         while (true) {
            n++;
            auto cyclo = cyclotomicPolynomial(n);
            if (cyclo.hasCoefficientAbs(i)) {
                writefln("CP[%d] has coefficient with magnitude = %d", n, i);
                n--;
                break;
            }
         }
    }
}


import java.util.List;

public class Cusip {
    private static Boolean isCusip(String s) {
        if (s.length() != 9) return false;
        int sum = 0;
        for (int i = 0; i <= 7; i++) {
            char c = s.charAt(i);

            int v;
            if (c >= '0' && c <= '9') {
                v = c - 48;
            } else if (c >= 'A' && c <= 'Z') {
                v = c - 55;  // lower case letters apparently invalid
            } else if (c == '*') {
                v = 36;
            } else if (c == '@') {
                v = 37;
            } else if (c == '#') {
                v = 38;
            } else {
                return false;
            }
            if (i % 2 == 1) v *= 2;  // check if odd as using 0-based indexing
            sum += v / 10 + v % 10;
        }
        return s.charAt(8) - 48 == (10 - (sum % 10)) % 10;
    }

    public static void main(String[] args) {
        List<String> candidates = List.of(
                "037833100", "17275R102", "38259P508", "594918104", "68389X106", "68389X105", "EXTRACRD8",
                "EXTRACRD9", "BADCUSIP!", "683&9X106", "68389x105", "683$9X106", "68389}105", "87264ABE4"
        );
        for (String candidate : candidates) {
            System.out.printf("%s -> %s%n", candidate, isCusip(candidate) ? "correct" : "incorrect");
        }
    }
}


import Data.Numbers.Primes (isPrime)
import Data.List (intercalate)
import Data.List.Split (chunksOf)
import Text.Printf (printf)

cubans :: [Int]
cubans = filter isPrime . map (\x -> (succ x ^ 3) - (x ^ 3)) $ [1 ..]

main :: IO ()
main = do
  mapM_ (\row -> mapM_ (printf "%10s" . thousands) row >> printf "\n") $ rows cubans
  printf "\nThe 100,000th cuban prime is: %10s\n" $ thousands $ cubans !! 99999
  where
    rows = chunksOf 10 . take 200
    thousands = reverse . intercalate "," . chunksOf 3 . reverse . show


isPrime =: 1&p:
assert 1 0 -: isPrime 3 9

NB. difference, but first cube, of incremented y with y
dcc =: -&(^&3)~ >:
assert ((8 9 13^3)-7 8 12^3) -: dcc  7 8 12

Filter =: (#~`)(`:6)
assert 2 3 5 7 11 13 -: isPrime Filter i. 16

cubanPrime =: [: isPrime Filter dcc
assert 7 19 37 61 127 271 331 397 547 631 919 -: cubanPrime i. 20

NB. comatose copies with comma fill
comatose =: (#!.','~ (1 1 1j1 1 1 1j1 1 1 1j1 1 1 1j1 1 1 1j1 1 1 1j1 1 1 1 {.~ [email protected]:#))@:":&>
assert (comatose 1000 1238 12  989832) -: [;._2 ] 0 :0
1,000
1,238
12
989,832
)

   CP =: cubanPrime i. 800000x
   # CP  NB. tally, I've stored more than 100000 cuban primes
103278
   NB. granted, I used wolframalpha Solve[(n+1)^3-n^3==1792617147127,n]

   9!:17]2 2 NB. specify bottom right position in box

   comatose&.> 10 20 $ CP
┌─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┬─────────┐
│        7│       19│       37│       61│      127│      271│      331│      397│      547│      631│      919│    1,657│    1,801│    1,951│    2,269│    2,437│    2,791│    3,169│    3,571│    4,219│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│    4,447│    5,167│    5,419│    6,211│    7,057│    7,351│    8,269│    9,241│   10,267│   11,719│   12,097│   13,267│   13,669│   16,651│   19,441│   19,927│   22,447│   23,497│   24,571│   25,117│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│   26,227│   27,361│   33,391│   35,317│   42,841│   45,757│   47,251│   49,537│   50,311│   55,897│   59,221│   60,919│   65,269│   70,687│   73,477│   74,419│   75,367│   81,181│   82,171│   87,211│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│   88,237│   89,269│   92,401│   96,661│  102,121│  103,231│  104,347│  110,017│  112,327│  114,661│  115,837│  126,691│  129,169│  131,671│  135,469│  140,617│  144,541│  145,861│  151,201│  155,269│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│  163,567│  169,219│  170,647│  176,419│  180,811│  189,757│  200,467│  202,021│  213,067│  231,019│  234,361│  241,117│  246,247│  251,431│  260,191│  263,737│  267,307│  276,337│  279,991│  283,669│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│  285,517│  292,969│  296,731│  298,621│  310,087│  329,677│  333,667│  337,681│  347,821│  351,919│  360,187│  368,551│  372,769│  374,887│  377,011│  383,419│  387,721│  398,581│  407,377│  423,001│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│  436,627│  452,797│  459,817│  476,407│  478,801│  493,291│  522,919│  527,941│  553,411│  574,219│  584,767│  590,077│  592,741│  595,411│  603,457│  608,851│  611,557│  619,711│  627,919│  650,071│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│  658,477│  666,937│  689,761│  692,641│  698,419│  707,131│  733,591│  742,519│  760,537│  769,627│  772,669│  784,897│  791,047│  812,761│  825,301│  837,937│  847,477│  863,497│  879,667│  886,177│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│  895,987│  909,151│  915,769│  925,741│  929,077│  932,419│  939,121│  952,597│  972,991│  976,411│  986,707│  990,151│  997,057│1,021,417│1,024,921│1,035,469│1,074,607│1,085,407│1,110,817│1,114,471│
├─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┼─────────┤
│1,125,469│1,155,061│1,177,507│1,181,269│1,215,397│1,253,887│1,281,187│1,285,111│1,324,681│1,328,671│1,372,957│1,409,731│1,422,097│1,426,231│1,442,827│1,451,161│1,480,519│1,484,737│1,527,247│1,570,357│
└─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┴─────────┘

   NB. the one hundred thousandth cuban prime
   comatose (<: 100000) { CP
1,792,617,147,127

   cubanPrime f.              NB. cubanPrime with fixed adverbs
[: (#~ 1&p:) (-&(^&3)~ >:)


******** Standard deviation of a population
STDDEV   CSECT
         USING  STDDEV,R13
SAVEAREA B      STM-SAVEAREA(R15)
         DC     17F'0'
         DC     CL8'STDDEV'
STM      STM    R14,R12,12(R13)
         ST     R13,4(R15)
         ST     R15,8(R13)
         LR     R13,R15
         SR     R8,R8           s=0
         SR     R9,R9           ss=0
         SR     R4,R4           i=0
         LA     R6,1
         LH     R7,N
LOOPI    BXH    R4,R6,ENDLOOPI
         LR     R1,R4           i
         BCTR   R1,0
         SLA    R1,1
         LH     R5,T(R1)
         ST     R5,WW           ww=t(i)
         MH     R5,=H'1000'     w=ww*1000
         AR     R8,R5           s=s+w
         LR     R15,R5
         MR     R14,R5          w*w
         AR     R9,R15          ss=ss+w*w
         LR     R14,R8          s
         SRDA   R14,32
         DR     R14,R4          /i
         ST     R15,AVG         avg=s/i
         LR     R14,R9          ss
         SRDA   R14,32
         DR     R14,R4          ss/i
         LR     R2,R15          ss/i
         LR     R15,R8          s
         MR     R14,R8          s*s
         LR     R3,R15
         LR     R15,R4          i
         MR     R14,R4          i*i
         LR     R1,R15
         LA     R14,0
         LR     R15,R3
         DR     R14,R1          (s*s)/(i*i)
         SR     R2,R15
         LR     R10,R2          std=ss/i-(s*s)/(i*i)
         LR     R11,R10         std
         SRA    R11,1           x=std/2
         LR     R12,R10         px=std
LOOPWHIL EQU    *
         CR     R12,R11         while px<>=x
         BE     ENDWHILE
         LR     R12,R11         px=x
         LR     R15,R10         std
         LA     R14,0
         DR     R14,R12         /px
         LR     R1,R12          px
         AR     R1,R15          px+std/px
         SRA    R1,1            /2
         LR     R11,R1          x=(px+std/px)/2
         B      LOOPWHIL
ENDWHILE EQU    *
         LR     R10,R11
         CVD    R4,P8           i
         MVC    C17,MASK17
         ED     C17,P8
         MVC    BUF+2(1),C17+15
         L      R1,WW
         CVD    R1,P8
         MVC    C17,MASK17
         ED     C17,P8
         MVC    BUF+10(1),C17+15
         L      R1,AVG
         CVD    R1,P8
         MVC    C18,MASK18
         ED     C18,P8
         MVC    BUF+17(5),C18+12
         CVD    R10,P8          std
         MVC    C18,MASK18
         ED     C18,P8
         MVC    BUF+31(5),C18+12
         WTO    MF=(E,WTOMSG)
         B      LOOPI
ENDLOOPI EQU    *
         L      R13,4(0,R13)
         LM     R14,R12,12(R13)
         XR     R15,R15
         BR     R14
         DS     0D
N        DC     H'8'
T        DC     H'2',H'4',H'4',H'4',H'5',H'5',H'7',H'9'
WW       DS     F
AVG      DS     F
P8       DS     PL8
MASK17   DC     C' ',13X'20',X'2120',C'-'
MASK18   DC     C' ',10X'20',X'2120',C'.',3X'20',C'-'
C17      DS     CL17
C18      DS     CL18
WTOMSG   DS     0F
         DC     H'80',XL2'0000'
BUF      DC     CL80'N=1  ITEM=1  AVG=1.234  STDDEV=1.234 '
         YREGS
         END    STDDEV


INCLUDE "H6:REALMATH.ACT"

REAL sum,sum2
INT count

PROC Calc(REAL POINTER x,sd)
  REAL tmp1,tmp2,tmp3

  RealAdd(sum,x,tmp1)       ;tmp1=sum+x
  RealAssign(tmp1,sum)      ;sum=sum+x
  RealMult(x,x,tmp1)        ;tmp1=x*x
  RealAdd(sum2,tmp1,tmp2)   ;tmp2=sum2+x*x
  RealAssign(tmp2,sum2)     ;sum2=sum2+x*x
  count==+1
  IF count=0 THEN
    IntToReal(0,sd)         ;sd=0
  ELSE
    IntToReal(count,tmp1)
    RealMult(sum,sum,tmp2)  ;tmp2=sum*sum
    RealDiv(tmp2,tmp1,tmp3) ;tmp3=sum*sum/count
    RealDiv(tmp3,tmp1,tmp2) ;tmp2=sum*sum/count/count
    RealDiv(sum2,tmp1,tmp3) ;tmp3=sum2/count
    RealSub(tmp3,tmp2,tmp1) ;tmp1=sum2/count-sum*sum/count/count
    Sqrt(tmp1,sd)           ;sd=sqrt(sum2/count-sum*sum/count/count)
  FI
RETURN

PROC Main()
  INT ARRAY values=[2 4 4 4 5 5 7 9]
  INT i
  REAL x,sd

  Put(125) PutE() ;clear screen
  MathInit()
  IntToReal(0,sum)
  IntToReal(0,sum2)
  count=0
  FOR i=0 TO 7
  DO
    IntToReal(values(i),x)
    Calc(x,sd)
    Print("x=") PrintR(x)
    Print(" sum=") PrintR(sum)
    Print(" sd=") PrintRE(sd)
  OD
RETURN


with Ada.Numerics.Elementary_Functions;  use Ada.Numerics.Elementary_Functions;
with Ada.Numerics.Elementary_Functions;  use Ada.Numerics.Elementary_Functions;
with Ada.Text_IO;                        use Ada.Text_IO;
with Ada.Float_Text_IO;                  use Ada.Float_Text_IO;
with Ada.Integer_Text_IO;                use Ada.Integer_Text_IO;

procedure Test_Deviation is
   type Sample is record
      N            : Natural := 0;
      Sum          : Float := 0.0;
      SumOfSquares : Float := 0.0;
   end record;
   procedure Add (Data : in out Sample; Point : Float) is
   begin
      Data.N       := Data.N + 1;
      Data.Sum    := Data.Sum    + Point;
      Data.SumOfSquares := Data.SumOfSquares + Point ** 2;
   end Add;
   function Deviation (Data : Sample) return Float is
   begin
      return Sqrt (Data.SumOfSquares / Float (Data.N) - (Data.Sum / Float (Data.N)) ** 2);
   end Deviation;

   Data : Sample;
   Test : array (1..8) of Integer := (2, 4, 4, 4, 5, 5, 7, 9);
begin
   for Index in Test'Range loop
      Add (Data, Float(Test(Index)));
      Put("N="); Put(Item => Index, Width => 1);
      Put(" ITEM="); Put(Item => Test(Index), Width => 1);
      Put(" AVG="); Put(Item => Float(Data.Sum)/Float(Index), Fore => 1, Aft => 3, Exp => 0);
      Put("  STDDEV="); Put(Item => Deviation (Data), Fore => 1, Aft => 3, Exp => 0);
      New_line;
   end loop;
end Test_Deviation;


&(J=x);                                                    {adjoin x as the variable in the polynomials}

Func Cyclotomic(n) =
    if n=1 then x-1 fi;                                    {first cyclotomic polynomial is x^n-1}
    r:=x^n-1;                                              {caclulate cyclotomic by division}
    for d = 1 to n-1 do
        if Divides(d,n) then
            r:=r\Cyclotomic(d)
        fi;
    od;
    r.;                                                    {return the polynomial}

Func Hascoef(n, k) =
    p:=Cyclotomic(n);
    for d = 0 to Deg(p) do
        if |(Coef(p,d))|=k then Return(1) fi
    od;
    0.;

for d = 1 to 30 do
    !!(d,' : ',Cyclotomic(d))
od;

for m = 1 to 10 do
    i:=1;
    while not Hascoef(i, m) do
        i:+
    od;
    !!(m,'   :   ',i);
od;


package main

import (
    "fmt"
    "log"
    "math"
    "sort"
    "strings"
)

const (
    algo          = 2
    maxAllFactors = 100000
)

func iabs(i int) int {
    if i < 0 {
        return -i
    }
    return i
}

type term struct{ coef, exp int }

func (t term) mul(t2 term) term {
    return term{t.coef * t2.coef, t.exp + t2.exp}
}

func (t term) add(t2 term) term {
    if t.exp != t2.exp {
        log.Fatal("exponents unequal in term.add method")
    }
    return term{t.coef + t2.coef, t.exp}
}

func (t term) negate() term { return term{-t.coef, t.exp} }

func (t term) String() string {
    switch {
    case t.coef == 0:
        return "0"
    case t.exp == 0:
        return fmt.Sprintf("%d", t.coef)
    case t.coef == 1:
        if t.exp == 1 {
            return "x"
        } else {
            return fmt.Sprintf("x^%d", t.exp)
        }
    case t.exp == 1:
        return fmt.Sprintf("%dx", t.coef)
    }
    return fmt.Sprintf("%dx^%d", t.coef, t.exp)
}

type poly struct{ terms []term }

// pass coef, exp in pairs as parameters
func newPoly(values ...int) poly {
    le := len(values)
    if le == 0 {
        return poly{[]term{term{0, 0}}}
    }
    if le%2 != 0 {
        log.Fatalf("odd number of parameters (%d) passed to newPoly function", le)
    }
    var terms []term
    for i := 0; i < le; i += 2 {
        terms = append(terms, term{values[i], values[i+1]})
    }
    p := poly{terms}.tidy()
    return p
}

func (p poly) hasCoefAbs(coef int) bool {
    for _, t := range p.terms {
        if iabs(t.coef) == coef {
            return true
        }
    }
    return false
}

func (p poly) add(p2 poly) poly {
    p3 := newPoly()
    le, le2 := len(p.terms), len(p2.terms)
    for le > 0 || le2 > 0 {
        if le == 0 {
            p3.terms = append(p3.terms, p2.terms[le2-1])
            le2--
        } else if le2 == 0 {
            p3.terms = append(p3.terms, p.terms[le-1])
            le--
        } else {
            t := p.terms[le-1]
            t2 := p2.terms[le2-1]
            if t.exp == t2.exp {
                t3 := t.add(t2)
                if t3.coef != 0 {
                    p3.terms = append(p3.terms, t3)
                }
                le--
                le2--
            } else if t.exp < t2.exp {
                p3.terms = append(p3.terms, t)
                le--
            } else {
                p3.terms = append(p3.terms, t2)
                le2--
            }
        }
    }
    return p3.tidy()
}

func (p poly) addTerm(t term) poly {
    q := newPoly()
    added := false
    for i := 0; i < len(p.terms); i++ {
        ct := p.terms[i]
        if ct.exp == t.exp {
            added = true
            if ct.coef+t.coef != 0 {
                q.terms = append(q.terms, ct.add(t))
            }
        } else {
            q.terms = append(q.terms, ct)
        }
    }
    if !added {
        q.terms = append(q.terms, t)
    }
    return q.tidy()
}

func (p poly) mulTerm(t term) poly {
    q := newPoly()
    for i := 0; i < len(p.terms); i++ {
        ct := p.terms[i]
        q.terms = append(q.terms, ct.mul(t))
    }
    return q.tidy()
}

func (p poly) div(v poly) poly {
    q := newPoly()
    lcv := v.leadingCoef()
    dv := v.degree()
    for p.degree() >= v.degree() {
        lcp := p.leadingCoef()
        s := lcp / lcv
        t := term{s, p.degree() - dv}
        q = q.addTerm(t)
        p = p.add(v.mulTerm(t.negate()))
    }
    return q.tidy()
}

func (p poly) leadingCoef() int {
    return p.terms[0].coef
}

func (p poly) degree() int {
    return p.terms[0].exp
}

func (p poly) String() string {
    var sb strings.Builder
    first := true
    for _, t := range p.terms {
        if first {
            sb.WriteString(t.String())
            first = false
        } else {
            sb.WriteString(" ")
            if t.coef > 0 {
                sb.WriteString("+ ")
                sb.WriteString(t.String())
            } else {
                sb.WriteString("- ")
                sb.WriteString(t.negate().String())
            }
        }
    }
    return sb.String()
}

// in place descending sort by term.exp
func (p poly) sortTerms() {
    sort.Slice(p.terms, func(i, j int) bool {
        return p.terms[i].exp > p.terms[j].exp
    })
}

// sort terms and remove any unnecesary zero terms
func (p poly) tidy() poly {
    p.sortTerms()
    if p.degree() == 0 {
        return p
    }
    for i := len(p.terms) - 1; i >= 0; i-- {
        if p.terms[i].coef == 0 {
            copy(p.terms[i:], p.terms[i+1:])
            p.terms[len(p.terms)-1] = term{0, 0}
            p.terms = p.terms[:len(p.terms)-1]
        }
    }
    if len(p.terms) == 0 {
        p.terms = append(p.terms, term{0, 0})
    }
    return p
}

func getDivisors(n int) []int {
    var divs []int
    sqrt := int(math.Sqrt(float64(n)))
    for i := 1; i <= sqrt; i++ {
        if n%i == 0 {
            divs = append(divs, i)
            d := n / i
            if d != i && d != n {
                divs = append(divs, d)
            }
        }
    }
    return divs
}

var (
    computed   = make(map[int]poly)
    allFactors = make(map[int]map[int]int)
)

func init() {
    f := map[int]int{2: 1}
    allFactors[2] = f
}

func getFactors(n int) map[int]int {
    if f, ok := allFactors[n]; ok {
        return f
    }
    factors := make(map[int]int)
    if n%2 == 0 {
        factorsDivTwo := getFactors(n / 2)
        for k, v := range factorsDivTwo {
            factors[k] = v
        }
        factors[2]++
        if n < maxAllFactors {
            allFactors[n] = factors
        }
        return factors
    }
    prime := true
    sqrt := int(math.Sqrt(float64(n)))
    for i := 3; i <= sqrt; i += 2 {
        if n%i == 0 {
            prime = false
            for k, v := range getFactors(n / i) {
                factors[k] = v
            }
            factors[i]++
            if n < maxAllFactors {
                allFactors[n] = factors
            }
            return factors
        }
    }
    if prime {
        factors[n] = 1
        if n < maxAllFactors {
            allFactors[n] = factors
        }
    }
    return factors
}

func cycloPoly(n int) poly {
    if p, ok := computed[n]; ok {
        return p
    }
    if n == 1 {
        // polynomial: x - 1
        p := newPoly(1, 1, -1, 0)
        computed[1] = p
        return p
    }
    factors := getFactors(n)
    cyclo := newPoly()
    if _, ok := factors[n]; ok {
        // n is prime
        for i := 0; i < n; i++ {
            cyclo.terms = append(cyclo.terms, term{1, i})
        }
    } else if len(factors) == 2 && factors[2] == 1 && factors[n/2] == 1 {
        // n == 2p
        prime := n / 2
        coef := -1
        for i := 0; i < prime; i++ {
            coef *= -1
            cyclo.terms = append(cyclo.terms, term{coef, i})
        }
    } else if len(factors) == 1 {
        if h, ok := factors[2]; ok {
            // n == 2^h
            cyclo.terms = append(cyclo.terms, term{1, 1 << (h - 1)}, term{1, 0})
        } else if _, ok := factors[n]; !ok {
            // n == p ^ k
            p := 0
            for prime := range factors {
                p = prime
            }
            k := factors[p]
            for i := 0; i < p; i++ {
                pk := int(math.Pow(float64(p), float64(k-1)))
                cyclo.terms = append(cyclo.terms, term{1, i * pk})
            }
        }
    } else if len(factors) == 2 && factors[2] != 0 {
        // n = 2^h * p^k
        p := 0
        for prime := range factors {
            if prime != 2 {
                p = prime
            }
        }
        coef := -1
        twoExp := 1 << (factors[2] - 1)
        k := factors[p]
        for i := 0; i < p; i++ {
            coef *= -1
            pk := int(math.Pow(float64(p), float64(k-1)))
            cyclo.terms = append(cyclo.terms, term{coef, i * twoExp * pk})
        }
    } else if factors[2] != 0 && ((n/2)%2 == 1) && (n/2) > 1 {
        //  CP(2m)[x] == CP(-m)[x], n odd integer > 1
        cycloDiv2 := cycloPoly(n / 2)
        for _, t := range cycloDiv2.terms {
            t2 := t
            if t.exp%2 != 0 {
                t2 = t.negate()
            }
            cyclo.terms = append(cyclo.terms, t2)
        }
    } else if algo == 0 {
        // slow - uses basic definition
        divs := getDivisors(n)
        // polynomial: x^n - 1
        cyclo = newPoly(1, n, -1, 0)
        for _, i := range divs {
            p := cycloPoly(i)
            cyclo = cyclo.div(p)
        }
    } else if algo == 1 {
        //  faster - remove max divisor (and all divisors of max divisor)
        //  only one divide for all divisors of max divisor
        divs := getDivisors(n)
        maxDiv := math.MinInt32
        for _, d := range divs {
            if d > maxDiv {
                maxDiv = d
            }
        }
        var divsExceptMax []int
        for _, d := range divs {
            if maxDiv%d != 0 {
                divsExceptMax = append(divsExceptMax, d)
            }
        }
        // polynomial:  ( x^n - 1 ) / ( x^m - 1 ), where m is the max divisor
        cyclo = newPoly(1, n, -1, 0)
        cyclo = cyclo.div(newPoly(1, maxDiv, -1, 0))
        for _, i := range divsExceptMax {
            p := cycloPoly(i)
            cyclo = cyclo.div(p)
        }
    } else if algo == 2 {
        //  fastest
        //  let p, q be primes such that p does not divide n, and q divides n
        //  then CP(np)[x] = CP(n)[x^p] / CP(n)[x]
        m := 1
        cyclo = cycloPoly(m)
        var primes []int
        for prime := range factors {
            primes = append(primes, prime)
        }
        sort.Ints(primes)
        for _, prime := range primes {
            //  CP(m)[x]
            cycloM := cyclo
            //  compute CP(m)[x^p]
            var terms []term
            for _, t := range cycloM.terms {
                terms = append(terms, term{t.coef, t.exp * prime})
            }
            cyclo = newPoly()
            cyclo.terms = append(cyclo.terms, terms...)
            cyclo = cyclo.tidy()
            cyclo = cyclo.div(cycloM)
            m *= prime
        }
        //  now, m is the largest square free divisor of n
        s := n / m
        //  Compute CP(n)[x] = CP(m)[x^s]
        var terms []term
        for _, t := range cyclo.terms {
            terms = append(terms, term{t.coef, t.exp * s})
        }
        cyclo = newPoly()
        cyclo.terms = append(cyclo.terms, terms...)
    } else {
        log.Fatal("invalid algorithm")
    }
    cyclo = cyclo.tidy()
    computed[n] = cyclo
    return cyclo
}

func main() {
    fmt.Println("Task 1:  cyclotomic polynomials for n <= 30:")
    for i := 1; i <= 30; i++ {
        p := cycloPoly(i)
        fmt.Printf("CP[%2d] = %s\n", i, p)
    }

    fmt.Println("\nTask 2:  Smallest cyclotomic polynomial with n or -n as a coefficient:")
    n := 0
    for i := 1; i <= 10; i++ {
        for {
            n++
            cyclo := cycloPoly(n)
            if cyclo.hasCoefAbs(i) {
                fmt.Printf("CP[%d] has coefficient with magnitude = %d\n", n, i)
                n--
                break
            }
        }
    }
}


(() => {
    'use strict';

    // cusipValid = Dict Char Int -> String -> Bool
    const cusipValid = charMap => s => {
        const
            ns = fromMaybe([])(
                traverse(flip(lookupDict)(charMap))(
                    chars(s)
                )
            );
        return 9 === ns.length && (
            last(ns) === rem(
                10 - rem(
                    sum(apList(
                        apList([quot, rem])(
                            zipWith(identity)(
                                cycle([identity, x => 2 * x])
                            )(take(8)(ns))
                        )
                    )([10]))
                )(10)
            )(10)
        );
    };

    //----------------------- TEST ------------------------
    // main :: IO ()
    const main = () => {

        // cusipMap :: Dict Char Int
        const cusipMap = dictFromList(
            zip(chars(
                "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*@#"
            ))(enumFrom(0)));

        console.log(unlines(map(
            apFn(
                s => validity => s + ' -> ' + str(validity)
            )(cusipValid(cusipMap))
        )([
            '037833100',
            '17275R102',
            '38259P508',
            '594918104',
            '68389X106',
            '68389X105'
        ])));
    };

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

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

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

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

    // apFn :: (a -> b -> c) -> (a -> b) -> a -> c
    const apFn = f =>
        // Applicative instance for functions.
        // f(x) applied to g(x).
        g => x => f(x)(
            g(x)
        );

    // apList (<*>) :: [(a -> b)] -> [a] -> [b]
    const apList = fs =>
        // The sequential application of each of a list
        // of functions to each of a list of values.
        xs => fs.flatMap(
            f => xs.map(f)
        );

    // append (++) :: [a] -> [a] -> [a]
    // append (++) :: String -> String -> String
    const append = xs =>
        // A list or string composed by
        // the concatenation of two others.
        ys => xs.concat(ys);

    // chars :: String -> [Char]
    const chars = s =>
        s.split('');

    // cons :: a -> [a] -> [a]
    const cons = x =>
        xs => Array.isArray(xs) ? (
            [x].concat(xs)
        ) : 'GeneratorFunction' !== xs
        .constructor.constructor.name ? (
            x + xs
        ) : ( // cons(x)(Generator)
            function*() {
                yield x;
                let nxt = xs.next()
                while (!nxt.done) {
                    yield nxt.value;
                    nxt = xs.next();
                }
            }
        )();

    // cycle :: [a] -> Generator [a]
    function* cycle(xs) {
        const lng = xs.length;
        let i = 0;
        while (true) {
            yield(xs[i])
            i = (1 + i) % lng;
        }
    }

    // dictFromList :: [(k, v)] -> Dict
    const dictFromList = kvs =>
        Object.fromEntries(kvs);

    // enumFrom :: Enum a => a -> [a]
    function* enumFrom(x) {
        // A non-finite succession of enumerable
        // values, starting with the value x.
        let v = x;
        while (true) {
            yield v;
            v = succ(v);
        }
    }

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = f =>
        1 < f.length ? (
            (a, b) => f(b, a)
        ) : (x => y => f(y)(x));

    // fromEnum :: Enum a => a -> Int
    const fromEnum = x =>
        typeof x !== 'string' ? (
            x.constructor === Object ? (
                x.value
            ) : parseInt(Number(x))
        ) : x.codePointAt(0);

    // fromMaybe :: a -> Maybe a -> a
    const fromMaybe = def =>
        // A default value if mb is Nothing
        // or the contents of mb.
        mb => mb.Nothing ? def : mb.Just;

    // fst :: (a, b) -> a
    const fst = tpl =>
        // First member of a pair.
        tpl[0];

    // identity :: a -> a
    const identity = x =>
        // The identity function. (`id`, in Haskell)
        x;

    // last :: [a] -> a
    const last = xs =>
        // The last item of a list.
        0 < xs.length ? xs.slice(-1)[0] : undefined;

    // 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
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // liftA2 :: (a -> b -> c) -> Maybe a -> Maybe b -> Maybe c
    const liftA2 = f => a => b =>
        a.Nothing ? a : b.Nothing ? b : Just(f(a.Just)(b.Just));

    // lookupDict :: a -> Dict -> Maybe b
    const lookupDict = k => dct => {
        const v = dct[k];
        return undefined !== v ? (
            Just(v)
        ) : Nothing();
    };

    // map :: (a -> b) -> [a] -> [b]
    const map = f =>
        // The list obtained by applying f
        // to each element of xs.
        // (The image of xs under f).
        xs => (
            Array.isArray(xs) ? (
                xs
            ) : xs.split('')
        ).map(f);

    // pureMay :: a -> Maybe a
    const pureMay = x => Just(x);

    // Given a type name string, returns a
    // specialised 'pure', where
    // 'pure' lifts a value into a particular functor.

    // pureT :: String -> f a -> (a -> f a)
    const pureT = t => x =>
        'List' !== t ? (
            'Either' === t ? (
                pureLR(x)
            ) : 'Maybe' === t ? (
                pureMay(x)
            ) : 'Node' === t ? (
                pureTree(x)
            ) : 'Tuple' === t ? (
                pureTuple(x)
            ) : pureList(x)
        ) : pureList(x);

    // pureTuple :: a -> (a, a)
    const pureTuple = x =>
        Tuple('')(x);

    // quot :: Int -> Int -> Int
    const quot = n =>
        m => Math.floor(n / m);

    // rem :: Int -> Int -> Int
    const rem = n => m => n % m;

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

    // str :: a -> String
    const str = x =>
        x.toString();

    // succ :: Enum a => a -> a
    const succ = x => {
        const t = typeof x;
        return 'number' !== t ? (() => {
            const [i, mx] = [x, maxBound(x)].map(fromEnum);
            return i < mx ? (
                toEnum(x)(1 + i)
            ) : Error('succ :: enum out of range.')
        })() : x < Number.MAX_SAFE_INTEGER ? (
            1 + x
        ) : Error('succ :: Num out of range.')
    };

    // sum :: [Num] -> Num
    const sum = xs =>
        // The numeric sum of all values in xs.
        xs.reduce((a, x) => a + x, 0);

    // 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];
        }));

    // The first argument is a sample of the type
    // allowing the function to make the right mapping

    // toEnum :: a -> Int -> a
    const toEnum = e => x =>
        ({
            'number': Number,
            'string': String.fromCodePoint,
            'boolean': Boolean,
            'object': v => e.min + v
        } [typeof e])(x);

    // traverse :: (Applicative f) => (a -> f b) -> [a] -> f [b]
    const traverse = f =>
        // Collected results of mapping each element
        // of a structure to an action, and evaluating
        // these actions from left to right.
        xs => 0 < xs.length ? (() => {
            const
                vLast = f(xs.slice(-1)[0]),
                t = vLast.type || 'List';
            return xs.slice(0, -1).reduceRight(
                (ys, x) => liftA2(cons)(f(x))(ys),
                liftA2(cons)(vLast)(pureT(t)([]))
            );
        })() : [
            []
        ];

    // uncons :: [a] -> Maybe (a, [a])
    const uncons = xs => {
        // Just a tuple of the head of xs and its tail,
        // Or Nothing if xs is an empty list.
        const lng = length(xs);
        return (0 < lng) ? (
            Infinity > lng ? (
                Just(Tuple(xs[0])(xs.slice(1))) // Finite list
            ) : (() => {
                const nxt = take(1)(xs);
                return 0 < nxt.length ? (
                    Just(Tuple(nxt[0])(xs))
                ) : Nothing();
            })() // Lazy generator
        ) : Nothing();
    };

    // uncurry :: (a -> b -> c) -> ((a, b) -> c)
    const uncurry = f =>
        // A function over a pair, derived
        // from a curried function.
        x => ((...args) => {
            const
                xy = 1 < args.length ? (
                    args
                ) : args[0];
            return f(xy[0])(xy[1]);
        })(x);

    // unlines :: [String] -> String
    const unlines = xs =>
        // A single string formed by the intercalation
        // of a list of strings with the newline character.
        xs.join('\n');

    // zip :: [a] -> [b] -> [(a, b)]
    const zip = xs =>
        // Use of `take` and `length` here allows for zipping with non-finite
        // lists - i.e. generators like cycle, repeat, iterate.
        ys => {
            const
                lng = Math.min(length(xs), length(ys)),
                vs = take(lng)(ys);
            return take(lng)(xs).map(
                (x, i) => Tuple(x)(vs[i])
            );
        };

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

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f => xs => ys => {
        const lng = Math.min(length(xs), length(ys));
        return Infinity > lng ? (() => {
            const
                as = take(lng)(xs),
                bs = take(lng)(ys);
            return Array.from({
                length: lng
            }, (_, i) => f(as[i])(
                bs[i]
            ));
        })() : zipWithGen(f)(xs)(ys);
    };

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

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


public class CubanPrimes {

    private static int MAX = 1_400_000;
    private static boolean[] primes = new boolean[MAX];

    public static void main(String[] args) {
        preCompute();
        cubanPrime(200, true);
        for ( int i = 1 ; i <= 5 ; i++ ) {
            int max = (int) Math.pow(10, i);
            System.out.printf("%,d-th cuban prime = %,d%n", max, cubanPrime(max, false));
        }
    }

    private static long cubanPrime(int n, boolean display) {
        int count = 0;
        long result = 0;
        for ( long i = 0 ; count < n ; i++ ) {
            long test = 1l + 3 * i * (i+1);
            if ( isPrime(test) ) {
                count++;
                result = test;
                if ( display ) {
                    System.out.printf("%10s%s", String.format("%,d", test), count % 10 == 0 ? "\n" : "");
                }
            }
        }
        return result;
    }

    private static boolean isPrime(long n) {
        if ( n < MAX ) {
            return primes[(int)n];
        }
        int max = (int) Math.sqrt(n);
        for ( int i = 3 ; i <= max ; i++ ) {
            if ( primes[i] && n % i == 0 ) {
                return false;
            }
        }
        return true;
    }

    private static final void preCompute() {
        //  primes
        for ( int i = 2 ; i < MAX ; i++ ) {
            primes[i] = true;
        }
        for ( int i = 2 ; i < MAX ; i++ ) {
            if ( primes[i] ) {
                for ( int j = 2*i ; j < MAX ; j += i ) {
                    primes[j] = false;
                }
            }
        }
    }
}


MODE VALUE = STRUCT(CHAR value),
     STDDEV = STRUCT(CHAR stddev),
     MEAN = STRUCT(CHAR mean),
     VAR = STRUCT(CHAR var),
     COUNT = STRUCT(CHAR count),
     RESET = STRUCT(CHAR reset);

MODE ACTION = UNION ( VALUE, STDDEV, MEAN, VAR, COUNT, RESET );

LONG REAL sum := 0;
LONG REAL sum2 := 0;
INT num := 0;

PROC stat object = (LONG REAL v, ACTION action)LONG REAL:
(

  LONG REAL m;

  CASE action IN
  (VALUE):(
    num +:= 1;
    sum +:= v;
    sum2 +:= v*v;
    stat object(0, LOC STDDEV)
  ),
  (STDDEV):
    long sqrt(stat object(0, LOC VAR)),
  (MEAN):
    IF num>0 THEN sum/LONG REAL(num) ELSE 0 FI,
  (VAR):(
    m := stat object(0, LOC MEAN);
    IF num>0 THEN sum2/LONG REAL(num)-m*m ELSE 0 FI
  ),
  (COUNT):
    num,
  (RESET):
    sum := sum2 := num := 0
  ESAC
);

[]LONG REAL v = ( 2,4,4,4,5,5,7,9 );

main:
(
  LONG REAL sd;

  FOR i FROM LWB v TO UPB v DO
    sd := stat object(v[i], LOC VALUE);
    printf(($"value: "g(0,6)," standard dev := "g(0,6)l$, v[i], sd))
  OD

)


import Data.List
import Data.Numbers.Primes (primeFactors)

negateVar p = zipWith (*) p $ reverse $ take (length p) $ cycle [1,-1]

lift p 1 = p
lift p n = intercalate (replicate (n-1) 0) (pure <$> p)

shortDiv :: [Integer] -> [Integer] -> [Integer]
shortDiv p1 (_:p2) = unfoldr go (length p1 - length p2, p1)
  where
    go (0, _) = Nothing
    go (i, h:t) = Just (h, (i-1, zipWith (+) (map (h *) ker) t))
    ker = negate <$> p2 ++ repeat 0

primePowerFactors = sortOn fst . map (\x-> (head x, length x)) . group . primeFactors

-- simple memoization
cyclotomics :: [[Integer]]
cyclotomics = cyclotomic <$> [0..]

cyclotomic :: Int -> [Integer]
cyclotomic 0 = [0]
cyclotomic 1 = [1, -1]
cyclotomic 2 = [1, 1]
cyclotomic n = case primePowerFactors n of
  -- for n = 2^k
  [(2,h)]       -> 1 : replicate (2 ^ (h-1) - 1) 0 ++ [1]
  -- for prime n
  [(p,1)]       -> replicate n 1
  -- for power of prime n
  [(p,m)]       -> lift (cyclotomics !! p) (p^(m-1))
  -- for n = 2*p and prime p
  [(2,1),(p,1)] -> take (n `div` 2) $ cycle [1,-1]
  -- for n = 2*m and odd m
  (2,1):_       -> negateVar $ cyclotomics !! (n `div` 2)
  -- general case
  (p, m):ps     -> let cm = cyclotomics !! (n `div` (p ^ m))
                   in lift (lift cm p `shortDiv` cm) (p^(m-1))


module CUSIP

function _lastdigitcusip(input::AbstractString)
    input = uppercase(input)
    s = 0

    for (i, c) in enumerate(input)
        if isdigit(c)
            v = Int(c) - 48
        elseif isalpha(c)
            v = Int(c) - 64 + 9
        elseif c == '*'
            v = 36
        elseif c == '@'
            v = 37
        elseif c == '#'
            v = 38
        end

        if iseven(i); v *= 2 end
        s += div(v, 10) + rem(v, 10)
    end

    return Char(rem(10 - rem(s, 10), 10) + 48)
end

checkdigit(input::AbstractString) = input[9] == _lastdigitcusip(input[1:8])

end  # module CUSIP

for code in ("037833100", "17275R102", "38259P508", "594918104", "68389X106", "68389X105")
    println("$code is ", CUSIP.checkdigit(code) ? "correct." : "not correct.")
end


// version 1.1.0

fun isCusip(s: String): Boolean {
    if (s.length != 9) return false
    var sum = 0
    for (i in 0..7) {
        val c = s[i]
        var v = when (c) {
            in '0'..'9'  -> c.toInt() - 48
            in 'A'..'Z'  -> c.toInt() - 55  // lower case letters apparently invalid
            '*'          -> 36
            '@'          -> 37
            '#'          -> 38
            else         -> return false
        }
        if (i % 2 == 1) v *= 2  // check if odd as using 0-based indexing
        sum += v / 10 + v % 10
    }
    return s[8].toInt() - 48  == (10 - (sum % 10)) % 10
}

fun main(args: Array<String>) {
    val candidates = listOf(
        "037833100",
        "17275R102",
        "38259P508",
        "594918104",
        "68389X106",
        "68389X105"
    )
    for (candidate in candidates)
        println("$candidate -> ${if(isCusip(candidate)) "correct" else "incorrect"}")
}


# input should be a non-negative integer
def commatize:
  def digits: tostring | explode | reverse;
  [foreach digits[] as $d (-1; .+1;
     (select(. > 0 and . % 3 == 0)|44), $d)]     # "," is 44
  | reverse | implode  ;

def count(stream): reduce stream as $i (0; .+1);

def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

def nwise($n):
  def n: if length <= $n then . else .[0:$n] , (.[$n:] | n) end;
  n;


using Primes

function cubanprimes(N)
    cubans = zeros(Int, N)
    cube100k, cube1, count = 0, 1, 1
    for i in Iterators.countfrom(1)
        j = BigInt(i + 1)
        cube2 = j^3
        diff = cube2 - cube1
        if isprime(diff)
            count ≤ N && (cubans[count] = diff)
            if count == 100000
                cube100k = diff
                break
            end
            count += 1
        end
        cube1 = cube2
    end
    println("The first $N cuban primes are: ")
    foreach(x -> print(lpad(cubans[x] == 0 ? "" : cubans[x], 10), x % 8 == 0 ? "\n" : ""), 1:N)
    println("\nThe 100,000th cuban prime is ", cube100k)
end

cubanprimes(200)


import kotlin.math.ceil
import kotlin.math.sqrt

fun main() {
    val primes = mutableListOf(3L, 5L)
    val cutOff = 200
    val bigUn = 100_000
    val chunks = 50
    val little = bigUn / chunks

    println("The first $cutOff cuban primes:")
    var showEach = true
    var c = 0
    var u = 0L
    var v = 1L
    var i = 1L
    while (i > 0) {
        var found = false
        u += 6
        v += u
        val mx = ceil(sqrt(v.toDouble())).toInt()
        for (item in primes) {
            if (item > mx) break
            if (v % item == 0L) {
                found = true
                break
            }
        }
        if (!found) {
            c++
            if (showEach) {
                var z = primes.last() + 2
                while (z <= v - 2) {
                    var fnd = false
                    for (item in primes) {
                        if (item > mx) break
                        if (z % item == 0L) {
                            fnd = true
                            break
                        }
                    }
                    if (!fnd) {
                        primes.add(z)
                    }
                    z += 2
                }
                primes.add(v)
                print("%11d".format(v))
                if (c % 10 == 0) println()
                if (c == cutOff) {
                    showEach = false
                    print("\nProgress to the ${bigUn}th cuban prime: ")
                }
            }
            if (c % little == 0) {
                print(".")
                if (c == bigUn) break
            }
        }
        i++
    }
    println("\nThe %dth cuban prime is %17d".format(c, v))
}


.model small                             ;specify memory model to use
.stack 1024                              ;set up stack

.data                                    ;data segment

UserRam BYTE 256 DUP (0)                 ;allocate 256 bytes of user RAM, initialized to zero.

tempByte equ UserRam                     ;define a few labels for clarity
tempWord equ UserRam+2
tempLong_LoWord equ UserRam+4
tempLong_HiWord equ UserRam+6

.code                                    ;code segment

mov ax, @data
mov ds, ax

mov ax, @code
mov es, ax                               ;load segment registers with the appropriate segments.

; now there is no need to use "mov ax, seg UserRam" since we've already loaded the data segment into DS

;store an integer value into memory

mov ax, 1000h                            ;load the value 0x1000 into AX
mov word ptr [ds:tempLong_LoWord],ax     ;store 0x1000 into tempLong_LoWord
mov ax, 0040h                            ;the 8086 is 16-bit so we have to load the pieces separately.
mov word ptr [ds:tempLong_HiWord],ax     ;store 0x0040 into tempLong_HiWord

;get the address of a variable
mov ax, tempLong_LoWord                  ;without "word ptr" and brackets, the assembler interprets a label as a constant.


DEFINE FIRST="12345"
DEFINE SECOND="54321"
DEFINE PTR="CARD"

PROC Main()
  PTR base,copy=base

  PrintF("Address of base variable: %H%E",@base)
  PrintF("Address of copy variable: %H%E",@copy)
  PutE()

  PrintF("Assign %U value to base variable%E",FIRST)
  base=FIRST
  PrintF("Value of base variable: %U%E",base)
  PrintF("Value of copy variable: %U%E",copy)
  PutE()

  PrintF("Assign %U value to base variable%E",SECOND)
  base=SECOND
  PrintF("Value of base variable: %U%E",base)
  PrintF("Value of copy variable: %U%E",copy)
RETURN


type IO_Port is mod 2**8; -- One byte
Device_Port : type IO_Port;
for Device_Port'Address use 16#FFFF_F000#;


var portaddr = 0x80
var v = peek (portaddr, 1)   // 1 byte
v |= 0x40
poke (portaddr, v, 1) // 1 byte back again

var addr = malloc (16)
poke (addr, 1234, 4)
poke (addr+4, 0, 2)
poke (addr+6, 12, 2)


 0  DEF  FN P(A) =  PEEK (A) +  PEEK (A + 1) * 256
 100 :
 110  REM CREATE AN INTEGER OBJECT
 120 :
 130 I$ =  CHR$ (42)
 140  POKE 236, PEEK (131)
 150  POKE 237, PEEK (132)
 160  PRINT "HERE IS AN INTEGER    : " ASC (I$)
 200 :
 210  REM PRINT THE MACHINE ADDRESS OF THE OBJECT
 220 :
 230  PRINT "ITS ADDRESS IS        : " FN P( FN P(236) + 1)
 300 :
 310  REM TAKE THE ADDRESS OF THE OBJECT AND CREATE ANOTHER INTEGER OBJECT AT THIS ADDRESS
 320 :
 330 O$ =  CHR$ (0)
 340  POKE 250, PEEK (131)
 350  POKE 251, PEEK (132)
 360  POKE  FN P(250) + 1, PEEK ( FN P(236) + 1)
 370  POKE  FN P(250) + 2, PEEK ( FN P(236) + 2)
 400 :
 410  REM PRINT THE VALUE OF THIS OBJECT TO VERIFY THAT IT IS SAME AS ONE OF THE ORIGIN
 420 :
 430  PRINT "COMPARE OTHER INTEGER : " ASC (O$)
 500 :
 510  REM CHANGE THE VALUE OF THE ORIGIN AND VERIFY IT AGAIN
 520 :
 530  POKE  FN P( FN P(236) + 1),69
 540  PRINT "NEW INTEGER VALUE     : " ASC (I$)
 550  PRINT "COMPARE OTHER INTEGER : " ASC (O$)


begin

    long real sum, sum2;
    integer   n;

    long real procedure sd (long real value x) ;
    begin
        sum  := sum  + x;
        sum2 := sum2 + (x*x);
        n    := n    + 1;
        if n = 0 then 0 else longsqrt(sum2/n - sum*sum/n/n)
    end sd;

    sum := sum2 := n := 0;

    r_format := "A"; r_w := 14; r_d := 6; % set output to fixed point format %

    for i := 2,4,4,4,5,5,7,9
    do begin
        long real val;
        val := i;
        write(val, sd(val))
    end for_i

end.


-------------- CUMULATIVE STANDARD DEVIATION -------------

-- stdDevInc :: Accumulator -> Num -> Index -> Accumulator
-- stdDevInc :: {sum:, squaresSum:, stages:} -> Real -> Integer
--                -> {sum:, squaresSum:, stages:}
on stdDevInc(a, n, i)
    set sum to (sum of a) + n
    set squaresSum to (squaresSum of a) + (n ^ 2)
    set stages to (stages of a) & ¬
        ((squaresSum / i) - ((sum / i) ^ 2)) ^ 0.5

    {sum:(sum of a) + n, squaresSum:squaresSum, stages:stages}
end stdDevInc

--------------------------- TEST -------------------------
on run
    set xs to [2, 4, 4, 4, 5, 5, 7, 9]

    stages of foldl(stdDevInc, ¬
        {sum:0, squaresSum:0, stages:[]}, xs)

    --> {0.0, 1.0, 0.942809041582, 0.866025403784, 0.979795897113, 1.0, 1.399708424448, 2.0}
end run

-------------------- GENERIC FUNCTIONS -------------------

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

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


val .isCusip = f(.s) {
    if not isString(.s) or len(.s) != 9 {
        return false
    }

    val .basechars = cp2s('0'..'9') ~ cp2s('A'..'Z') ~ "*@#"

    val .sum = for[=0] .i of 8 {
        var .v = index(s2s(.s, .i), .basechars)
        if not .v: return false
        .v = .v[1]-1
        if .i div 2: .v x= 2
        _for += .v \ 10 + .v rem 10
    }

    .s[9]-'0' == (10-(.sum rem 10)) rem 10
}

val .candidates = w/037833100 17275R102 38259P508 594918104 68389X106 68389X105/

for .c in .candidates {
    writeln .c, ": ", if(.isCusip(.c): "good" ; "bad")
}


function checkDigit (cusip)
  if #cusip ~= 8 then return false end

  local sum, c, v, p = 0
  for i = 1, 8 do
    c = cusip:sub(i, i)
    if c:match("%d") then
      v = tonumber(c)
    elseif c:match("%a") then
      p = string.byte(c) - 55
      v = p + 9
    elseif c == "*" then
      v = 36
    elseif c == "@" then
      v = 37
    elseif c == "#" then
      v = 38
    end
    if i % 2 == 0 then
      v = v * 2
    end

    sum = sum + math.floor(v / 10) + v % 10
  end

  return tostring((10 - (sum % 10)) % 10)
end

local testCases = {
  "037833100",
  "17275R102",
  "38259P508",
  "594918104",
  "68389X106",
  "68389X105"
}
for _, CUSIP in pairs(testCases) do
  io.write(CUSIP .. ": ")
  if checkDigit(CUSIP:sub(1, 8)) == CUSIP:sub(9, 9) then
    print("VALID")
  else
    print("INVALID")
  end
end


local primes = {3, 5}
local cutOff = 200
local bigUn = 100000
local chunks = 50
local little = math.floor(bigUn / chunks)
local tn = " cuban prime"
print(string.format("The first %d%ss", cutOff, tn))
local showEach = true
local c = 0
local u = 0
local v = 1
for i=1,10000000000000 do
    local found = false
    u = u + 6
    v = v + u
    local mx = math.ceil(math.sqrt(v))
    --for _,item in pairs(primes) do -- why: latent traversal bugfix (and performance), 6/11/2020 db
    for _,item in ipairs(primes) do
        if item > mx then
            break
        end
        if v % item == 0 then
            --print("[DEBUG] :( i = " .. i .. "; v = " .. v)
            found = true
            break
        end
    end
    if not found then
        --print("[DEBUG] :) i = " .. i .. "; v = " .. v)
        c = c + 1
        if showEach then
            --local z = primes[table.getn(primes)] + 2 -- why: modernize (deprecated), 6/11/2020 db
            local z = primes[#primes] + 2
            while z <= v - 2 do
                local fnd = false
                --for _,item in pairs(primes) do -- why: latent traversal bugfix (and performance), 6/11/2020 db
                for _,item in ipairs(primes) do
                    if item > mx then
                        break
                    end
                    if z % item == 0 then
                        fnd = true
                        break
                    end
                end
                if not fnd then
                    table.insert(primes, z)
                end
                z = z + 2
            end
            table.insert(primes, v)
            io.write(string.format("%11d", v))
            if c % 10 == 0 then
                print()
            end
            if c == cutOff then
                showEach = false
                io.write(string.format("\nProgress to the %dth%s: ", bigUn, tn))
            end
        end
        if c % little == 0 then
            io.write(".")
            if c == bigUn then
                break
            end
        end
    end
end
--print(string.format("\nThe %dth%s is %17d", c, tn, v)) -- why: correcting reported inaccuracy in output, 6/11/2020 db
print(string.format("\nThe %dth%s is %.0f", c, tn, v))


CubanPrimes := proc(n) local i, cp;
               cp := Array([]);
               for i by 2 while numelems(cp) < n do
                   if isprime(3/4*i^2 + 1/4) then
                      ArrayTools:-Append(cp, 3/4*i^2 + 1/4);
                   end if;
               end do;
               return cp;
               end proc;


mov r0,#0x00100000
ldr r1,testData
str r1,[r0]   ;store 0x12345678 at address $100000
bx lr         ;return from subroutine

testData:
     .long 0x12345678    ;VASM uses .long for 32 bit and .word for 16 bit values, unlike most ARM assemblers.


; Create a variable with 4 bytes size and show it's machine address.
VarSetCapacity(var, 4, 0)
pAddress := &var
MsgBox Machine address: %pAddress%

; pAddress contains the memory address.
; Write a number and read it back.
NumPut(123456, pAddress+0, 0, "UInt")
MsgBox % "Contents of *pAddress: " . NumGet(pAddress+0, 0, "UInt")


      REM Create an integer object:
      anInteger% = 12345678
      PRINT "Original value =", anInteger%

      REM Print the machine address of the object:
      address% = ^anInteger%
      PRINT "Hexadecimal address =   ";~address%

      REM Take the address of the object and create
      REM another integer object at this address:
      !address% = 87654321

      REM Print the value of this object to verify
      REM that it is same as one of the origin:
      PRINT "New value =", anInteger%

      REM Change the value and verify it again:
      anInteger% = 55555555
      PRINT "Final value =", !address%


#include <stdio.h>

int main()
{
  int intspace;
  int *address;

  address = &intspace; // address = 0x100;
  *address = 65535;
  printf("%p: %08x (=%08x)\n", address, *address, intspace);
  // likely we must be worried about endianness, e.g.
  *((char*)address) = 0x00;
  *((char*)address+1) = 0x00;
  *((char*)address+2) = 0xff;
  *((char*)address+3) = 0xff; // if sizeof(int) == 4!
  // which maybe is not the best way of writing 32 bit values...
  printf("%p: %08x (=%08x)\n", address, *address, intspace);
  return 0;
}


#include <string>
#include <iostream>

int main()
{
    // Allocate enough memory to hold an instance of std::string
    char* data = new char[sizeof(std::string)];

    // use placement new to construct a std::string in the memory we allocated previously
    std::string* stringPtr = new (data) std::string("ABCD");

    std::cout << *stringPtr << " 0x" << stringPtr << std::endl;

    // use placement new to construct a new string object in the same memory location
    // remember to manually call destructor
    stringPtr->~basic_string();
    stringPtr = new (data) std::string("123456");

    std::cout << *stringPtr << " 0x" << stringPtr << std::endl;

    // clean up
    stringPtr->~basic_string();
    delete[] data;
}


arr: new []
loop [2 4 4 4 5 5 7 9] 'value [
    'arr ++ value
    print [value "->" deviation arr]
]


Data := [2,4,4,4,5,5,7,9]

for k, v in Data {
    FileAppend, % "#" a_index " value = " v " stddev = " stddev(v) "`n", * ; send to stdout
}
return

stddev(x) {
	static n, sum, sum2
	n++
	sum += x
	sum2 += x*x

	return sqrt((sum2/n) - (((sum*sum)/n)/n))
}


# syntax: GAWK -f STANDARD_DEVIATION.AWK
BEGIN {
    n = split("2,4,4,4,5,5,7,9",arr,",")
    for (i=1; i<=n; i++) {
      temp[i] = arr[i]
      printf("%g %g\n",arr[i],stdev(temp))
    }
    exit(0)
}
function stdev(arr,  i,n,s1,s2,variance,x) {
    for (i in arr) {
      n++
      x = arr[i]
      s1 += x ^ 2
      s2 += x
    }
    variance = ((n * s1) - (s2 ^ 2)) / (n ^ 2)
    return(sqrt(variance))
}