Population count

The   ''population count''   is the number of   '''1'''s   (ones)   in the binary representation of a non-negative integer.

''Population count''   is also known as:
::::*   ''pop count''
::::*   ''popcount''
::::*   ''sideways sum''
::::*   ''bit summation''
::::*   ''Hamming weight''

For example,   '''5'''   (which is   '''101'''   in binary)   has a population count of   '''2'''.

''Evil numbers''   are non-negative integers  that have an   ''even''   population count.

''Odious numbers''      are  positive integers that have an    ''odd''   population count.

;Task:
* write a function (or routine) to return the population count of a non-negative integer.
* all computation of the lists below should start with   '''0'''   (zero indexed).
:* display the   ''pop count''   of the   1st   thirty powers of   '''3'''       ('''30''',   '''31''',   '''32''',   '''33''',   '''34''',      '''329''').
:* display the   1st   thirty     ''evil''        numbers.
:* display the   1st   thirty          ''odious''           numbers.
* display each list of integers on one line   (which may or may not include a title),   each set of integers being shown should be properly identified.

;See also
* The On-Line Encyclopedia of Integer Sequences:   A000120 population count.
* The On-Line Encyclopedia of Integer Sequences:   A000069 odious numbers.
* The On-Line Encyclopedia of Integer Sequences:   A001969 evil numbers.

Solution:
(() => {
    'use strict';

    // populationCount :: Int -> Int
    const populationCount = n =>
        // The number of non-zero bits in the binary
        // representation of the integer n.
        sum(unfoldr(
            x => 0 < x ? (
                Just(Tuple(x % 2)(Math.floor(x / 2)))
            ) : Nothing()
        )(n));

    // ----------------------- TEST ------------------------
    // main :: IO ()
    const main = () => {
        const [evens, odds] = Array.from(
            partition(compose(even, populationCount))(
                enumFromTo(0)(59)
            )
        );
        return [
            'Population counts of the first 30 powers of three:',
            `    [${enumFromTo(0)(29).map(
                    compose(populationCount, raise(3))
                 ).join(',')}]`,
            "\nFirst thirty 'evil' numbers:",
            `    [${[evens.join(',')]}]`,
            "\nFirst thirty 'odious' numbers:",
            `    [${odds.join(',')}]`
        ].join('\n');
    };

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

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        // A function defined by the right-to-left
        // composition of all the functions in fs.
        fs.reduce(
            (f, g) => x => f(g(x)),
            x => x
        );

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => !isNaN(m) ? (
            Array.from({
                length: 1 + n - m
            }, (_, i) => m + i)
        ) : enumFromTo_(m)(n);

    // even :: Int -> Bool
    const even = n =>
        // True if n is an even number.
        0 === n % 2;

    // partition :: (a -> Bool) -> [a] -> ([a], [a])
    const partition = p =>
        // A tuple of two lists - those elements in
        // xs which match p, and those which don't.
        xs => ([...xs]).reduce(
            (a, x) =>
            p(x) ? (
                Tuple(a[0].concat(x))(a[1])
            ) : Tuple(a[0])(a[1].concat(x)),
            Tuple([])([])
        );

    // raise :: Num -> Int -> Num
    const raise = x =>
        // X to the power of n.
        n => Math.pow(x, n);

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

    // unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
    const unfoldr = f =>
        v => {
            const xs = [];
            let xr = [v, v];
            while (true) {
                const mb = f(xr[1]);
                if (mb.Nothing) {
                    return xs
                } else {
                    xr = mb.Just;
                    xs.push(xr[0])
                }
            }
        };

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


Pythagoras tree

The Pythagoras tree is a fractal tree constructed from squares.  It is named after Pythagoras because each triple of touching squares encloses a right triangle, in a configuration traditionally used to represent the Pythagorean theorem.

;Task
Construct a Pythagoras tree of order 7 using only vectors (no rotation or trigonometric functions).

;Related tasks
* Fractal tree

Solution:
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <style>
        canvas {
            position: absolute;
            top: 45%;
            left: 50%;
            width: 640px;
            height: 640px;
            margin: -320px 0 0 -320px;
        }
    </style>
</head>

<body>
    <canvas></canvas>
    <script>
        'use strict';
        var canvas = document.querySelector('canvas');
        canvas.width = 640;
        canvas.height = 640;

        var g = canvas.getContext('2d');

        var depthLimit = 7;
        var hue = 0.15;

        function drawTree(x1, y1, x2, y2, depth) {

            if (depth == depthLimit)
                return;

            var dx = x2 - x1;
            var dy = y1 - y2;

            var x3 = x2 - dy;
            var y3 = y2 - dx;
            var x4 = x1 - dy;
            var y4 = y1 - dx;
            var x5 = x4 + 0.5 * (dx - dy);
            var y5 = y4 - 0.5 * (dx + dy);

            g.beginPath();
            g.moveTo(x1, y1);
            g.lineTo(x2, y2);
            g.lineTo(x3, y3);
            g.lineTo(x4, y4);
            g.closePath();

            g.fillStyle = HSVtoRGB(hue + depth * 0.02, 1, 1);
            g.fill();
            g.strokeStyle = "lightGray";
            g.stroke();

            g.beginPath();
            g.moveTo(x3, y3);
            g.lineTo(x4, y4);
            g.lineTo(x5, y5);
            g.closePath();

            g.fillStyle = HSVtoRGB(hue + depth * 0.035, 1, 1);
            g.fill();
            g.strokeStyle = "lightGray";
            g.stroke();

            drawTree(x4, y4, x5, y5, depth + 1);
            drawTree(x5, y5, x3, y3, depth + 1);
        }

        /* copied from stackoverflow */
        function HSVtoRGB(h, s, v) {
            var r, g, b, i, f, p, q, t;

            i = Math.floor(h * 6);
            f = h * 6 - i;
            p = v * (1 - s);
            q = v * (1 - f * s);
            t = v * (1 - (1 - f) * s);
            switch (i % 6) {
                case 0: r = v, g = t, b = p; break;
                case 1: r = q, g = v, b = p; break;
                case 2: r = p, g = v, b = t; break;
                case 3: r = p, g = q, b = v; break;
                case 4: r = t, g = p, b = v; break;
                case 5: r = v, g = p, b = q; break;
            }
            return "rgb("
                + Math.round(r * 255) + ","
                + Math.round(g * 255) + ","
                + Math.round(b * 255) + ")";
        }

        function draw() {
            g.clearRect(0, 0, canvas.width, canvas.height);
            drawTree(275, 500, 375, 500, 0);
        }
        draw();
    </script>

</body>

</html>


Pythagorean quadruples

One form of   '''Pythagorean quadruples'''   is   (for positive integers   '''a''',   '''b''',   '''c''',   and   '''d'''):

::::::::    a2   +   b2   +   c2     =     d2

An example:

::::::::    22   +   32   +   62     =     72

::::: which is:

::::::::    4    +   9    +   36     =     49

;Task:

For positive integers up   '''2,200'''   (inclusive),   for all values of   '''a''',
'''b''',   '''c''',   and   '''d''',
find   (and show here)   those values of   '''d'''   that   ''can't''   be represented.

Show the values of   '''d'''   on one line of output   (optionally with a title).

;Related tasks:
*   [[Euler's sum of powers conjecture]].
*   [[Pythagorean triples]].

;Reference:
:*   the Wikipedia article:   Pythagorean quadruple.

Solution:
(() => {
    'use strict';

    // main :: IO ()
    const main = () => {
        const xs = takeWhileGen(
            x => 2200 >= x,
            mergeInOrder(
                powersOfTwo(),
                fmapGen(x => 5 * x, powersOfTwo())
            )
        );

        return (
            console.log(JSON.stringify(xs)),
            xs
        );
    }

    // powersOfTwo :: Gen [Int]
    const powersOfTwo = () =>
        iterate(x => 2 * x, 1);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


Pythagorean triples

A Pythagorean triple is defined as three positive integers (a, b, c) where a < b < c, and a^2+b^2=c^2.

They are called primitive triples if a, b, c are co-prime, that is, if their pairwise greatest common divisors {\rm gcd}(a, b) = {\rm gcd}(a, c) = {\rm gcd}(b, c) = 1.

Because of their relationship through the Pythagorean theorem, a, b, and c are co-prime if a and b are co-prime ({\rm gcd}(a, b) = 1).

Each triple forms the length of the sides of a right triangle, whose perimeter is P=a+b+c.

;Task:
The task is to determine how many Pythagorean triples there are with a perimeter no larger than 100 and the number of these that are primitive.

;Extra credit:
Deal with large values.   Can your program handle a maximum perimeter of 1,000,000?   What about 10,000,000?   100,000,000?

Note: the extra credit is not for you to demonstrate how fast your language is compared to others;   you need a proper algorithm to solve them in a timely manner.

;Related tasks:
*   [[Euler's sum of powers conjecture]]
*   [[List comprehensions]]
*   [[Pythagorean quadruples]]

Solution:
(() => {
    "use strict";

    // Arguments: predicate, maximum perimeter
    // pythTripleCount :: ((Int, Int, Int) -> Bool) -> Int -> Int
    const pythTripleCount = p =>
        maxPerim => {
            const
                xs = enumFromTo(1)(
                    Math.floor(maxPerim / 2)
                );

            return xs.flatMap(
                x => xs.slice(x).flatMap(
                    y => xs.slice(y).flatMap(
                        z => ((x + y + z <= maxPerim) &&
                            ((x * x) + (y * y) === z * z) &&
                            p(x, y, z)) ? [
                            [x, y, z]
                        ] : []
                    )
                )
            ).length;
        };

    // ---------------------- TEST -----------------------
    const main = () => [10, 100, 1000]
        .map(n => ({
            maxPerimeter: n,
            triples: pythTripleCount(() => true)(n),
            primitives: pythTripleCount(
                (x, y) => gcd(x)(y) === 1
            )(n)
        }));

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

    // abs :: Num -> Num
    const abs =
        // Absolute value of a given number
        // without the sign.
        x => 0 > x ? (
            -x
        ) : x;

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // gcd :: Integral a => a -> a -> a
    const gcd = x =>
        y => {
            const zero = x.constructor(0);
            const go = (a, b) =>
                zero === b ? (
                    a
                ) : go(b, a % b);

            return go(abs(x), abs(y));
        };

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


Quaternion type

complex numbers.

A complex number has a real and complex part,   sometimes written as     a + bi,
where     a     and     b     stand for real numbers, and     i     stands for the square root of minus 1.

An example of a complex number might be     -3 + 2i,
where the real part,     a     is     '''-3.0'''     and the complex part,     b     is     '''+2.0'''.

A quaternion has one real part and ''three'' imaginary parts,     i,       j,     and     k.

A quaternion might be written as     a + bi + cj + dk.

In the quaternion numbering system:
:::*     ii = jj = kk = ijk = -1,         or more simply,
:::*     ii  = jj  = kk  = ijk   = -1.

The order of multiplication is important, as, in general, for two quaternions:
::::     q1     and     q2:         q1q2  q2q1.

An example of a quaternion might be     1 +2i +3j +4k

There is a list form of notation where just the numbers are shown and the imaginary multipliers    i,       j,     and     k     are assumed by position.

So the example above would be written as     (1, 2, 3, 4)

;Task:
Given the three quaternions and their components:
    q  = (1, 2, 3, 4) = (a,  b,  c,  d)
    q1 = (2, 3, 4, 5) = (a1, b1, c1, d1)
    q2 = (3, 4, 5, 6) = (a2, b2, c2, d2)
And a wholly real number     r = 7.

Create functions   (or classes)   to perform simple maths with quaternions including computing:
# The norm of a quaternion: = \sqrt{a^2 + b^2 + c^2 + d^2}
# The negative of a quaternion:    = (-a, -b, -c, -d)
# The conjugate of a quaternion:    = ( a, -b, -c, -d)
# Addition of a real number     r     and a quaternion     q:      r + q = q + r = (a+r, b, c, d)
# Addition of two quaternions:    q1 + q2 = (a1+a2, b1+b2, c1+c2, d1+d2)
# Multiplication of a real number and a quaternion:    qr = rq = (ar, br, cr, dr)
# Multiplication of two quaternions     q1     and   q2     is given by:    ( a1a2 - b1b2 - c1c2 - d1d2,      a1b2 + b1a2 + c1d2 - d1c2,      a1c2 - b1d2 + c1a2 + d1b2,      a1d2 + b1c2 - c1b2 + d1a2 )
# Show that, for the two quaternions     q1     and     q2:  q1q2  q2q1

If a language has built-in support for quaternions, then use it.

;C.f.:
*   [[Vector products]]
*   On Quaternions;   or on a new System of Imaginaries in Algebra.   By Sir William Rowan Hamilton LL.D, P.R.I.A., F.R.A.S., Hon. M. R. Soc. Ed. and Dub., Hon. or Corr. M. of the Royal or Imperial Academies of St. Petersburgh, Berlin, Turin and Paris, Member of the American Academy of Arts and Sciences, and of other Scientific Societies at Home and Abroad, Andrews' Prof. of Astronomy in the University of Dublin, and Royal Astronomer of Ireland.

Solution:
var Quaternion = (function() {
    // The Q() function takes an array argument and changes it
    // prototype so that it becomes a Quaternion instance.  This is
    // scoped only for prototype member access.
    function Q(a) {
	a.__proto__ = proto;
	return a;
    }

    // Actual constructor.  This constructor converts its arguments to
    // an array, then that array to a Quaternion instance, then
    // returns that instance.  (using "new" with this constructor is
    // optional)
    function Quaternion() {
	return Q(Array.prototype.slice.call(arguments, 0, 4));
    }

    // Prototype for all Quaternions
    const proto = {
	// Inherits from a 4-element Array
	__proto__ : [0,0,0,0],

	// Properties -- In addition to Array[0..3] access, we
	// also define matching a, b, c, and d properties
	get a() this[0],
	get b() this[1],
	get c() this[2],
	get d() this[3],

	// Methods
	norm : function() Math.sqrt(this.map(function(x) x*x).reduce(function(x,y) x+y)),
	negate : function() Q(this.map(function(x) -x)),
	conjugate : function() Q([ this[0] ].concat(this.slice(1).map(function(x) -x))),
	add : function(x) {
	    if ("number" === typeof x) {
		return Q([ this[0] + x ].concat(this.slice(1)));
	    } else {
		return Q(this.map(function(v,i) v+x[i]));
	    }
	},
	mul : function(r) {
	    var q = this;
	    if ("number" === typeof r) {
		return Q(q.map(function(e) e*r));
	    } else {
		return Q([ q[0] * r[0] - q[1] * r[1] - q[2] * r[2] - q[3] * r[3],
			   q[0] * r[1] + q[1] * r[0] + q[2] * r[3] - q[3] * r[2],
			   q[0] * r[2] - q[1] * r[3] + q[2] * r[0] + q[3] * r[1],
			   q[0] * r[3] + q[1] * r[2] - q[2] * r[1] + q[3] * r[0] ]);
	    }
	},
	equals : function(q) this.every(function(v,i) v === q[i]),
	toString : function() (this[0] + " + " + this[1] + "i + "+this[2] + "j + " + this[3] + "k").replace(/\+ -/g, '- ')
    };

    Quaternion.prototype = proto;
    return Quaternion;
})();


RPG attributes generator

'''RPG'''   =   Role Playing Game.

You're running a tabletop RPG, and your players are creating characters.

Each character has six core attributes: strength, dexterity, constitution, intelligence, wisdom, and charisma.

One way of generating values for these attributes is to roll four, 6-sided dice (d6) and sum the three highest rolls, discarding the lowest roll.

Some players like to assign values to their attributes in the order they're rolled.

To ensure generated characters don't put players at a disadvantage, the following requirements must be satisfied:

* The total of all character attributes must be at least 75.
* At least two of the attributes must be at least 15.

However, this can require a lot of manual dice rolling. A programatic solution would be much faster.

;Task:
Write a program that:
# Generates 4 random, whole values between 1 and 6.
# Saves the sum of the 3 largest values.
# Generates a total of 6 values this way.
# Displays the total, and all 6 values once finished.

* The order in which each value was generated must be preserved.
* The total of all 6 values must be at least 75.
* At least 2 of the values must be 15 or more.

Solution:
function roll() {
  const stats = {
    total: 0,
    rolls: []
  }
  let count = 0;

  for(let i=0;i<=5;i++) {
    let d6s = [];

    for(let j=0;j<=3;j++) {
      d6s.push(Math.ceil(Math.random() * 6))
    }

    d6s.sort().splice(0, 1);
    rollTotal = d6s.reduce((a, b) => a+b, 0);

    stats.rolls.push(rollTotal);
    stats.total += rollTotal;
  }

  return stats;
}

let rolledCharacter = roll();

while(rolledCharacter.total < 75 || rolledCharacter.rolls.filter(a => a >= 15).length < 2){
  rolledCharacter = roll();
}

console.log(`The 6 random numbers generated are:
${rolledCharacter.rolls.join(', ')}

Their sum is ${rolledCharacter.total} and ${rolledCharacter.rolls.filter(a => a >= 15).length} of them are >= 15`);


RPG attributes generator

Solution:
(() => {
    'use strict';

    // main :: IO ()
    const main = () =>
        // 10 random heroes drawn from
        // a non-finite series.
        unlines(map(
            xs => show(sum(xs)) +
            ' -> [' + show(xs) + ']',

            take(10, heroes(
                seventyFivePlusWithTwo15s
            ))
        ));

    // seventyFivePlusWithTwo15s :: [Int] -> Bool
    const seventyFivePlusWithTwo15s = xs =>
        // Total score over 75,
        // with two or more qualities scoring 15.
        75 < sum(xs) && 1 < length(filter(
            x => 15 === x, xs
        ));

    // heroes :: Gen IO [(Int, Int, Int, Int, Int, Int)]
    function* heroes(p) {
        // Non-finite list of heroes matching
        // the requirements of predicate p.
        while (true) {
            yield hero(p)
        }
    }

    // hero :: (Int -> Bool) -> IO (Int, Int, Int, Int, Int, Int)
    const hero = p =>
        // A random character matching the
        // requirements of predicate p.
        until(p, character, []);

    // character :: () -> IO [Int]
    const character = () =>
        // A random character with six
        // integral attributes.
        map(() => sum(tail(sort(map(
                randomRInt(1, 6),
                enumFromTo(1, 4)
            )))),
            enumFromTo(1, 6)
        );

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

    // enumFromTo :: (Int, Int) -> [Int]
    const enumFromTo = (m, n) =>
        Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

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

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

    // length :: [a] -> Int
    const length = xs =>
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // e.g. map(randomRInt(1, 10), enumFromTo(1, 20))

    // randomRInt :: Int -> Int -> IO () -> Int
    const randomRInt = (low, high) => () =>
        low + Math.floor(
            (Math.random() * ((high - low) + 1))
        );

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

    // sort :: Ord a => [a] -> [a]
    const sort = xs => xs.slice()
        .sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));

    // sum :: [Num] -> Num
    const sum = xs => xs.reduce((a, x) => a + x, 0);

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

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, 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];
        }));

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

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

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


Ramer-Douglas-Peucker line simplification

The   '''Ramer-Douglas-Peucker'''   algorithm is a line simplification algorithm for reducing the number of points used to define its shape.

;Task:
Using the   '''Ramer-Douglas-Peucker'''   algorithm, simplify the   2D   line defined by the points:
    (0,0)  (1,0.1)  (2,-0.1)  (3,5)  (4,6)  (5,7)  (6,8.1)  (7,9)  (8,9)  (9,9)

The error threshold to be used is:   '''1.0'''.

Display the remaining points here.

;Reference:
:*   the Wikipedia article:   Ramer-Douglas-Peucker algorithm.

Solution:
/**
 * @typedef {{
 *    x: (!number),
 *    y: (!number)
 * }}
 */
let pointType;

/**
 * @param {!Array<pointType>} l
 * @param {number} eps
 */
const RDP = (l, eps) => {
  const last = l.length - 1;
  const p1 = l[0];
  const p2 = l[last];
  const x21 = p2.x - p1.x;
  const y21 = p2.y - p1.y;

  const [dMax, x] = l.slice(1, last)
      .map(p => Math.abs(y21 * p.x - x21 * p.y + p2.x * p1.y - p2.y * p1.x))
      .reduce((p, c, i) => {
        const v = Math.max(p[0], c);
        return [v, v === p[0] ? p[1] : i + 1];
      }, [-1, 0]);

  if (dMax > eps) {
    return [...RDP(l.slice(0, x + 1), eps), ...RDP(l.slice(x), eps).slice(1)];
  }
  return [l[0], l[last]]
};

const points = [
  {x: 0, y: 0},
  {x: 1, y: 0.1},
  {x: 2, y: -0.1},
  {x: 3, y: 5},
  {x: 4, y: 6},
  {x: 5, y: 7},
  {x: 6, y: 8.1},
  {x: 7, y: 9},
  {x: 8, y: 9},
  {x: 9, y: 9}];

console.log(RDP(points, 1));


Random Latin squares

A Latin square of size n is an arrangement of n symbols  in an n-by-n square in such a way that each row and column has each symbol appearing exactly once.
For the purposes of this task, a random Latin square of size n is a Latin square constructed or generated by a probabilistic procedure such that the probability of any particular Latin square of size n being produced is non-zero.

;Example n=4 randomised Latin square:
0 2 3 1
2 1 0 3
3 0 1 2
1 3 2 0

;Task:
# Create a function/routine/procedure/method/... that given n generates a randomised Latin square of size n.
# Use the function to generate ''and show here'', two randomly generated squares of size 5.

;Note:
Strict ''uniformity'' in the random generation is a hard problem and '''not''' a requirement of the task.

;Related tasks:
* [[Latin Squares in reduced form/Randomizing using Jacobson and Matthews' Technique]]
* [[Latin Squares in reduced form]]

;Reference:
* Wikipedia: Latin square
* OEIS: A002860

Solution:
class Latin {
  constructor(size = 3) {
    this.size = size;
    this.mst = [...Array(this.size)].map((v, i) => i + 1);
    this.square = Array(this.size).fill(0).map(() => Array(this.size).fill(0));

    if (this.create(0, 0)) {
      console.table(this.square);
    }
  }

  create(c, r) {
    const d = [...this.mst];
    let s;
    while (true) {
      do {
        s = d.splice(Math.floor(Math.random() * d.length), 1)[0];
        if (!s) return false;
      } while (this.check(s, c, r));

      this.square[c][r] = s;
      if (++c >= this.size) {
        c = 0;
        if (++r >= this.size) {
          return true;
        }
      }
      if (this.create(c, r)) return true;
      if (--c < 0) {
        c = this.size - 1;
        if (--r < 0) {
          return false;
        }
      }
    }
  }

  check(d, c, r) {
    for (let a = 0; a < this.size; a++) {
      if (c - a > -1) {
        if (this.square[c - a][r] === d)
          return true;
      }
      if (r - a > -1) {
        if (this.square[c][r - a] === d)
          return true;
      }
    }
    return false;
  }
}
new Latin(5);


Random number generator (included)

The task is to:
: State the type of random number generator algorithm used in a language's built-in random number generator. If the language or its immediate libraries don't provide a random number generator, skip this task.
: If possible, give a link to a wider explanation of the algorithm used.

Note: the task is ''not'' to create an RNG, but to report on the languages in-built RNG that would be the most likely RNG used.

The main types of pseudo-random number generator (Mersenne twister generator is a subclass). The last main type is where the output of one of the previous ones (typically a Mersenne twister) is fed through a [[cryptographic hash function]] to maximize unpredictability of individual bits.

Note that neither LCGs nor GFSRs should be used for the most demanding applications (cryptography) without additional steps.

Solution: The only built-in random number generation facility is Math.random(), which returns a floating-point number greater than or equal to 0 and less than 1, with approximately uniform distribution. The standard (ECMA-262) does not specify what algorithm is to be used.


Range consolidation

Define a range of numbers   '''R''',   with bounds   '''b0'''   and   '''b1'''   covering all numbers ''between and including both bounds''.

That range can be shown as:
::::::::: '''[b0, b1]'''
::::::::    or equally as:
::::::::: '''[b1, b0]'''

Given two ranges, the act of consolidation between them compares the two ranges:
*   If one range covers all of the other then the result is that encompassing range.
*   If the ranges touch or intersect then the result is   ''one''   new single range covering the overlapping ranges.
*   Otherwise the act of consolidation is to return the two non-touching ranges.

Given   '''N'''   ranges where   '''N > 2'''   then the result is the same as repeatedly replacing all combinations of two ranges by their consolidation until no further consolidation between range pairs is possible.

If   '''N < 2'''   then range consolidation has no strict meaning and the input can be returned.

;Example 1:
:   Given the two ranges   '''[1, 2.5]'''   and   '''[3, 4.2]'''   then
:   there is no common region between the ranges and the result is the same as the input.

;Example 2:
:   Given the two ranges   '''[1, 2.5]'''   and   '''[1.8, 4.7]'''   then
:   there is :   an overlap   '''[2.5, 1.8]'''   between the ranges and
:   the result is the single range   '''[1, 4.7]'''.
:   Note that order of bounds in a range is not (yet) stated.

;Example 3:
:   Given the two ranges   '''[6.1, 7.2]'''   and   '''[7.2, 8.3]'''   then
:   they touch at   '''7.2'''   and
:   the result is the single range   '''[6.1, 8.3]'''.

;Example 4:
:   Given the three ranges   '''[1, 2]'''   and   '''[4, 8]'''   and   '''[2, 5]'''
:   then there is no intersection of the ranges   '''[1, 2]'''   and   '''[4, 8]'''
:   but the ranges   '''[1, 2]'''   and   '''[2, 5]'''   overlap and
:   consolidate to produce the range   '''[1, 5]'''.
:   This range, in turn, overlaps the other range   '''[4, 8]''',   and
:   so consolidates to the final output of the single range   '''[1, 8]'''.

;Task:
Let a normalized range display show the smaller bound to the left;   and show the
range with the smaller lower bound to the left of other ranges when showing multiple ranges.

Output the ''normalized'' result of applying consolidation to these five sets of ranges:
            [1.1, 2.2]
            [6.1, 7.2], [7.2, 8.3]
            [4, 3], [2, 1]
            [4, 3], [2, 1], [-1, -2], [3.9, 10]
            [1, 3], [-6, -1], [-4, -5], [8, 2], [-6, -6]
Show all output here.

;See also:
* [[Set consolidation]]
* [[Set of real numbers]]

Solution:
(() => {
    'use strict';

    const main = () => {

        // consolidated :: [(Float, Float)] -> [(Float, Float)]
        const consolidated = xs =>
            foldl((abetc, xy) =>
                0 < abetc.length ? (() => {
                    const
                        etc = abetc.slice(1),
                        [a, b] = abetc[0],
                        [x, y] = xy;

                    return y >= b ? (
                        cons(xy, etc)
                    ) : y >= a ? (
                        cons([x, b], etc)
                    ) : cons(xy, abetc);
                })() : [xy],
                [],
                sortBy(flip(comparing(fst)),
                    map(([a, b]) => a < b ? (
                            [a, b]
                        ) : [b, a],
                        xs
                    )
                )
            );

        // TEST -------------------------------------------
        console.log(
            tabulated(
                'Range consolidations:',
                JSON.stringify,
                JSON.stringify,
                consolidated,
                [
                    [
                        [1.1, 2.2]
                    ],
                    [
                        [6.1, 7.2],
                        [7.2, 8.3]
                    ],
                    [
                        [4, 3],
                        [2, 1]
                    ],
                    [
                        [4, 3],
                        [2, 1],
                        [-1, -2],
                        [3.9, 10]
                    ],
                    [
                        [1, 3],
                        [-6, -1],
                        [-4, -5],
                        [8, 2],
                        [-6, -6]
                    ]
                ]
            )
        );
    };

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

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

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (f, g) => x => f(g(x));

    // cons :: a -> [a] -> [a]
    const cons = (x, xs) => [x].concat(xs);

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

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

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

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = (n, cFiller, s) =>
        n > s.length ? (
            s.padStart(n, cFiller)
        ) : s;

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

    // length :: [a] -> Int
    const length = xs =>
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // map :: (a -> b) -> [a] -> [b]
    const map = (f, xs) =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // maximumBy :: (a -> a -> Ordering) -> [a] -> a
    const maximumBy = (f, xs) =>
        0 < xs.length ? (
            xs.slice(1)
            .reduce((a, x) => 0 < f(x, a) ? x : a, xs[0])
        ) : undefined;

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

    // tabulated :: String -> (a -> String) ->
    //                        (b -> String) ->
    //           (a -> b) -> [a] -> String
    const tabulated = (s, xShow, fxShow, f, xs) => {
        // Heading -> x display function ->
        //           fx display function ->
        //    f -> values -> tabular string
        const
            ys = map(xShow, xs),
            w = maximumBy(comparing(x => x.length), ys).length,
            rows = zipWith(
                (a, b) => justifyRight(w, ' ', a) + ' -> ' + b,
                ys,
                map(compose(fxShow, f), xs)
            );
        return s + '\n' + unlines(rows);
    };

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, 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];
        }));

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

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

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


Range expansion

{{:Range extraction/Format}}

;Task:
Expand the range description:
   -6,-3--1,3-5,7-11,14,15,17-20
Note that the second element above,
is the '''range from minus 3 to ''minus'' 1'''.

;Related task:
*   [[Range extraction]]

Solution:
#!/usr/bin/env js

function main() {
    print(rangeExpand('-6,-3--1,3-5,7-11,14,15,17-20'));
}

function rangeExpand(rangeExpr) {

    function getFactors(term) {
        var matches = term.match(/(-?[0-9]+)-(-?[0-9]+)/);
        if (!matches) return {first:Number(term)};
        return {first:Number(matches[1]), last:Number(matches[2])};
    }

    function expandTerm(term) {
        var factors = getFactors(term);
        if (factors.length < 2) return [factors.first];
        var range = [];
        for (var n = factors.first; n <= factors.last;  n++) {
            range.push(n);
        }
        return range;
    }

    var result = [];
    var terms = rangeExpr.split(/,/);
    for (var t in terms) {
        result = result.concat(expandTerm(terms[t]));
    }

    return result;
}

main();


Range extraction

{{:Range extraction/Format}}

;Task:
* Create a function that takes a list of integers in increasing order and returns a correctly formatted string in the range format.
* Use the function to compute and print the range formatted version of the following ordered list of integers. (The correct answer is: 0-2,4,6-8,11,12,14-25,27-33,35-39).

     0,  1,  2,  4,  6,  7,  8, 11, 12, 14,
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
    25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
    37, 38, 39
* Show the output of your program.

;Related task:
*   [[Range expansion]]

Solution:
function rangeExtraction(list) {
  var len = list.length;
  var out = [];
  var i, j;

  for (i = 0; i < len; i = j + 1) {
    // beginning of range or single
    out.push(list[i]);

    // find end of range
    for (var j = i + 1; j < len && list[j] == list[j-1] + 1; j++);
    j--;

    if (i == j) {
      // single number
      out.push(",");
    } else if (i + 1 == j) {
      // two numbers
      out.push(",", list[j], ",");
    } else {
      // range
      out.push("-", list[j], ",");
    }
  }
  out.pop(); // remove trailing comma
  return out.join("");
}

// using print function as supplied by Rhino standalone
print(rangeExtraction([
  0,  1,  2,  4,  6,  7,  8, 11, 12, 14,
  15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
  37, 38, 39
]));


Range extraction

Solution:
(() => {
    'use strict';

    // ---------------- RANGE EXTRACTION -----------------

    // rangeFormat :: [Int] -> String
    const rangeFormat = xs =>
        splitBy((a, b) => b - a > 1, xs)
        .map(rangeString)
        .join(',');

    // rangeString :: [Int] -> String
    const rangeString = xs =>
        xs.length > 2 ? (
            [xs[0], last(xs)].map(show)
            .join('-')
        ) : xs.join(',')

    // ---------------------- TEST -----------------------
    const main = () =>
        rangeFormat([0, 1, 2, 4, 6, 7, 8, 11, 12, 14,
            15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
            25, 27, 28, 29, 30, 31, 32, 33, 35, 36,
            37, 38, 39
        ]);

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

    // Splitting not on a delimiter, but whenever the
    // relationship between two consecutive items matches
    // a supplied predicate function

    // splitBy :: (a -> a -> Bool) -> [a] -> [[a]]
    const splitBy = (f, xs) => {
        if (xs.length < 2) return [xs];
        const
            h = xs[0],
            lstParts = xs.slice(1)
            .reduce(([acc, active, prev], x) =>
                f(prev, x) ? (
                    [acc.concat([active]), [x], x]
                ) : [acc, active.concat(x), x], [
                    [],
                    [h],
                    h
                ]);
        return lstParts[0].concat([lstParts[1]]);
    };

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

    // show :: a -> String
    const show = x =>
        JSON.stringify(x);

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


Rate counter

Counting the frequency at which something occurs is a common activity in measuring performance and managing resources. In this task, we assume that there is some job which we want to perform repeatedly, and we want to know how quickly these jobs are being performed.
Of interest is the code that performs the actual measurements. Any other code (such as job implementation or dispatching) that is required to demonstrate the rate tracking is helpful, but not the focus.

Multiple approaches are allowed (even preferable), so long as they can accomplish these goals:

* Run N seconds worth of jobs and/or Y jobs.
* Report at least three distinct times.

Be aware of the precision and accuracy limitations of your timing mechanisms, and document them if you can.

'''See also:''' [[System time]], [[Time a function]]

Solution:
function millis() { // Gets current time in milliseconds.
  return (new Date()).getTime();
}

/* Executes function 'func' n times, returns array of execution times. */
function benchmark(n, func, args) {
  var times = [];
  for (var i=0; i<n; i++) {
    var m = millis();
    func.apply(func, args);
    times.push(millis() - m);
  }
  return times;
}


Recaman's sequence

The '''Recaman's sequence''' generates Natural numbers.

Starting from a(0)=0, the n'th term a(n), where n>0, is the previous term minus n i.e a(n) = a(n-1) - n but only if this is '''both''' positive ''and'' has not been previousely generated.

If the conditions ''don't'' hold then a(n) = a(n-1) + n.

;Task:
# Generate and show here the first 15 members of the sequence.
# Find and show here, the first duplicated number in the sequence.
# '''Optionally''': Find and show here, how many terms of the sequence are needed until all the integers 0..1000, inclusive, are generated.

;References:
* A005132,  The On-Line Encyclopedia of Integer Sequences.
* The Slightly Spooky Recaman Sequence, Numberphile video.
* Recaman's sequence, on Wikipedia.

Solution:
(() => {
    const main = () => {

        console.log(
            'First 15 Recaman:\n' +
            recamanUpto(i => 15 === i)
        );

        console.log(
            '\n\nFirst duplicated Recaman:\n' +
            last(recamanUpto(
                (_, set, rs) => set.size !== rs.length
            ))
        );

        const setK = new Set(enumFromTo(0, 1000));
        console.log(
            '\n\nNumber of Recaman terms needed to generate' +
            '\nall integers from [0..1000]:\n' +
            (recamanUpto(
                (_, setR) => isSubSetOf(setK, setR)
            ).length - 1)
        );
    };

    // RECAMAN --------------------------------------------

    // recamanUpto :: (Int -> Set Int > [Int] -> Bool) -> [Int]
    const recamanUpto = p => {
        let
            i = 1,
            r = 0, // First term of series
            rs = [r];
        const seen = new Set(rs);
        while (!p(i, seen, rs)) {
            r = nextR(seen, i, r);
            seen.add(r);
            rs.push(r);
            i++;
        }
        return rs;
    }

    // Next Recaman number.

    // nextR :: Set Int -> Int -> Int
    const nextR = (seen, i, n) => {
        const back = n - i;
        return (0 > back || seen.has(back)) ? (
            n + i
        ) : back;
    };

    // GENERIC --------------------------------------------

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = (m, n) =>
        m <= n ? iterateUntil(
            x => n <= x,
            x => 1 + x,
            m
        ) : [];

    // isSubsetOf :: Ord a => Set a -> Set a -> Bool
    const isSubSetOf = (a, b) => {
        for (let x of a) {
            if (!b.has(x)) return false;
        }
        return true;
    };

    // iterateUntil :: (a -> Bool) -> (a -> a) -> a -> [a]
    const iterateUntil = (p, f, x) => {
        const vs = [x];
        let h = x;
        while (!p(h))(h = f(h), vs.push(h));
        return vs;
    };

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

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


Rep-string

Given a series of ones and zeroes in a string, define a repeated string or ''rep-string'' as a string which is created by repeating a substring of the ''first'' N characters of the string ''truncated on the right to the length of the input string, and in which the substring appears repeated at least twice in the original''.

For example, the string '''10011001100''' is a rep-string as the leftmost four characters of '''1001''' are repeated three times and truncated on the right to give the original string.

Note that the requirement for having the repeat occur two or more times means that the repeating unit is ''never'' longer than half the length of the input string.

;Task:
* Write a function/subroutine/method/... that takes a string and returns an indication of if it is a rep-string and the repeated string.   (Either the string that is repeated, or the number of repeated characters would suffice).
* There may be multiple sub-strings that make a string a rep-string - in that case an indication of all, or the longest, or the shortest would suffice.
* Use the function to indicate the repeating substring if any, in the following:

1001110011
1110111011
0010010010
1010101010
1111111111
0100101101
0100100
101
11
00
1

* Show your output on this page.

Solution:
(() => {
    'use strict';

    const main = () => {

        // REP-CYCLES -------------------------------------

        // repCycles :: String -> [String]
        const repCycles = s => {
            const n = s.length;
            return filter(
                x => s === take(n, cycle(x)).join(''),
                tail(inits(take(quot(n, 2), s)))
            );
        };

        // TEST -------------------------------------------
        console.log(fTable(
            'Longest cycles:\n',
            str,
            xs => 0 < xs.length ? concat(last(xs)) : '(none)',
            repCycles,
            [
                '1001110011',
                '1110111011',
                '0010010010',
                '1010101010',
                '1111111111',
                '0100101101',
                '0100100',
                '101',
                '11',
                '00',
                '1'
            ]
        ));
    };

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

    // concat :: [[a]] -> [a]
    // concat :: [String] -> String
    const concat = xs =>
        0 < xs.length ? (() => {
            const unit = 'string' !== typeof xs[0] ? (
                []
            ) : '';
            return unit.concat.apply(unit, xs);
        })() : [];

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

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

    // fTable :: String -> (a -> String) ->
    //                     (b -> String) -> (a -> b) -> [a] -> String
    const fTable = (s, xShow, fxShow, f, xs) => {
        // Heading -> x display function ->
        //           fx display function ->
        //    f -> values -> tabular string
        const
            ys = xs.map(xShow),
            w = Math.max(...ys.map(length));
        return s + '\n' + zipWith(
            (a, b) => a.padStart(w, ' ') + ' -> ' + b,
            ys,
            xs.map(x => fxShow(f(x)))
        ).join('\n');
    };

    // inits([1, 2, 3]) -> [[], [1], [1, 2], [1, 2, 3]
    // inits('abc') -> ["", "a", "ab", "abc"]

    // inits :: [a] -> [[a]]
    // inits :: String -> [String]
    const inits = xs => [
            []
        ]
        .concat(('string' === typeof xs ? xs.split('') : xs)
            .map((_, i, lst) => lst.slice(0, 1 + i)));

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

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

    // length :: [a] -> Int
    const length = xs =>
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

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

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

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

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, 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];
        }));

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

    // 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)),
            as = take(lng, xs),
            bs = take(lng, ys);
        return Array.from({
            length: lng
        }, (_, i) => f(as[i], bs[i], i));
    };

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


Resistor mesh

Given    10x10    grid nodes   (as shown in the image)   interconnected by    1O    resistors as shown,
find the resistance between points   '''A'''   and   '''B'''.

;See also:
*   (humor, nerd sniping)   xkcd.com cartoon (you can solve that for extra credits)
*   An article on how to calculate this and an implementation in Mathematica

Solution:
// Vector addition, scalar multiplication & dot product:
const add = (u, v) => {let i = u.length; while(i--) u[i] += v[i]; return u;};
const sub = (u, v) => {let i = u.length; while(i--) u[i] -= v[i]; return u;};
const mul = (a, u) => {let i = u.length; while(i--) u[i] *= a; return u;};
const dot = (u, v) => {let s = 0, i = u.length; while(i--) s += u[i]*v[i]; return s;};

const W = 10, H = 10, A = 11, B = 67;

function getAdjacent(node){ // Adjacency lists for square grid
  let list = [], x = node % W, y = Math.floor(node / W);
  if (x > 0)     list.push(node - 1);
  if (y > 0)     list.push(node - W);
  if (x < W - 1) list.push(node + 1);
  if (y < H - 1) list.push(node + W);
  return list;
}

function linOp(u){ // LHS of the linear equation
  let v = new Float64Array(W * H);
  for(let i = 0; i < v.length; i++){
    if ( i === A || i === B ) {
      v[i] = u[i];
      continue;
    }
    // For each node other then A, B calculate the net current flow:
    for(let j of getAdjacent(i)){
      v[i] += (j === A || j === B) ? u[i] : u[i] - u[j];
    }
  }
  return v;
}

function getRHS(phiA = 1, phiB = 0){ // RHS of the linear equation
  let b = new Float64Array(W * H);
  // Setting boundary conditions (electric potential at A and B):
  b[A] = phiA;
  b[B] = phiB;
  for(let j of getAdjacent(A)) b[j] = phiA;
  for(let j of getAdjacent(B)) b[j] = phiB;
  return b;
}

function init(phiA = 1, phiB = 0){ // initialize unknown vector
  let u = new Float64Array(W * H);
  u[A] = phiA;
  u[B] = phiB;
  return u;
}

function solveLinearSystem(err = 1e-20){ // conjugate gradient solver

  let b = getRHS();
  let u = init();
  let r = sub(linOp(u), b);
  let p = r;
  let e = dot(r,r);

  while(true){
    let Ap    = linOp(p);
    let alpha = e / dot(p, Ap);
    u = sub(u, mul(alpha, p.slice()));
    r = sub(linOp(u), b);
    let e_new = dot(r,r);
    let beta  = e_new / e;

    if(e_new < err) return u;

    e = e_new;
    p = add(r, mul(beta, p));
  }
}

function getResistance(u){
  let curr = 0;
  for(let j of getAdjacent(A)) curr += u[A] - u[j];
  return 1 / curr;
}

let phi = solveLinearSystem();
let res = getResistance(phi);
console.log(`R = ${res} Ohm`);


Reverse words in a string

Reverse the order of all tokens in each of a number of strings and display the result;   the order of characters within a token should not be modified.

;Example:
Hey you, Bub!    would be shown reversed as:    Bub! you, Hey

Tokens are any non-space characters separated by spaces (formally, white-space);   the visible punctuation form part of the word within which it is located and should not be modified.

You may assume that there are no significant non-visible characters in the input.   Multiple or superfluous spaces may be compressed into a single space.

Some strings have no tokens, so an empty string   (or one just containing spaces)   would be the result.

'''Display''' the strings in order   (1st, 2nd, 3rd, ***),   and one string per line.

(You can consider the ten strings as ten lines, and the tokens as words.)

;Input data

             (ten lines within the box)
 line
     +----------------------------------------+
   1 |  ---------- Ice and Fire ------------  |
   2 |                                        |  <--- a blank line here.
   3 |  fire, in end will world the say Some  |
   4 |  ice. in say Some                      |
   5 |  desire of tasted I've what From       |
   6 |  fire. favor who those with hold I     |
   7 |                                        |  <--- a blank line here.
   8 |  ... elided paragraph last ...         |
   9 |                                        |  <--- a blank line here.
  10 |  Frost Robert -----------------------  |
     +----------------------------------------+

;Cf.
* [[Phrase reversals]]

Solution:
var strReversed =
"---------- Ice and Fire ------------\n\
\n\
fire, in end will world the say Some\n\
ice. in say Some\n\
desire of tasted I've what From\n\
fire. favor who those with hold I\n\
\n\
... elided paragraph last ...\n\
\n\
Frost Robert -----------------------";

function reverseString(s) {
  return s.split('\n').map(
    function (line) {
      return line.split(/\s/).reverse().join(' ');
    }
  ).join('\n');
}

console.log(
  reverseString(strReversed)
);


Roman numerals/Decode

Create a function that takes a Roman numeral as its argument and returns its value as a numeric decimal integer.

You don't need to validate the form of the Roman numeral.

Modern Roman numerals are written by expressing each decimal digit of the number to be encoded separately,
starting with the leftmost decimal digit and skipping any '''0'''s   (zeroes).

'''1990''' is rendered as   '''MCMXC'''     (1000 = M,   900 = CM,   90 = XC)     and
'''2008''' is rendered as   '''MMVIII'''       (2000 = MM,   8 = VIII).

The Roman numeral for '''1666''',   '''MDCLXVI''',   uses each letter in descending order.

Solution:
(() => {

    // -------------- ROMAN NUMERALS DECODED ---------------

    // Folding from right to left,
    // lower leftward characters are subtracted,
    // others are added.

    // fromRoman :: String -> Int
    const fromRoman = s =>
        foldr(l => ([r, n]) => [
            l,
            l >= r ? (
                n + l
            ) : n - l
        ])([0, 0])(
            [...s].map(charVal)
        )[1];

    // charVal :: Char -> Maybe Int
    const charVal = k => {
        const v = {
            I: 1,
            V: 5,
            X: 10,
            L: 50,
            C: 100,
            D: 500,
            M: 1000
        } [k];
        return v !== undefined ? v : 0;
    };

    // ----------------------- TEST ------------------------
    const main = () => [
            'MDCLXVI', 'MCMXC', 'MMVIII', 'MMXVI', 'MMXVII'
        ]
        .map(fromRoman)
        .join('\n');

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

    // foldr :: (a -> b -> b) -> b -> [a] -> b
    const foldr = f =>
        // Note that that the Haskell signature of foldr
        // differs from that of foldl - the positions of
        // accumulator and current value are reversed.
        a => xs => [...xs].reduceRight(
            (a, x) => f(x)(a),
            a
        );

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


Roman numerals/Encode

Create a function taking a positive integer as its parameter and returning a string containing the Roman numeral representation of that integer. Modern Roman numerals are written by expressing each digit separately, starting with the left most digit and skipping any digit with a value of zero.

In Roman numerals:
* 1990  is rendered: 1000=M, 900=CM, 90=XC; resulting in MCMXC
* 2008  is written as 2000=MM, 8=VIII; or MMVIII
* 1666  uses each Roman symbol in descending order: MDCLXVI

Solution:
(function () {
    'use strict';

    // If the Roman is a string, pass any delimiters through

    // (Int | String) -> String
    function romanTranscription(a) {
        if (typeof a === 'string') {
            var ps = a.split(/\d+/),
                dlm = ps.length > 1 ? ps[1] : undefined;

            return (dlm ? a.split(dlm)
                    .map(function (x) {
                        return Number(x);
                    }) : [a])
                .map(roman)
                .join(dlm);
        } else return roman(a);
    }

    // roman :: Int -> String
    function roman(n) {
        return [[1000, "M"], [900, "CM"], [500, "D"], [400, "CD"], [100,
        "C"], [90, "XC"], [50, "L"], [40, "XL"], [10, "X"], [9,
        "IX"], [5, "V"], [4, "IV"], [1, "I"]]
            .reduce(function (a, lstPair) {
                var m = a.remainder,
                    v = lstPair[0];

                return (v > m ? a : {
                    remainder: m % v,
                    roman: a.roman + Array(
                            Math.floor(m / v) + 1
                        )
                        .join(lstPair[1])
                });
            }, {
                remainder: n,
                roman: ''
            }).roman;
    }

    // TEST

    return [2016, 1990, 2008, "14.09.2015", 2000, 1666].map(
        romanTranscription);

})();


Roman numerals/Encode

Solution:
(() => {
    "use strict";

    // -------------- ROMAN INTEGER STRINGS --------------

    // roman :: Int -> String
    const roman = n =>
        mapAccumL(residue =>
            ([k, v]) => second(
                q => 0 < q ? (
                    k.repeat(q)
                ) : ""
            )(remQuot(residue)(v))
        )(n)(
            zip([
                "M", "CM", "D", "CD", "C", "XC",
                "L", "XL", "X", "IX", "V", "IV", "I"
            ])([
                1000, 900, 500, 400, 100, 90,
                50, 40, 10, 9, 5, 4, 1
            ])
        )[1]
        .join("");

    // ---------------------- TEST -----------------------
    // main :: IO ()
    const main = () => (
        [2016, 1990, 2008, 2000, 2020, 1666].map(roman)
    ).join("\n");

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

    // mapAccumL :: (acc -> x -> (acc, y)) -> acc ->
    // [x] -> (acc, [y])
    const mapAccumL = f =>
        // A tuple of an accumulation and a list
        // obtained by a combined map and fold,
        // with accumulation from left to right.
        acc => xs => [...xs].reduce(
            (a, x) => {
                const tpl = f(a[0])(x);

                return [
                    tpl[0],
                    a[1].concat(tpl[1])
                ];
            },
            [acc, []]
        );

    // remQuot :: Int -> Int -> (Int, Int)
    const remQuot = m =>
        n => [m % n, Math.trunc(m / n)];

    // second :: (a -> b) -> ((c, a) -> (c, b))
    const second = f =>
        // A function over a simple value lifted
        // to a function over a tuple.
        // f (a, b) -> (a, f(b))
        xy => [xy[0], f(xy[1])];

    // zip :: [a] -> [b] -> [(a, b)]
    const zip = xs =>
        // The paired members of xs and ys, up to
        // the length of the shorter of the two lists.
        ys => Array.from({
            length: Math.min(xs.length, ys.length)
        }, (_, i) => [xs[i], ys[i]]);

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


Runge-Kutta method

Given the example Differential equation:
:y'(t) = t \times \sqrt {y(t)}
With initial condition:
:t_0 = 0 and y_0 = y(t_0) = y(0) = 1
This equation has an exact solution:
:y(t) = \tfrac{1}{16}(t^2 +4)^2

;Task
Demonstrate the commonly used explicit   fourth-order Runge-Kutta method   to solve the above differential equation.
* Solve the given differential equation over the range t = 0 \ldots 10 with a step value of \delta t=0.1 (101 total points, the first being given)
* Print the calculated values of y at whole numbered t's (0.0, 1.0, \ldots 10.0) along with error as compared to the exact solution.

;Method summary
Starting with a given y_n and t_n calculate:
:\delta y_1 = \delta t\times y'(t_n, y_n)\quad
:\delta y_2 = \delta t\times y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_1)
:\delta y_3 = \delta t\times y'(t_n + \tfrac{1}{2}\delta t , y_n + \tfrac{1}{2}\delta y_2)
:\delta y_4 = \delta t\times y'(t_n + \delta t , y_n + \delta y_3)\quad
then:
:y_{n+1} = y_n + \tfrac{1}{6} (\delta y_1 + 2\delta y_2 + 2\delta y_3 + \delta y_4)
:t_{n+1} = t_n + \delta t\quad

Solution:
function rk4(y, x, dx, f) {
    var k1 = dx * f(x, y),
        k2 = dx * f(x + dx / 2.0,   +y + k1 / 2.0),
        k3 = dx * f(x + dx / 2.0,   +y + k2 / 2.0),
        k4 = dx * f(x + dx,         +y + k3);

    return y + (k1 + 2.0 * k2 + 2.0 * k3 + k4) / 6.0;
}

function f(x, y) {
    return x * Math.sqrt(y);
}

function actual(x) {
    return (1/16) * (x*x+4)*(x*x+4);
}

var y = 1.0,
    x = 0.0,
    step = 0.1,
    steps = 0,
    maxSteps = 101,
    sampleEveryN = 10;

while (steps < maxSteps) {
    if (steps%sampleEveryN === 0) {
        console.log("y(" + x + ") =  \t" + y + "\t ± " + (actual(x) - y).toExponential());
    }

    y = rk4(y, x, step, f);

    // using integer math for the step addition
    // to prevent floating point errors as 0.2 + 0.1 != 0.3
    x = ((x * 10) + (step * 10)) / 10;
    steps += 1;
}


Runtime evaluation

Demonstrate a language's ability for programs to execute code written in the language provided at runtime.

Show what kind of program fragments are permitted (e.g. expressions vs. statements), and how to get values in and out (e.g. environments, arguments, return values), if applicable what lexical/static environment the program is evaluated in, and what facilities for restricting (e.g. sandboxes, resource limits) or customizing (e.g. debugging facilities) the execution.

You may not invoke a separate evaluator program, or invoke a compiler and then its output, unless the interface of that program, and the syntax and means of executing it, are considered part of your language/library/platform.

For a more constrained task giving a specific program fragment to evaluate, see [[Eval in environment]].

Solution:
var foo = eval('{value: 42}');
eval('var bar = "Hello, world!";');

typeof foo; // 'object'
typeof bar; // 'string'


Runtime evaluation/In an environment

Given a program in the language (as a string or AST) with a free variable named x (or another name if that is not valid syntax), evaluate it with x bound to a provided value, then evaluate it again with x bound to another provided value, then subtract the result of the first from the second and return or print it.

Do so in a way which:
* does not involve string manipulation of the input source code
* is plausibly extensible to a runtime-chosen set of bindings rather than just x
* does not make x a ''global'' variable

or note that these are impossible.

;See also:
* For more general examples and language-specific details, see [[Eval]].
* [[Dynamic variable names]] is a similar task.

Solution:
function evalWithX(expr, a, b) {
    var x = a;
    var atA = eval(expr);
    x = b;
    var atB = eval(expr);
    return atB - atA;
}


Sailors, coconuts and a monkey problem

Five sailors are shipwrecked on an island and collect a large pile of coconuts during the day.

That night the first sailor wakes up and decides to take his first share early  so tries to divide the pile of coconuts equally into five piles but finds that there is one coconut left over, so he tosses it to a monkey and then hides "his" one of the five equally sized piles of coconuts and pushes the other four piles together to form a single visible pile of coconuts again and goes to bed.

To cut a long story short, each of the sailors in turn gets up once during the night and performs the same actions of dividing the coconut pile into five, finding that one coconut is left over and giving that single remainder coconut to the monkey.

In the morning (after the surreptitious and separate action of each of the five sailors during the night), the remaining coconuts are divided into five equal piles for each of the sailors, whereupon it is found that the pile of coconuts divides equally amongst the sailors with no remainder. (Nothing for the monkey in the morning.)

;The task:
# Calculate the minimum possible size of the initial pile of coconuts collected during the first day.
# Use a method that assumes an answer is possible, and then applies the constraints of the tale to see if it is correct. (I.e. no applying some formula that generates the correct answer without integer divisions and remainders and tests on remainders; but constraint solvers ''are'' allowed.)
# Calculate the size of the initial pile of coconuts if six sailors were marooned and went through a similar process (but split into six piles instead of five of course).
# Show your answers here.

;Extra credit (optional):
* Give some indication of the number of coconuts each sailor hides during the night.

;Note:
* Of course the tale is told in a world where the collection of any amount of coconuts in a day and multiple divisions of the pile, etc can occur in time fitting the story line, so as not to affect the mathematics.
* The tale is also told in a version where the monkey also gets a coconut in the morning. This is ''not'' that tale!

;C.f:
* Monkeys and Coconuts - Numberphile (Video) Analytical solution.
* A002021: Pile of coconuts problem The On-Line Encyclopedia of Integer Sequences. (Although some of its references may use the alternate form of the tale).

Solution:
(function () {

    // wakeSplit :: Int -> Int -> Int -> Int
    function wakeSplit(intNuts, intSailors, intDepth) {
        var nDepth = intDepth !== undefined ? intDepth : intSailors,
            portion = Math.floor(intNuts / intSailors),
            remain = intNuts % intSailors;

        return 0 >= portion || remain !== (nDepth ? 1 : 0) ?
            null : nDepth ? wakeSplit(
                intNuts - portion - remain, intSailors, nDepth - 1
            ) : intNuts;
    }

    // TEST for 5, 6, and 7 intSailors
    return [5, 6, 7].map(function (intSailors) {
        var intNuts = intSailors;

        while (!wakeSplit(intNuts, intSailors)) intNuts += 1;

        return intNuts;
    });
})();


Selectively replace multiple instances of a character within a string

Task
This is admittedly a trivial task but I thought it would be interesting to see how succinctly (or otherwise) different languages can handle it.

Given the string: "abracadabra", replace programatically:

* the first 'a' with 'A'
* the second 'a' with 'B'
* the fourth 'a' with 'C'
* the fifth 'a' with 'D'
* the first 'b' with 'E'
* the second 'r' with 'F'

Note that there is no replacement for the third 'a', second 'b' or first 'r'.

The answer should, of course, be : "AErBcadCbFD".

Solution:
function findNth(s, c, n) {
  if (n === 1) return s.indexOf(c);
  return s.indexOf(c, findNth(s, c, n - 1) + 1);
}

function selectiveReplace(s, ops) {
  const chars = Array.from(s);
  for ([n, old, rep] of ops) {
    chars[findNth(s, old, n)] = rep;
  }
  return chars.join("");
}

console.log(
  selectiveReplace("abracadabra", [
    [1, "a", "A"], // the first 'a' with 'A'
    [2, "a", "B"], // the second 'a' with 'B'
    [4, "a", "C"], // the fourth 'a' with 'C'
    [5, "a", "D"], // the fifth 'a' with 'D'
    [1, "b", "E"], // the first 'b' with 'E'
    [2, "r", "F"], // the second 'r' with 'F'
  ])
);


Semordnilap

A semordnilap is a word (or phrase) that spells a different word (or phrase) backward. "Semordnilap" is a word that itself is a semordnilap.

Example: ''lager'' and ''regal''

;Task
This task does not consider semordnilap phrases, only single words.
Using only words from this list, report the total number of unique semordnilap pairs, and print 5 examples.
Two matching semordnilaps, such as ''lager'' and ''regal'', should be counted as one unique pair.
(Note that the word "semordnilap" is not in the above dictionary.)

Solution:
#!/usr/bin/env node
var  fs = require('fs');
var sys = require('sys');

var dictFile = process.argv[2] || "unixdict.txt";

var dict = {};
fs.readFileSync(dictFile)
  .toString()
  .split('\n')
  .forEach(function(word) {
    dict[word] = word.split("").reverse().join("");
  });

function isSemordnilap(word) { return dict[dict[word]]; };

var semordnilaps = []
for (var key in dict) {
  if (isSemordnilap(key)) {
    var rev = dict[key];
    if (key < rev) {
      semordnilaps.push([key,rev]) ;
    }
  }
}

var count = semordnilaps.length;
sys.puts("There are " + count + " semordnilaps in " +
         dictFile + ".  Here are 5:" );

var indices=[]
for (var i=0; i<count; ++i) {
  if (Math.random() < 1/Math.ceil(i/5.0)) {
    indices[i%5] = i
  }
}
indices.sort()
for (var i=0; i<5; ++i) {
  sys.puts(semordnilaps[indices[i]]);
}


Semordnilap

Solution:
(() => {
    'use strict';

    // semordnilap :: [String] -> String
    const semordnilap = xs => {
        const go = ([s, ws], w) =>
            s.has(w.split('').reverse().join('')) ? (
                [s, [w].concat(ws)]
            ) : [s.add(w), ws];
        return xs.reduce(go, [new Set(), []])[1];
    };

    const main = () => {

        // xs :: [String]
        const xs = semordnilap(
            lines(readFile('unixdict.txt'))
        );

        console.log(xs.length);
        xs.filter(x => 4 < x.length).forEach(
            x => showLog(...[x, x.split('').reverse().join('')])
        )
    };

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

    // lines :: String -> [String]
    const lines = s => s.split(/[\r\n]/);

    // readFile :: FilePath -> IO String
    const readFile = fp => {
        const
            e = $(),
            uw = ObjC.unwrap,
            s = uw(
                $.NSString.stringWithContentsOfFileEncodingError(
                    $(fp)
                    .stringByStandardizingPath,
                    $.NSUTF8StringEncoding,
                    e
                )
            );
        return undefined !== s ? (
            s
        ) : uw(e.localizedDescription);
    };

    // showLog :: a -> IO ()
    const showLog = (...args) =>
        console.log(
            args
            .map(JSON.stringify)
            .join(' -> ')
        );

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


Sequence: smallest number with exactly n divisors

Calculate the sequence where each term   an   is the '''smallest natural number''' that has exactly   '''n'''   divisors.

;Task
Show here, on this page, at least the first  '''15'''  terms of the sequence.

;Related tasks:
:* [[Sequence: smallest number greater than previous term with exactly n divisors]]
:* [[Sequence: nth number with exactly n divisors]]

;See also:
:* OEIS:A005179

Solution:
(() => {
    'use strict';

    // a005179 :: () -> [Int]
    const a005179 = () =>
        fmapGen(
            n => find(
                compose(
                    eq(n),
                    succ,
                    length,
                    properDivisors
                )
            )(enumFrom(1)).Just
        )(enumFrom(1));

    // ------------------------TEST------------------------
    // main :: IO ()
    const main = () =>
        console.log(
            take(15)(
                a005179()
            )
        );

    // [1,2,4,6,16,12,64,24,36,48,1024,60,4096,192,144]

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

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        fs.reduce(
            (f, g) => x => f(g(x)),
            x => x
        );

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

    // eq (==) :: Eq a => a -> a -> Bool
    const eq = a =>
        // True when a and b are equivalent in the terms
        // defined below for their shared data type.
        b => a === b;

    // find :: (a -> Bool) -> Gen [a] -> Maybe a
    const find = p => xs => {
        const mb = until(tpl => {
            const nxt = tpl[0];
            return nxt.done || p(nxt.value);
        })(
            tpl => Tuple(tpl[1].next())(
                tpl[1]
            )
        )(Tuple(xs.next())(xs))[0];
        return mb.done ? (
            Nothing()
        ) : Just(mb.value);
    }

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

    // group :: [a] -> [[a]]
    const group = xs => {
        // A list of lists, each containing only equal elements,
        // such that the concatenation of these lists is xs.
        const go = xs =>
            0 < xs.length ? (() => {
                const
                    h = xs[0],
                    i = xs.findIndex(x => h !== x);
                return i !== -1 ? (
                    [xs.slice(0, i)].concat(go(xs.slice(i)))
                ) : [xs];
            })() : [];
        return go(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
        (Array.isArray(xs) || 'string' === typeof xs) ? (
            xs.length
        ) : Infinity;

    // liftA2List :: (a -> b -> c) -> [a] -> [b] -> [c]
    const liftA2List = f => xs => ys =>
        // The binary operator f lifted to a function over two
        // lists. f applied to each pair of arguments in the
        // cartesian product of xs and ys.
        xs.flatMap(
            x => ys.map(f(x))
        );

    // mul (*) :: Num a => a -> a -> a
    const mul = a => b => a * b;

    // properDivisors :: Int -> [Int]
    const properDivisors = n =>
        // The ordered divisors of n,
        // excluding n itself.
        1 < n ? (
            sort(group(primeFactors(n)).reduce(
                (a, g) => liftA2List(mul)(a)(
                    scanl(mul)([1])(g)
                ),
                [1]
            )).slice(0, -1)
        ) : [];

    // primeFactors :: Int -> [Int]
    const primeFactors = n => {
        // A list of the prime factors of n.
        const
            go = x => {
                const
                    root = Math.floor(Math.sqrt(x)),
                    m = until(
                        ([q, _]) => (root < q) || (0 === (x % q))
                    )(
                        ([_, r]) => [step(r), 1 + r]
                    )(
                        [0 === x % 2 ? 2 : 3, 1]
                    )[0];
                return m > root ? (
                    [x]
                ) : ([m].concat(go(Math.floor(x / m))));
            },
            step = x => 1 + (x << 2) - ((x >> 1) << 1);
        return go(n);
    };

    // scanl :: (b -> a -> b) -> b -> [a] -> [b]
    const scanl = f => startValue => xs =>
        xs.reduce((a, x) => {
            const v = f(a[0])(x);
            return Tuple(v)(a[1].concat(v));
        }, Tuple(startValue)([startValue]))[1];

    // sort :: Ord a => [a] -> [a]
    const sort = xs => xs.slice()
        .sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));

    // succ :: Enum a => a -> a
    const succ = x =>
        1 + x;

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


Set consolidation

Given two sets of items then if any item is common to any set then the result of applying ''consolidation'' to those sets is a set of sets whose contents is:
*  The two input sets if no common item exists between the two input sets of items.
*  The single set that is the union of the two input sets if they share a common item.

Given N sets of items where N>2 then the result is the same as repeatedly replacing all combinations of two sets by their consolidation until no further consolidation between set pairs is possible.
If N<2 then consolidation has no strict meaning and the input can be returned.

;'''Example 1:'''
:Given the two sets {A,B} and {C,D} then there is no common element between the sets and the result is the same as the input.
;'''Example 2:'''
:Given the two sets {A,B} and {B,D} then there is a common element B between the sets and the result is the single set {B,D,A}.  (Note that order of items in a set is immaterial: {A,B,D} is the same as {B,D,A} and {D,A,B}, etc).
;'''Example 3:'''
:Given the three sets {A,B} and {C,D} and {D,B} then there is no common element between the sets {A,B} and {C,D} but the sets {A,B} and {D,B} do share a common element that consolidates to produce the result {B,D,A}. On examining this result with the remaining set, {C,D}, they share a common element and so consolidate to the final output of the single set {A,B,C,D}
;'''Example 4:'''
:The consolidation of the five sets:
::{H,I,K}, {A,B}, {C,D}, {D,B}, and {F,G,H}
:Is the two sets:
::{A, C, B, D}, and {G, F, I, H, K}

'''See also'''
* Connected component (graph theory)
* [[Range consolidation]]

Solution:
(() => {
    'use strict';

    // consolidated :: Ord a => [Set a] -> [Set a]
    const consolidated = xs => {
        const go = (s, xs) =>
            0 !== xs.length ? (() => {
                const h = xs[0];
                return 0 === intersection(h, s).size ? (
                    [h].concat(go(s, tail(xs)))
                ) : go(union(h, s), tail(xs));
            })() : [s];
        return foldr(go, [], xs);
    };

    // TESTS ----------------------------------------------
    const main = () =>
        map(xs => intercalate(
                ', and ',
                map(showSet, consolidated(xs))
            ),
            map(x => map(
                    s => new Set(chars(s)),
                    x
                ),
                [
                    ['ab', 'cd'],
                    ['ab', 'bd'],
                    ['ab', 'cd', 'db'],
                    ['hik', 'ab', 'cd', 'db', 'fgh']
                ]
            )
        ).join('\n');

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

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

    // concat :: [[a]] -> [a]
    // concat :: [String] -> String
    const concat = xs =>
        0 < xs.length ? (() => {
            const unit = 'string' !== typeof xs[0] ? (
                []
            ) : '';
            return unit.concat.apply(unit, xs);
        })() : [];

    // elems :: Dict -> [a]
    // elems :: Set -> [a]
    const elems = x =>
        'Set' !== x.constructor.name ? (
            Object.values(x)
        ) : Array.from(x.values());

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

    // Note that that the Haskell signature of foldr differs from that of
    // foldl - the positions of accumulator and current value are reversed

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

    // intercalate :: [a] -> [[a]] -> [a]
    // intercalate :: String -> [String] -> String
    const intercalate = (sep, xs) =>
        0 < xs.length && 'string' === typeof sep &&
        'string' === typeof xs[0] ? (
            xs.join(sep)
        ) : concat(intersperse(sep, xs));

    // intersection :: Ord a => Set a -> Set a -> Set a
    const intersection = (s, s1) =>
        new Set([...s].filter(x => s1.has(x)));

    // intersperse :: a -> [a] -> [a]
    // intersperse :: Char -> String -> String
    const intersperse = (sep, xs) => {
        const bln = 'string' === typeof xs;
        return xs.length > 1 ? (
            (bln ? concat : x => x)(
                (bln ? (
                    xs.split('')
                ) : xs)
                .slice(1)
                .reduce((a, x) => a.concat([sep, x]), [xs[0]])
            )) : xs;
    };

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

    // showSet :: Set -> String
    const showSet = s =>
        intercalate(elems(s), ['{', '}']);

    // sort :: Ord a => [a] -> [a]
    const sort = xs => xs.slice()
        .sort((a, b) => a < b ? -1 : (a > b ? 1 : 0));

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

    // union :: Ord a => Set a -> Set a -> Set a
    const union = (s, s1) =>
        Array.from(s1.values())
        .reduce(
            (a, x) => (a.add(x), a),
            new Set(s)
        );

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


Set of real numbers

All real numbers form the uncountable set R.  Among its subsets, relatively simple are the convex sets, each expressed as a range between two real numbers ''a'' and ''b'' where ''a'' <= ''b''.  There are actually four cases for the meaning of "between", depending on open or closed boundary:
* [''a'', ''b'']: {''x'' | ''a'' <= ''x'' and ''x'' <= ''b'' }
* (''a'', ''b''): {''x'' | ''a'' < ''x'' and ''x'' < ''b'' }
* [''a'', ''b''): {''x'' | ''a'' <= ''x'' and ''x'' < ''b'' }
* (''a'', ''b'']: {''x'' | ''a'' < ''x'' and ''x'' <= ''b'' }
Note that if ''a'' = ''b'', of the four only [''a'', ''a''] would be non-empty.

'''Task'''
* Devise a way to represent any set of real numbers, for the definition of 'any' in the implementation notes below.
* Provide methods for these common set operations (''x'' is a real number; ''A'' and ''B'' are sets):
:* ''x''  ''A'': determine if ''x'' is an element of ''A''
:: example: 1 is in [1, 2), while 2, 3, ... are not.
:* ''A''  ''B'': union of ''A'' and ''B'', i.e. {''x'' | ''x''  ''A'' or ''x''  ''B''}
:: example: [0, 2)  (1, 3) = [0, 3); [0, 1)  (2, 3] = well, [0, 1)  (2, 3]
:* ''A''  ''B'': intersection of ''A'' and ''B'', i.e. {''x'' | ''x''  ''A'' and ''x''  ''B''}
:: example: [0, 2)  (1, 3) = (1, 2); [0, 1)  (2, 3] = empty set
:* ''A'' - ''B'': difference between ''A'' and ''B'', also written as ''A'' \ ''B'', i.e. {''x'' | ''x''  ''A'' and ''x''  ''B''}
:: example: [0, 2) - (1, 3) = [0, 1]
* Test your implementation by checking if numbers 0, 1, and 2 are in any of the following sets:
:* (0, 1]  [0, 2)
:* [0, 2)  (1, 2]
:* [0, 3) - (0, 1)
:* [0, 3) - [0, 1]

'''Implementation notes'''
* 'Any' real set means 'sets that can be expressed as the union of a finite number of convex real sets'.  Cantor's set needs not apply.
* Infinities should be handled gracefully; indeterminate numbers (NaN) can be ignored.
* You can use your machine's native real number representation, which is probably IEEE floating point, and assume it's good enough (it usually is).

'''Optional work'''
* Create a function to determine if a given set is empty (contains no element).
* Define ''A'' = {''x'' | 0 < ''x'' < 10 and |sin(p ''x''2)| > 1/2 }, ''B'' = {''x'' | 0 < ''x'' < 10 and |sin(p ''x'')| > 1/2}, calculate the length of the real axis covered by the set ''A'' - ''B''.  Note that
|sin(p ''x'')| > 1/2 is the same as ''n'' + 1/6 < ''x'' < ''n'' + 5/6 for all integers ''n''; your program does not need to derive this by itself.

Solution:
function realSet(set1, set2, op, values) {
    const makeSet=(set0)=>{
        let res = []
        if(set0.rangeType===0){
            for(let i=set0.low;i<=set0.high;i++)
                res.push(i);
        } else if (set0.rangeType===1) {
            for(let i=set0.low+1;i<set0.high;i++)
                res.push(i);
        } else if(set0.rangeType===2){
            for(let i=set0.low+1;i<=set0.high;i++)
                res.push(i);
        } else {
            for(let i=set0.low;i<set0.high;i++)
                res.push(i);
        }
        return res;
    }
    let res = [],finalSet=[];
    set1 = makeSet(set1);
    set2 = makeSet(set2);
    if(op==="union")
        finalSet = [...new Set([...set1,...set2])];
    else if(op==="intersect") {
        for(let i=0;i<set1.length;i++)
            if(set1.indexOf(set2[i])!==-1)
                finalSet.push(set2[i]);
    } else {
        for(let i=0;i<set2.length;i++)
            if(set1.indexOf(set2[i])===-1)
                finalSet.push(set2[i]);

        for(let i=0;i<set1.length;i++)
            if(set2.indexOf(set1[i])===-1)
                finalSet.push(set1[i]);
    }
    for(let i=0;i<values.length;i++){
        if(finalSet.indexOf(values[i])!==-1)
            res.push(true);
        else
            res.push(false);
    }
    return res;
}


Shoelace formula for polygonal area

Given the n + 1 vertices x[0], y[0] .. x[N], y[N] of a simple polygon described in a clockwise direction, then the polygon's area can be calculated by:

abs( (sum(x[0]*y[1] + ... x[n-1]*y[n]) + x[N]*y[0]) -
     (sum(x[1]*y[0] + ... x[n]*y[n-1]) + x[0]*y[N])
   ) / 2
(Where abs returns the absolute value)

;Task:
Write a function/method/routine to use the the Shoelace formula to calculate the area of the polygon described by the ordered points:
      (3,4), (5,11), (12,8), (9,5), and (5,6)

Show the answer here, on this page.

Solution:
(() => {
    "use strict";

    // ------- SHOELACE FORMULA FOR POLYGONAL AREA -------

    // shoelaceArea :: [(Float, Float)] -> Float
    const shoeLaceArea = vertices => abs(
        uncurry(subtract)(
            ap(zip)(compose(tail, cycle))(
                vertices
            )
            .reduce(
                (a, x) => [0, 1].map(b => {
                    const n = Number(b);

                    return a[n] + (
                        x[0][n] * x[1][Number(!b)]
                    );
                }),
                [0, 0]
            )
        )
    ) / 2;

    // ----------------------- TEST -----------------------
    const main = () => {
        const ps = [
            [3, 4],
            [5, 11],
            [12, 8],
            [9, 5],
            [5, 6]
        ];

        return [
                "Polygonal area by shoelace formula:",
                `${JSON.stringify(ps)} -> ${shoeLaceArea(ps)}`
            ]
            .join("\n");
    };

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

    // abs :: Num -> Num
    const abs = x =>
        // Absolute value of a given number
        // without the sign.
        0 > x ? -x : x;

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

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        // A function defined by the right-to-left
        // composition of all the functions in fs.
        fs.reduce(
            (f, g) => x => f(g(x)),
            x => x
        );

    // cycle :: [a] -> Generator [a]
    const cycle = function* (xs) {
        // An infinite repetition of xs,
        // from which an arbitrary prefix
        // may be taken.
        const lng = xs.length;
        let i = 0;

        while (true) {
            yield xs[i];
            i = (1 + i) % lng;
        }
    };

    // 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;

    // subtract :: Num -> Num -> Num
    const subtract = x =>
        y => y - x;

    // tail :: [a] -> [a]
    const tail = xs =>
        // A new list consisting of all
        // items of xs except the first.
        "GeneratorFunction" !== xs.constructor
        .constructor.name ? (
            Boolean(xs.length) ? (
                xs.slice(1)
            ) : undefined
        ) : (take(1)(xs), xs);

    // 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)
        ) : Array.from({
            length: n
        }, () => {
            const x = xs.next();

            return x.done ? [] : [x.value];
        }).flat();

    // uncurry :: (a -> b -> c) -> ((a, b) -> c)
    const uncurry = f =>
        // A function over a pair, derived
        // from a curried function.
        (...args) => {
            const [x, y] = Boolean(args.length % 2) ? (
                args[0]
            ) : args;

            return f(x)(y);
        };

    // zip :: [a] -> [b] -> [(a, b)]
    const zip = xs => ys => {
        const
            n = Math.min(length(xs), length(ys)),
            vs = take(n)(ys);

        return take(n)(xs)
            .map((x, i) => [x, vs[i]]);
    };

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


Show ASCII table

Show  the ASCII character set  from values   '''32'''   to   '''127'''   (decimal)   in a table format.

Solution:
(() => {

    "use strict";

    // ------------------- ASCII TABLE -------------------

    // asciiTable :: String
    const asciiTable = () =>
        transpose(
            chunksOf(16)(
                enumFromTo(32)(127)
                .map(asciiEntry)
            )
        )
        .map(
            xs => xs.map(justifyLeft(12)(" "))
            .join("")
        )
        .join("\n");

    // asciiEntry :: Int -> String
    const asciiEntry = n => {
        const k = asciiName(n);

        return "" === k ? (
            ""
        ) : `${justifyRight(4)(" ")(n.toString())} : ${k}`;
    };

    // asciiName :: Int -> String
    const asciiName = n =>
        32 > n || 127 < n ? (
            ""
        ) : 32 === n ? (
            "Spc"
        ) : 127 === n ? (
            "Del"
        ) : chr(n);

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

    // chr :: Int -> Char
    const chr = x =>
        // The character at unix code-point x.
        String.fromCodePoint(x);

    // chunksOf :: Int -> [a] -> [[a]]
    const chunksOf = n => {
        // xs split into sublists of length n.
        // The last sublist will be short if n
        // does not evenly divide the length of xs .
        const go = xs => {
            const chunk = xs.slice(0, n);

            return 0 < chunk.length ? (
                [chunk].concat(
                    go(xs.slice(n))
                )
            ) : [];
        };

        return go;
    };

    // enumFromTo :: Int -> Int -> [Int]
    const enumFromTo = m =>
        n => Array.from({
            length: 1 + n - m
        }, (_, i) => m + i);

    // justifyLeft :: Int -> Char -> String -> String
    const justifyLeft = n =>
        // The string s, followed by enough padding (with
        // the character c) to reach the string length n.
        c => s => n > s.length ? (
            s.padEnd(n, c)
        ) : s;

    // justifyRight :: Int -> Char -> String -> String
    const justifyRight = n =>
        // The string s, preceded by enough padding (with
        // the character c) to reach the string length n.
        c => s => Boolean(s) ? (
            s.padStart(n, c)
        ) : "";

    // transpose :: [[a]] -> [[a]]
    const transpose = rows =>
        // The columns of the input transposed
        // into new rows.
        // This version assumes input rows of even length.
        0 < rows.length ? rows[0].map(
            (x, i) => rows.flatMap(
                v => v[i]
            )
        ) : [];

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


Sierpinski pentagon

Produce a graphical or ASCII-art representation of a Sierpinski pentagon (aka a Pentaflake) of order 5. Your code should also be able to correctly generate representations of lower orders: 1 to 4.

;See also
* Sierpinski pentagon

Solution:
 	Click Pentaflake to iterate.  Order: 0
 	<input type="submit" value="RESET" onclick="resetf(0);">
 	(Reset anytime: to start new Pentaflake and change color.)

    <canvas id="cvsid" width=640 height=640></canvas>


Sierpinski triangle/Graphical

Produce a graphical representation of a Sierpinski triangle of order N in any orientation.

An example of Sierpinski's triangle (order = 8) looks like this:
[[File:Sierpinski_Triangle_Unicon.PNG]]

Solution:
;Note:
* "Order" to calculate a size of resulting plot/matrix is not used in this algorithm, Instead, construction is done in accordance to a square   m x m matrix. In our case it should be equal to a size of the square canvas.
* Change canvas setting from size "640" to "1280". You will discover that density of dots in plotted triangle is stable for this algorithm. Size of the plotted figure is constantly increasing in the S-E direction. Also, the number of all triangles in N-W triangular part of the canvas is always the same.
* So, in this case it could be called: "Sierpinski ever-expanding field of triangles".
<br>