Functional coverage tree

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

    // updatedCoverageOutline :: String -> String
    const updatedCoverageOutline = outlineText => {
        const
            delimiter = '|',
            indentedLines = indentLevelsFromLines(lines(outlineText)),
            columns = init(tokenizeWith(delimiter)(snd(indentedLines[0])));

        // SERIALISATION OF UPDATED PARSE TREE (TO NEW OUTLINE TEXT)
        return tabulation(delimiter)(
            columns.concat('SHARE OF RESIDUE\n')
        ) + unlines(
            indentedLinesFromTree(
                showCoverage(delimiter))('    ')(

                // TWO TRAVERSAL COMPUTATIONS

                withResidueShares(1.0)(
                    foldTree(weightedCoverage)(

                        // PARSE TREE (FROM OUTLINE TEXT)
                        fmapTree(compose(
                            partialRecord, tokenizeWith(delimiter)
                        ))(fst(
                            forestFromLineIndents(tail(indentedLines))
                        ))
                    )
                ))
        );
    };

    // TEST -----------------------------------------------
    // main :: IO ()
    const main = () =>
        console.log(
            // strOutline is included as literal text
            // at the foot of this code listing.
            updatedCoverageOutline(strOutline)
        );

    // COVERAGE AND SHARES OF RESIDUE ---------------------

    // weightedCoverage :: Dict -> Forest Dict -> Tree Dict
    const weightedCoverage = x => xs => {
        const
            cws = map(compose(
                fanArrow(x => x.coverage)(x => x.weight),
                root
            ))(xs),
            totalWeight = cws.reduce((a, tpl) => a + snd(tpl), 0);
        return Node(
            insertDict('coverage')(
                cws.reduce((a, tpl) => {
                    const [c, w] = Array.from(tpl);
                    return a + (c * w);
                }, x.coverage) / (
                    0 < totalWeight ? totalWeight : 1
                )
            )(x)
        )(xs);
    };

    // withResidueShares :: Float -> Tree Dict -> Tree Dict
    const withResidueShares = shareOfTotal => tree => {
        const go = fraction => node => {
            const
                nodeRoot = node.root,
                forest = node.nest,
                weights = forest.map(x => x.root.weight),
                weightTotal = sum(weights);
            return Node(
                insertDict('share')(
                    fraction * (1 - nodeRoot.coverage)
                )(nodeRoot)
            )(
                zipWith(go)(
                    weights.map(w => fraction * (w / weightTotal))
                )(forest)
            );
        };
        return go(shareOfTotal)(tree);
    };

    // OUTLINE PARSED TO TREE -----------------------------

    // forestFromLineIndents :: [(Int, String)] -> [Tree String]
    const forestFromLineIndents = tuples => {
        const go = xs =>
            0 < xs.length ? (() => {
                const [n, s] = Array.from(xs[0]);
                // Lines indented under this line,
                // tupled with all the rest.
                const [firstTreeLines, rest] = Array.from(
                    span(x => n < x[0])(xs.slice(1))
                );
                // This first tree, and then the rest.
                return [Node(s)(go(firstTreeLines))]
                    .concat(go(rest));
            })() : [];
        return go(tuples);
    };

    // indentLevelsFromLines :: [String] -> [(Int, String)]
    const indentLevelsFromLines = xs => {
        const
            indentTextPairs = xs.map(compose(
                firstArrow(length), span(isSpace)
            )),
            indentUnit = minimum(indentTextPairs.flatMap(pair => {
                const w = fst(pair);
                return 0 < w ? [w] : [];
            }));
        return indentTextPairs.map(
            firstArrow(flip(div)(indentUnit))
        );
    };

    // partialRecord :: [String] -> Dict
    const partialRecord = xs => {
        const [name, weightText, coverageText] = take(3)(
            xs.concat(['', '', ''])
        );
        return {
            name: name || '?',
            weight: parseFloat(weightText) || 1.0,
            coverage: parseFloat(coverageText) || 0.0,
            share: 0.0
        };
    };

    // tokenizeWith :: String -> String -> [String]
    const tokenizeWith = delimiter =>
        // A sequence of trimmed tokens obtained by
        // splitting s on the supplied delimiter.
        s => s.split(delimiter).map(x => x.trim());

    // TREE SERIALIZED TO OUTLINE -------------------------

    // indentedLinesFromTree :: (String -> a -> String) ->
    // String -> Tree a -> [String]
    const indentedLinesFromTree = showRoot =>
        strTab => tree => {
            const go = indent =>
                node => [showRoot(indent)(node.root)]
                .concat(node.nest.flatMap(go(strTab + indent)));
            return go('')(tree);
        };

    // showN :: Int -> Float -> String
    const showN = p =>
        n => justifyRight(7)(' ')(n.toFixed(p));

    // showCoverage :: String -> String -> Dict -> String
    const showCoverage = delimiter =>
        indent => x => tabulation(delimiter)(
            [indent + x.name, showN(0)(x.weight)]
            .concat([x.coverage, x.share].map(showN(4)))
        );

    // tabulation :: String -> [String] -> String
    const tabulation = delimiter =>
        // Up to 4 tokens drawn from the argument list,
        // as a single string with fixed left-justified
        // white-space widths, between delimiters.
        compose(
            intercalate(delimiter + ' '),
            zipWith(flip(justifyLeft)(' '))([31, 9, 9, 9])
        );

    // GENERIC AND REUSABLE FUNCTIONS ---------------------

    // Node :: a -> [Tree a] -> Tree a
    const Node = v => xs => ({
        type: 'Node',
        root: v, // any type of value (consistent across tree)
        nest: xs || []
    });

    // 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) =>
        x => fs.reduceRight((a, f) => f(a), x);

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

    // div :: Int -> Int -> Int
    const div = x => y => Math.floor(x / y);

    // either :: (a -> c) -> (b -> c) -> Either a b -> c
    const either = fl => fr => e =>
        'Either' === e.type ? (
            undefined !== e.Left ? (
                fl(e.Left)
            ) : fr(e.Right)
        ) : undefined;

    // Compose a function from a simple value to a tuple of
    // the separate outputs of two different functions

    // fanArrow (&&&) :: (a -> b) -> (a -> c) -> (a -> (b, c))
    const fanArrow = f => g => x => Tuple(f(x))(
        g(x)
    );

    // Lift a simple function to one which applies to a tuple,
    // transforming only the first item of the tuple

    // firstArrow :: (a -> b) -> ((a, c) -> (b, c))
    const firstArrow = f => xy => Tuple(f(xy[0]))(
        xy[1]
    );

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

    // fmapTree :: (a -> b) -> Tree a -> Tree b
    const fmapTree = f => tree => {
        const go = node => Node(f(node.root))(
            node.nest.map(go)
        );
        return go(tree);
    };

    // foldTree :: (a -> [b] -> b) -> Tree a -> b
    const foldTree = f => tree => {
        const go = node => f(node.root)(
            node.nest.map(go)
        );
        return go(tree);
    };

    // foldl1 :: (a -> a -> a) -> [a] -> a
    const foldl1 = f => xs =>
        1 < xs.length ? xs.slice(1)
        .reduce(uncurry(f), xs[0]) : xs[0];

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

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

    // insertDict :: String -> a -> Dict -> Dict
    const insertDict = k => v => dct =>
        Object.assign({}, dct, {
            [k]: v
        });

    // intercalate :: [a] -> [[a]] -> [a]
    // intercalate :: String -> [String] -> String
    const intercalate = sep =>
        xs => xs.join(sep);

    // isSpace :: Char -> Bool
    const isSpace = c => /\s/.test(c);

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

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

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

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

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

    // minimum :: Ord a => [a] -> a
    const minimum = xs =>
        0 < xs.length ? (
            foldl1(a => x => x < a ? x : a)(xs)
        ) : undefined;

    // root :: Tree a -> a
    const root = tree => tree.root;

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

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

    // span :: (a -> Bool) -> [a] -> ([a], [a])
    const span = p => xs => {
        const iLast = xs.length - 1;
        return splitAt(
            until(i => iLast < i || !p(xs[i]))(
                succ
            )(0)
        )(xs);
    };

    // splitAt :: Int -> [a] -> ([a], [a])
    const splitAt = n => xs =>
        Tuple(xs.slice(0, n))(
            xs.slice(n)
        );

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

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

    // uncurry :: (a -> b -> c) -> ((a, b) -> c)
    const uncurry = f =>
        (x, y) => f(x)(y);

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

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f => xs => ys =>
        xs.slice(
            0, Math.min(xs.length, ys.length)
        ).map((x, i) => f(x)(ys[i]));

    // SOURCE OUTLINE -----------------------------------------

    const strOutline = `NAME_HIERARCHY                  |WEIGHT  |COVERAGE  |
cleaning                        |        |          |
    house1                      |40      |          |
        bedrooms                |        |0.25      |
        bathrooms               |        |          |
            bathroom1           |        |0.5       |
            bathroom2           |        |          |
            outside_lavatory    |        |1         |
        attic                   |        |0.75      |
        kitchen                 |        |0.1       |
        living_rooms            |        |          |
            lounge              |        |          |
            dining_room         |        |          |
            conservatory        |        |          |
            playroom            |        |1         |
        basement                |        |          |
        garage                  |        |          |
        garden                  |        |0.8       |
    house2                      |60      |          |
        upstairs                |        |          |
            bedrooms            |        |          |
                suite_1         |        |          |
                suite_2         |        |          |
                bedroom_3       |        |          |
                bedroom_4       |        |          |
            bathroom            |        |          |
            toilet              |        |          |
            attics              |        |0.6       |
        groundfloor             |        |          |
            kitchen             |        |          |
            living_rooms        |        |          |
                lounge          |        |          |
                dining_room     |        |          |
                conservatory    |        |          |
                playroom        |        |          |
            wet_room_&_toilet   |        |          |
            garage              |        |          |
            garden              |        |0.9       |
            hot_tub_suite       |        |1         |
        basement                |        |          |
            cellars             |        |1         |
            wine_cellar         |        |1         |
            cinema              |        |0.75      |`;

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


Fusc sequence

Definitions:
The   '''fusc'''   integer sequence is defined as:
::*   fusc(0) = 0
::*   fusc(1) = 1
::*   for '''n'''>1,   the   '''n'''th   term is defined as:
::::*   if   '''n'''   is       even;     fusc(n) = fusc(n/2)
::::*   if   '''n'''   is   odd;     fusc(n) = fusc((n-1)/2)   +   fusc((n+1)/2)

Note that MathWorld's definition starts with unity, not zero.   This task will be using the OEIS' version   (above).

;An observation:
:::::*   fusc(A) = fusc(B)

where   '''A'''   is some non-negative integer expressed in binary,   and
where   '''B'''   is the binary value of   '''A'''   reversed.

Fusc numbers are also known as:
::*   fusc function   (named by Dijkstra, 1982)
::*   Stern's Diatomic series   (although it starts with unity, not zero)
::*   Stern-Brocot sequence   (although it starts with unity, not zero)

;Task:
::*   show the first   '''61'''   fusc numbers (starting at zero) in a horizontal format.
::*   show the fusc number (and its index) whose length is greater than any previous fusc number length.
::::*   (the length is the number of decimal digits when the fusc number is expressed in base ten.)
::*   show all numbers with commas   (if appropriate).
::*   show all output here.

;Related task:
::*   RosettaCode Stern-Brocot sequence

;Also see:
::*   the MathWorld entry:   Stern's Diatomic Series.
::*   the OEIS      entry:   A2487.

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

    // ---------------------- FUSC -----------------------

    // fusc :: Int -> Int
    const fusc = i => {
        const go = n =>
            0 === n ? [
                1, 0
            ] : (() => {
                const [x, y] = go(Math.floor(n / 2));

                return 0 === n % 2 ? (
                    [x + y, y]
                ) : [x, x + y];
            })();

        return 1 > i ? (
            0
        ) : go(i - 1)[0];
    };

    // ---------------------- TEST -----------------------
    const main = () => {
        const terms = enumFromTo(0)(60).map(fusc);

        return [
                "First 61 terms:",
                `[${terms.join(",")}]`,
                "",
                "(Index, Value):",
                firstWidths(5).reduce(
                    (a, x) => [x.slice(1), ...a],
                    []
                )
                .map(([i, x]) => `(${i}, ${x})`)
                .join("\n")
            ]
            .join("\n");
    };

    // firstWidths :: Int -> [(Int, Int)]
    const firstWidths = n => {
        const nxtWidth = xs => {
            const
                fi = fanArrow(fusc)(x => x),
                [w, i] = xs[0],
                [x, j] = Array.from(
                    until(
                        v => w <= `${v[0]}`.length
                    )(
                        v => fi(1 + v[1])
                    )(fi(i))
                );

            return [
                [1 + w, j, x],
                ...xs
            ];
        };

        return until(x => n < x[0][0])(
            nxtWidth
        )([
            [2, 0, 0]
        ]);
    };

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

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

    // fanArrow (&&&) ::
    // (a -> b) -> (a -> c) -> (a -> (b, c))
    const fanArrow = f =>
        // A combined function, given f and g,
        // from x to a tuple of (f(x), g(x))
        // ((,) . f <*> g)
        g => x => [f(x), g(x)];

    // until :: (a -> Bool) -> (a -> a) -> a -> a
    const until = p =>
        // The value resulting from successive applications
        // of f to f(x), starting with a seed value x,
        // and terminating when the result returns true
        // for the predicate p.
        f => {
            const go = x =>
                p(x) ? x : go(f(x));

            return go;
        };

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


Gaussian elimination

Solve   '''Ax=b'''   using Gaussian elimination then backwards substitution.

'''A'''   being an   '''n''' by '''n'''   matrix.

Also,   '''x''' and '''b'''   are   '''n''' by '''1'''   vectors.

To improve accuracy, please use partial pivoting and scaling.

;See also:
:*   the Wikipedia entry:   Gaussian elimination

Solution:
// Lower Upper Solver
function lusolve(A, b, update) {
	var lu = ludcmp(A, update)
	if (lu === undefined) return // Singular Matrix!
	return lubksb(lu, b, update)
}

// Lower Upper Decomposition
function ludcmp(A, update) {
	// A is a matrix that we want to decompose into Lower and Upper matrices.
	var d = true
	var n = A.length
	var idx = new Array(n) // Output vector with row permutations from partial pivoting
	var vv = new Array(n)  // Scaling information

	for (var i=0; i<n; i++) {
		var max = 0
		for (var j=0; j<n; j++) {
			var temp = Math.abs(A[i][j])
			if (temp > max) max = temp
		}
		if (max == 0) return // Singular Matrix!
		vv[i] = 1 / max // Scaling
	}

	if (!update) { // make a copy of A
		var Acpy = new Array(n)
		for (var i=0; i<n; i++) {
			var Ai = A[i]
			Acpyi = new Array(Ai.length)
			for (j=0; j<Ai.length; j+=1) Acpyi[j] = Ai[j]
			Acpy[i] = Acpyi
		}
		A = Acpy
	}

	var tiny = 1e-20 // in case pivot element is zero
	for (var i=0; ; i++) {
		for (var j=0; j<i; j++) {
			var sum = A[j][i]
			for (var k=0; k<j; k++) sum -= A[j][k] * A[k][i];
			A[j][i] = sum
		}
		var jmax = 0
		var max = 0;
		for (var j=i; j<n; j++) {
			var sum = A[j][i]
			for (var k=0; k<i; k++) sum -= A[j][k] * A[k][i];
			A[j][i] = sum
			var temp = vv[j] * Math.abs(sum)
			if (temp >= max) {
				max = temp
				jmax = j
			}
		}
		if (i <= jmax) {
			for (var j=0; j<n; j++) {
				var temp = A[jmax][j]
				A[jmax][j] = A[i][j]
				A[i][j] = temp
			}
			d = !d;
			vv[jmax] = vv[i]
		}
		idx[i] = jmax;
		if (i == n-1) break;
		var temp = A[i][i]
		if (temp == 0) A[i][i] = temp = tiny
		temp = 1 / temp
		for (var j=i+1; j<n; j++) A[j][i] *= temp
	}
	return {A:A, idx:idx, d:d}
}

// Lower Upper Back Substitution
function lubksb(lu, b, update) {
	// solves the set of n linear equations A*x = b.
	// lu is the object containing A, idx and d as determined by the routine ludcmp.
	var A = lu.A
	var idx = lu.idx
	var n = idx.length

	if (!update) { // make a copy of b
		var bcpy = new Array(n)
		for (var i=0; i<b.length; i+=1) bcpy[i] = b[i]
		b = bcpy
	}

	for (var ii=-1, i=0; i<n; i++) {
		var ix = idx[i]
		var sum = b[ix]
		b[ix] = b[i]
		if (ii > -1)
			for (var j=ii; j<i; j++) sum -= A[i][j] * b[j]
		else if (sum)
			ii = i
		b[i] = sum
	}
	for (var i=n-1; i>=0; i--) {
		var sum = b[i]
		for (var j=i+1; j<n; j++) sum -= A[i][j] * b[j]
		b[i] = sum / A[i][i]
	}
	return b // solution vector x
}

document.write(
	lusolve(
		[
			[1.00, 0.00, 0.00,  0.00,  0.00,   0.00],
                	[1.00, 0.63, 0.39,  0.25,  0.16,   0.10],
                	[1.00, 1.26, 1.58,  1.98,  2.49,   3.13],
                	[1.00, 1.88, 3.55,  6.70, 12.62,  23.80],
                	[1.00, 2.51, 6.32, 15.88, 39.90, 100.28],
                	[1.00, 3.14, 9.87, 31.01, 97.41, 306.02]
		],
    		[-0.01, 0.61, 0.91,  0.99,  0.60,   0.02]
	)
)


Generate Chess960 starting position

Bobby Fischer.  Unlike other variants of the game, Chess960 does not require a different material, but instead relies on a random initial position, with a few constraints:

* as in the standard chess game, all eight white pawns must be placed on the second rank.
* White pieces must stand on the first rank as in the standard game, in random column order but with the two following constraints:
** the bishops must be placed on opposite color squares (i.e. they must be an odd number of spaces apart or there must be an even number of spaces between them)
** the King must be between two rooks (with any number of other pieces between them all)
* Black pawns and pieces must be placed respectively on the seventh and eighth ranks, mirroring the white pawns and pieces, just as in the standard game.  (That is, their positions are not independently randomized.)

With those constraints there are '''960''' possible starting positions, thus the name of the variant.

;Task:
The purpose of this task is to write a program that can randomly generate any one of the 960 Chess960 initial positions. You will show the result as the first rank displayed with Chess symbols in Unicode:  or with the letters '''K'''ing '''Q'''ueen '''R'''ook '''B'''ishop k'''N'''ight.

Solution:
function ch960startPos() {
  var rank = new Array(8),
      // randomizer (our die)
      d = function(num) { return Math.floor(Math.random() * ++num) },
      emptySquares = function() {
        var arr = [];
        for (var i = 0; i < 8; i++) if (rank[i] == undefined) arr.push(i);
        return arr;
      };
  // place one bishop on any black square
  rank[d(2) * 2] = "♗";
  // place the other bishop on any white square
  rank[d(2) * 2 + 1] = "♗";
  // place the queen on any empty square
  rank[emptySquares()[d(5)]] = "♕";
  // place one knight on any empty square
  rank[emptySquares()[d(4)]] = "♘";
  // place the other knight on any empty square
  rank[emptySquares()[d(3)]] = "♘";
  // place the rooks and the king on the squares left, king in the middle
  for (var x = 1; x <= 3; x++) rank[emptySquares()[0]] = x==2 ? "♔" : "♖";
  return rank;
}

// testing (10 times)
for (var x = 1; x <= 10; x++) console.log(ch960startPos().join(" | "));


Generate random chess position

Generate a random chess position in FEN format.

The position does not have to be realistic or even balanced,  but it must comply to the following rules:
:* there is one and only one king of each color  (one black king and one white king);
:* the kings must not be placed on adjacent squares;
:* there can not be any pawn in the promotion square  (no white pawn in the eighth rank, and no black pawn in the first rank);
:* including the kings, up to 32 pieces of either color can be placed.
:* There is no requirement for material balance between sides.
:* The picking of pieces does not have to comply to a regular chess set --- there can be five knights, twenty rooks, whatever ... as long as the total number of pieces do not exceed thirty-two.
:* it is white's turn.
:* It's assumed that both sides have lost castling rights and that there is no possibility for   ''en passant''   (the FEN should thus end in w - - 0 1).

No requirement is made regarding the probability distribution of your method, but your program should be able to span a reasonably representative sample of all possible positions.  For instance, programs that would always generate positions with say five pieces on the board, or with kings on a corner, would not be considered truly random.

Solution:
Array.prototype.shuffle = function() {
  for (let i = this.length - 1; i > 0; i--) {
    let j = Math.floor(Math.random() * (i + 1));
    [this[i], this[j]] = [this[j], this[i]];
  }
}

function randomFEN() {

  let board = [];
  for (let x = 0; x < 8; x++) board.push('. . . . . . . .'.split(' '));

  function getRandPos() {
    return [Math.floor(Math.random() * 8), Math.floor(Math.random() * 8)];
  }

  function isOccupied(pos) {
    return board[pos[0]][pos[1]] != '.';
  }

  function isAdjacent(pos1, pos2) {
    if (pos1[0] == pos2[0] || pos1[0] == pos2[0]-1 || pos1[0] == pos2[0]+1)
    if (pos1[1] == pos2[1] || pos1[1] == pos2[1]-1 || pos1[1] == pos2[1]+1)
      return true;
    return false;
  }

  // place kings
  let wk, bk;
  do { wk = getRandPos(); bk = getRandPos(); }
  while (isAdjacent(wk, bk));
  board[wk[0]][wk[1]] = 'K';
  board[bk[0]][bk[1]] = 'k';

  // get peaces
  let peaces = [];
  let names = 'PRNBQ';
  function pick() {
    for (x = 1; x < Math.floor(Math.random() * 32); x++)
      peaces.push(names[Math.floor(Math.random() * names.length)]);
  }
  pick();
  names = names.toLowerCase();
  pick();
  peaces.shuffle();

  // place peaces
  while (peaces.length > 0) {
    let p = peaces.shift(), pos;
    // paws: cannot be placed in bottom or top row
    if (p == 'p' || p == 'P')
      do { pos = getRandPos() }
      while (isOccupied(pos) || pos[0] == 0 || pos[0] == 7);
    // everything else
    else do { pos = getRandPos(); } while (isOccupied(pos));
    board[pos[0]][pos[1]] = p;
  }

  // write FEN
  let fen = [];
  for (x = 0; x < board.length; x++) {
    let str ='', buf = 0;
    for (let y = 0; y < board[x].length; y++)
      if (board[x][y] == '.') buf++;
      else {
        if (buf > 0) { str += buf; buf = 0; }
        str += board[x][y];
      }
    if (buf > 0) str += buf;
    fen.push(str);
  }
  fen = fen.join('/') + ' w - - 0 1';
  console.table(board); // for demonstrating purpose
  return fen;
}

// example
console.log(randomFEN());


Generator/Exponential

A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided.

Generators are often built on top of coroutines or objects so that the internal state of the object is handled "naturally".

Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.

;Task:
* Create a function that returns a generation of the m'th powers of the positive integers starting from zero, in order, and without obvious or simple upper limit. (Any upper limit to the generator should not be stated in the source but should be down to factors such as the languages natural integer size limit or computational time/size).
* Use it to create a generator of:
:::*   Squares.
:::*   Cubes.
* Create a new generator that filters all cubes from the generator of squares.
* Drop the first 20 values from this last generator of filtered results, and then show the next 10 values.

Note that this task ''requires'' the use of generators in the calculation of the result.

;Also see:
* Generator

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

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

        // powers :: Gen [Int]
        const powers = n =>
            fmapGen(
                x => Math.pow(x, n),
                enumFrom(0)
            );

        // xs :: [Int]
        const xs = take(10, drop(20,
            differenceGen(
                powers(2),
                powers(3)
            )
        ));

        console.log(xs);
        // -> [529,576,625,676,784,841,900,961,1024,1089]
    };

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

    // differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
    function* differenceGen(ga, gb) {
        // All values of generator stream a except any
        // already seen in generator stream b.
        const
            stream = zipGen(ga, gb),
            sb = new Set([]);
        let xy = take(1, stream);
        while (0 < xy.length) {
            const [x, y] = Array.from(xy[0]);
            sb.add(y);
            if (!sb.has(x)) yield x;
            xy = take(1, stream);
        }
    };

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

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

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

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

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

    // snd :: (a, b) -> b
    const snd = tpl => tpl[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];
        }));

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

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

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


Gotchas

Definition
In programming, a '''gotcha''' is a valid construct in a system, program or programming language that works as documented but is counter-intuitive and almost invites mistakes because it is both easy to invoke and unexpected or unreasonable in its outcome.

;Task
Give an example or examples of common gotchas in your programming language and what, if anything, can be done to defend against it or them without using special tools.

Solution:
===Equality Comparisons===
The normal equality operator (==) is very infamous for its strange results when comparing two variables of different types. Javascript has a complicated set of type coercion rules, which was intended to simplify comparisons between integers and floating point, integers and their string representations (e.g. 2 == '2'), etc. However, this is often frustrating for the programmer when they want to know if two variables are equal and also have the same data type. The strict equality (===) operator will always return false if the variables are of two different types. Many new programmers are taught to always use === to avoid subtle bugs in their programs.


Gray code

Karnaugh maps in order from left to right or top to bottom.
Create functions to encode a number to and decode a number from Gray code.

Display the normal binary representations, Gray code representations, and decoded Gray code values for all 5-bit binary numbers (0-31 inclusive, leading 0's not necessary).

There are many possible Gray codes. The following encodes what is called "binary reflected Gray code."

Encoding (MSB is bit 0, b is binary, g is Gray code):

if b[i-1] = 1
   g[i] = not b[i]
else
   g[i] = b[i]

Or:

g = b xor (b logically right shifted 1 time)

Decoding (MSB is bit 0, b is binary, g is Gray code):

b[0] = g[0]

for other bits:
b[i] = g[i] xor b[i-1]

;Reference
* Converting Between Gray and Binary Codes. It includes step-by-step animations.

Solution:
import printf from 'printf' // Module must be installed with npm first
import * as gray from './gray-code.js'

console.log(
    'Number\t' +
    'Binary\t' +
    'Gray Code\t' +
    'Decoded Gray Code'
)

for (let number = 0; number < 32; number++) {
    const grayCode = gray.encode(number)
    const decodedGrayCode = gray.decode(grayCode)

    console.log(printf(
        '%2d\t%05d\t%05d\t\t%2d',
        number,
        number.toString(2),
        grayCode.toString(2),
        decodedGrayCode
    ))
}


Greatest subsequential sum

Given a sequence of integers, find a continuous subsequence which maximizes the sum of its elements, that is, the elements of no other single subsequence add up to a value larger than this one.

An empty subsequence is considered to have the sum of   '''0''';   thus if all elements are negative, the result must be the empty sequence.

Solution:
function MaximumSubsequence(population) {
    var maxValue = 0;
    var subsequence = [];

    for (var i = 0, len = population.length; i < len; i++) {
        for (var j = i; j <= len; j++) {
            var subsequence = population.slice(i, j);
            var value = sumValues(subsequence);
            if (value > maxValue) {
                maxValue = value;
                greatest = subsequence;
            };
        }
    }

    return greatest;
}

function sumValues(arr) {
    var result = 0;
    for (var i = 0, len = arr.length; i < len; i++) {
        result += arr[i];
    }
    return result;
}


Greatest subsequential sum

Solution:
(() => {

    // maxSubseq :: [Int] -> (Int, [Int])
    const maxSubseq = xs =>
        snd(xs.reduce((tpl, x) => {
            const [m1, m2] = Array.from(fst(tpl)),
                high = max(
                    Tuple(0, []),
                    Tuple(m1 + x, m2.concat(x))
                );
            return Tuple(high, max(snd(tpl), high));
        }, Tuple(Tuple(0, []), Tuple(0, []))));

    // TEST -----------------------------------------------
    // main :: IO ()
    const main = () => {
        const mx = maxSubseq([-1, -2, 3, 5, 6, -2, -1, 4, -4, 2, -1]);
        showLog(snd(mx), fst(mx))
    }
    // [3,5,6,-2,-1,4] -> 15

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

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

    // gt :: Ord a => a -> a -> Bool
    const gt = (x, y) =>
        'Tuple' === x.type ? (
            x[0] > y[0]
        ) : (x > y);

    // max :: Ord a => a -> a -> a
    const max = (a, b) => gt(b, a) ? b : a;

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

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

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

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


Greyscale bars/Display

The task is to display a series of vertical greyscale bars (contrast bars) with a sufficient number of bars to span the entire width of the display.

For the top quarter of the display, the left hand bar should be black, and we then incrementally step through six shades of grey until we have a white bar on the right hand side of the display. (This gives a total of 8 bars)

For the second quarter down, we start with white and step down through 14 shades of gray, getting darker until we have black on the right hand side of the display. (This gives a total of 16 bars).

Halfway down the display, we start with black, and produce 32 bars, ending in white, and for the last quarter, we start with white and step through 62 shades of grey, before finally arriving at black in the bottom right hand corner, producing a total of 64 bars for the bottom quarter.

Solution:
<html><body>
<script type="text/javascript">
var width = 640; var height = 400;
var c = document.createElement("canvas");
c.setAttribute('id',    'myCanvas');
c.setAttribute('style', 'border:1px solid black;');
c.setAttribute('width',  width);
c.setAttribute('height', height);
document.body.appendChild(c);
var ctx = document.getElementById('myCanvas').getContext("2d");

var columnCount = 8;    // number of columns
var rowCount    = 4;    // number of rows
var direction   = 1;    // 1 = from left to right, 0 = from right to left
var blackLeft   = 1;    // black is left: 1 = true, 0 = false
for(var j = 0; j < rowCount; j++){
    for(var i = 0; i < columnCount; i++){
        ctx.fillStyle = 'rgba(0,0,0,'+ (blackLeft-(1/(columnCount-1)*i))*direction +')';
        ctx.fillRect(
            (width/columnCount)*i,(height/rowCount)*j,
            (width/columnCount),(height/rowCount)
            );
        }
    columnCount *= 2;
    direction *= -1;
    blackLeft = blackLeft ? 0 : 1;
    }
</script>
</body></html>


Hailstone sequence

The Hailstone sequence of numbers can be generated from a starting positive integer,   n   by:
*   If   n   is     '''1'''     then the sequence ends.
*   If   n   is   '''even''' then the next   n   of the sequence    = n/2
*   If   n   is   '''odd'''    then the next   n   of the sequence    = (3 * n) + 1

The (unproven) Collatz conjecture is that the hailstone sequence for any starting number always terminates.

This sequence was named by Lothar Collatz in 1937   (or possibly in 1939),   and is also known as (the):
:::*   hailstone sequence,   hailstone numbers
:::*   3x + 2 mapping,   3n + 1 problem
:::*   Collatz sequence
:::*   Hasse's algorithm
:::*   Kakutani's problem
:::*   Syracuse algorithm,   Syracuse problem
:::*   Thwaites conjecture
:::*   Ulam's problem

The hailstone sequence is also known as   ''hailstone numbers''   (because the values are usually subject to multiple descents and ascents like hailstones in a cloud).

;Task:
# Create a routine to generate the hailstone sequence for a number.
# Use the routine to show that the hailstone sequence for the number 27 has 112 elements starting with 27, 82, 41, 124 and ending with 8, 4, 2, 1
# Show the number less than 100,000 which has the longest hailstone sequence together with that sequence's length.    (But don't show the actual sequence!)

;See also:
*   xkcd (humourous).
*   The Notorious Collatz conjecture Terence Tao, UCLA (Presentation, pdf).
*   The Simplest Math Problem No One Can Solve Veritasium (video, sponsored).

Solution:
function hailstone (n) {
    var seq = [n];
    while (n > 1) {
        n = n % 2 ? 3 * n + 1 : n / 2;
        seq.push(n);
    }
    return seq;
}

// task 2: verify the sequence for n = 27
var h = hailstone(27), hLen = h.length;
print("sequence 27 is (" + h.slice(0, 4).join(", ") + " ... "
    + h.slice(hLen - 4, hLen).join(", ") + "). length: " + hLen);

// task 3: find the longest sequence for n < 100000
for (var n, max = 0, i = 100000; --i;) {
    var seq = hailstone(i), sLen = seq.length;
    if (sLen > max) {
        n = i;
        max = sLen;
    }
}
print("longest sequence: " + max + " numbers for starting point " + n);


Harshad or Niven series

The Harshad or Niven numbers are positive integers >= 1 that are divisible by the sum of their digits.

For example,   '''42'''   is a Harshad number as   '''42'''   is divisible by   ('''4''' + '''2''')   without remainder.

Assume that the series is defined as the numbers in increasing order.

;Task:
The task is to create a function/method/procedure to generate successive members of the Harshad sequence.

Use it to:
::*   list the first '''20''' members of the sequence,   and
::*   list the first Harshad number greater than '''1000'''.

Show your output here.

;Related task
:*   Increasing gaps between consecutive Niven numbers

;See also
*    OEIS: A005349

Solution:
function isHarshad(n) {
    var s = 0;
    var n_str = new String(n);
    for (var i = 0; i < n_str.length; ++i) {
        s += parseInt(n_str.charAt(i));
    }
    return n % s === 0;
}

var count = 0;
var harshads = [];

for (var n = 1; count < 20; ++n) {
    if (isHarshad(n)) {
        count++;
        harshads.push(n);
    }
}

console.log(harshads.join(" "));

var h = 1000;
while (!isHarshad(++h));
console.log(h);


Hash join

{| class="wikitable"
|-
! Input
! Output
|-
|

{| style="border:none; border-collapse:collapse;"
|-
| style="border:none" | ''A'' =
| style="border:none" |

{| class="wikitable"
|-
! Age !! Name
|-
| 27 || Jonah
|-
| 18 || Alan
|-
| 28 || Glory
|-
| 18 || Popeye
|-
| 28 || Alan
|}

| style="border:none; padding-left:1.5em;" rowspan="2" |
| style="border:none" | ''B'' =
| style="border:none" |

{| class="wikitable"
|-
! Character !! Nemesis
|-
| Jonah || Whales
|-
| Jonah || Spiders
|-
| Alan || Ghosts
|-
| Alan || Zombies
|-
| Glory || Buffy
|}

|-
| style="border:none" | ''jA'' =
| style="border:none" | Name (i.e. column 1)

| style="border:none" | ''jB'' =
| style="border:none" | Character (i.e. column 0)
|}

|

{| class="wikitable" style="margin-left:1em"
|-
! A.Age !! A.Name !! B.Character !! B.Nemesis
|-
| 27 || Jonah || Jonah || Whales
|-
| 27 || Jonah || Jonah || Spiders
|-
| 18 || Alan || Alan || Ghosts
|-
| 18 || Alan || Alan || Zombies
|-
| 28 || Glory || Glory || Buffy
|-
| 28 || Alan || Alan || Ghosts
|-
| 28 || Alan || Alan || Zombies
|}

|}

The order of the rows in the output table is not significant.
If you're using numerically indexed arrays to represent table rows (rather than referring to columns by name), you could represent the output rows in the form [[27, "Jonah"], ["Jonah", "Whales"]].

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

    // hashJoin :: [Dict] -> [Dict] -> String -> [Dict]
    let hashJoin = (tblA, tblB, strJoin) => {

        let [jA, jB] = strJoin.split('='),
            M = tblB.reduce((a, x) => {
                let id = x[jB];
                return (
                    a[id] ? a[id].push(x) : a[id] = [x],
                    a
                );
            }, {});

        return tblA.reduce((a, x) => {
            let match = M[x[jA]];
            return match ? (
                a.concat(match.map(row => dictConcat(x, row)))
            ) : a;
        }, []);
    },

    // dictConcat :: Dict -> Dict -> Dict
    dictConcat = (dctA, dctB) => {
        let ok = Object.keys;
        return ok(dctB).reduce(
            (a, k) => (a['B_' + k] = dctB[k]) && a,
            ok(dctA).reduce(
                (a, k) => (a['A_' + k] = dctA[k]) && a, {}
            )
        );
    };

    // TEST
    let lstA = [
        { age: 27, name: 'Jonah' },
        { age: 18, name: 'Alan' },
        { age: 28, name: 'Glory' },
        { age: 18, name: 'Popeye' },
        { age: 28, name: 'Alan' }
    ],
    lstB = [
        { character: 'Jonah', nemesis: 'Whales' },
        { character: 'Jonah', nemesis: 'Spiders' },
        { character: 'Alan', nemesis: 'Ghosts' },
        { character:'Alan', nemesis: 'Zombies' },
        { character: 'Glory', nemesis: 'Buffy' },
        { character: 'Bob', nemesis: 'foo' }
    ];

    return hashJoin(lstA, lstB, 'name=character');

})();


Haversine formula

{{Wikipedia}}

The '''haversine formula''' is an equation important in navigation, giving great-circle distances between two points on a sphere from their longitudes and latitudes.

It is a special case of a more general formula  in spherical trigonometry, the '''law of haversines''', relating the sides and angles of spherical "triangles".

;Task:
Implement a great-circle distance function, or use a library function,
to show the great-circle distance between:
* Nashville International Airport (BNA)   in Nashville, TN, USA,   which is:
    '''N''' 36deg7.2',   '''W''' 86deg40.2'     (36.12,   -86.67)           -and-
* Los Angeles International Airport (LAX)  in Los Angeles, CA, USA,   which is:
    '''N''' 33deg56.4',  '''W''' 118deg24.0'    (33.94,  -118.40)

User Kaimbridge clarified on the Talk page:

 -- 6371.0 km is the authalic radius based on/extracted from surface area;
 -- 6372.8 km is an approximation of the radius of the average circumference
    (i.e., the average great-elliptic or great-circle radius), where the
     boundaries are the meridian (6367.45 km) and the equator (6378.14 km).

Using either of these values results, of course, in differing distances:

 6371.0 km -> 2886.44444283798329974715782394574671655 km;
 6372.8 km -> 2887.25995060711033944886005029688505340 km;
 (results extended for accuracy check:  Given that the radii are only
  approximations anyways, .01'  1.0621333 km and .001"  .00177 km,
  practical precision required is certainly no greater than about
  .0000001----i.e., .1 mm!)

As distances are segments of great circles/circumferences, it is
recommended that the latter value (r = 6372.8 km) be used (which
most of the given solutions have already adopted, anyways).

Most of the examples below adopted Kaimbridge's recommended value of
6372.8 km for the earth radius.  However, the derivation of this
ellipsoidal quadratic mean radius
is wrong (the averaging over azimuth is biased).  When applying these
examples in real applications, it is better to use the
mean earth radius,
6371 km.  This value is recommended by the International Union of
Geodesy and Geophysics and it minimizes the RMS relative error between the
great circle and geodesic distance.

Solution:
function haversine() {
       var radians = Array.prototype.map.call(arguments, function(deg) { return deg/180.0 * Math.PI; });
       var lat1 = radians[0], lon1 = radians[1], lat2 = radians[2], lon2 = radians[3];
       var R = 6372.8; // km
       var dLat = lat2 - lat1;
       var dLon = lon2 - lon1;
       var a = Math.sin(dLat / 2) * Math.sin(dLat /2) + Math.sin(dLon / 2) * Math.sin(dLon /2) * Math.cos(lat1) * Math.cos(lat2);
       var c = 2 * Math.asin(Math.sqrt(a));
       return R * c;
}
console.log(haversine(36.12, -86.67, 33.94, -118.40));


Here document

A   ''here document''    (or "heredoc")   is a way of specifying a text block, preserving the line breaks, indentation and other whitespace within the text.

Depending on the language being used, a   ''here document''   is constructed using a command followed by "<<" (or some other symbol) followed by a token string.

The text block will then start on the next line, and will be followed by the chosen token at the beginning of the following line, which is used to mark the end of the text block.

;Task:
Demonstrate the use of   ''here documents''   within the language.

;Related task:
*   [[Documentation]]

Solution:
const myVar = 123;
const tempLit = `Here is some
multi-line string. And here is
the value of "myVar": ${myVar}
That's all.`;
console.log(tempLit)


Heronian triangles

Hero's formula for the area of a triangle given the length of its three sides    ''a'',   ''b'',   and   ''c''   is given by:

:::: A = \sqrt{s(s-a)(s-b)(s-c)},

where   ''s''   is half the perimeter of the triangle; that is,

:::: s=\frac{a+b+c}{2}.

'''Heronian triangles'''
are triangles whose sides ''and area'' are all integers.
: An example is the triangle with sides   '''3, 4, 5'''   whose area is   '''6'''   (and whose perimeter is   '''12''').

Note that any triangle whose sides are all an integer multiple of   '''3, 4, 5''';   such as   '''6, 8, 10,'''   will also be a Heronian triangle.

Define a '''Primitive Heronian triangle''' as a Heronian triangle where the greatest common divisor
of all three sides is   '''1'''   (unity).

This will exclude, for example, triangle   '''6, 8, 10.'''

;Task:
# Create a named function/method/procedure/... that implements Hero's formula.
# Use the function to generate all the ''primitive'' Heronian triangles with sides <= 200.
# Show the count of how many triangles are found.
# Order the triangles by first increasing area, then by increasing perimeter, then by increasing maximum side lengths
# Show the first ten ordered triangles in a table of sides, perimeter, and area.
# Show a similar ordered table for those triangles with area = 210

Show all output here.

'''Note''': when generating triangles it may help to restrict a <= b <= c

Solution:
window.onload = function(){
    var list = [];
    var j = 0;
    for(var c = 1; c <= 200; c++)
        for(var b = 1; b <= c; b++)
            for(var a = 1; a <= b; a++)
	        if(gcd(gcd(a, b), c) == 1 && isHeron(heronArea(a, b, c)))
		    list[j++] = new Array(a, b, c, a + b + c, heronArea(a, b, c));
    sort(list);
    document.write("
Primitive Heronian triangles with sides up to 200: " + list.length + "

First ten when ordered by increasing area, then perimeter:

Sides	Perimeter	Area
");
    for(var i = 0; i < 10; i++)
	document.write("
" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "	" + list[i][3] + "	" + list[i][4] + "
");
    document.write("

Area = 210

Sides	Perimeter	Area
");
    for(var i = 0; i < list.length; i++)
	if(list[i][4] == 210)
	    document.write("
" + list[i][0] + " x " + list[i][1] + " x " + list[i][2] + "	" + list[i][3] + "	" + list[i][4] + "
");
    function heronArea(a, b, c){
	var s = (a + b + c)/ 2;
	return Math.sqrt(s *(s -a)*(s - b)*(s - c));
    }
    function isHeron(h){
        return h % 1 == 0 && h > 0;
    }
    function gcd(a, b){
	var leftover = 1, dividend = a > b ? a : b, divisor = a > b ? b : a;
	while(leftover != 0){
	    leftover = dividend % divisor;
	    if(leftover > 0){
		dividend = divisor;
		divisor = leftover;
	    }
	}
	return divisor;
    }
    function sort(list){
	var swapped = true;
	var temp = [];
	while(swapped){
	    swapped = false;
	    for(var i = 1; i < list.length; i++){
		if(list[i][4] < list[i - 1][4] || list[i][4] == list[i - 1][4] && list[i][3] < list[i - 1][3]){
		    temp = list[i];
		    list[i] = list[i - 1];
		    list[i - 1] = temp;
		    swapped = true;
		}
	    }
	}
    }
}


Hofstadter-Conway $10,000 sequence

The definition of the sequence is colloquially described as:
*   Starting with the list [1,1],
*   Take the last number in the list so far: 1, I'll call it x.
*   Count forward x places from the beginning of the list to find the first number to add (1)
*   Count backward x places from the end of the list to find the second number to add (1)
*   Add the two indexed numbers from the list and the result becomes the next number in the list (1+1)
*   This would then produce [1,1,2] where 2 is the third element of the sequence.

Note that indexing for the description above starts from alternately the left and right ends of the list and starts from an index of ''one''.

A less wordy description of the sequence is:
    a(1)=a(2)=1
    a(n)=a(a(n-1))+a(n-a(n-1))

The sequence begins:
    1, 1, 2, 2, 3, 4, 4, 4, 5, ...

Interesting features of the sequence are that:
*   a(n)/n   tends to   0.5   as   n   grows towards infinity.
*   a(n)/n   where   n   is a power of   2   is   0.5
*   For   n>4   the maximal value of   a(n)/n   between successive powers of 2 decreases.

a(n) / n   for   n   in   1..256

The sequence is so named because John Conway offered a prize of $10,000 to the first person who could
find the first position,   p   in the sequence where
    |a(n)/n| < 0.55  for all  n > p
It was later found that Hofstadter had also done prior work on the sequence.

The 'prize' was won quite quickly by Dr. Colin L. Mallows who proved the properties of the sequence and allowed him to find the value of   n   (which is much smaller than the 3,173,375,556 quoted in the NYT article).

;Task:
#   Create a routine to generate members of the Hofstadter-Conway $10,000 sequence.
#   Use it to show the maxima of   a(n)/n   between successive powers of two up to   2**20
#   As a stretch goal:   compute the value of   n   that would have won the prize and confirm it is true for   n   up to 2**20

;Also see:
*   Conways Challenge Sequence, Mallows' own account.
*   Mathworld Article.

Solution:
var hofst_10k = function(n) {
	var memo = [1, 1];

	var a = function(n) {
		var result = memo[n-1];
		if (typeof result !== 'number') {
			result = a(a(n-1))+a(n-a(n-1));
			memo[n-1] = result;
		}
		return result;
	}
	return a;
}();

var maxima_between_twos = function(exp) {
	var current_max = 0;
	for(var i = Math.pow(2,exp)+1; i < Math.pow(2,exp+1); i += 1) {
		current_max = Math.max(current_max, hofst_10k(i)/i);
	}
	return current_max;
}

for(var i = 1; i <= 20; i += 1) {
	console.log("Maxima between 2^"+i+"-2^"+(i+1)+" is: "+maxima_between_twos(i)+"\n");
}


Hofstadter Figure-Figure sequences

These two sequences of positive integers are defined as:
:::: \begin{align}
R(1)&=1\ ;\ S(1)=2 \\
R(n)&=R(n-1)+S(n-1), \quad n>1.
\end{align}

The sequence S(n) is further defined as the sequence of positive integers '''''not''''' present in R(n).

Sequence R starts:
    1, 3, 7, 12, 18, ...
Sequence S starts:
    2, 4, 5, 6, 8, ...

;Task:
# Create two functions named '''ffr''' and '''ffs''' that when given '''n''' return '''R(n)''' or '''S(n)''' respectively.(Note that R(1) = 1 and S(1) = 2 to avoid off-by-one errors).
# No maximum value for '''n''' should be assumed.
# Calculate and show that the first ten values of '''R''' are: 1, 3, 7, 12, 18, 26, 35, 45, 56, and 69
# Calculate and show that the first 40 values of '''ffr''' plus the first 960 values of '''ffs''' include all the integers from 1 to 1000 exactly once.

;References:
* Sloane's A005228 and A030124.
* Wolfram MathWorld
* Wikipedia: Hofstadter Figure-Figure sequences.

Solution:
var R = [null, 1];
var S = [null, 2];

var extend_sequences = function (n) {
	var current = Math.max(R[R.length-1],S[S.length-1]);
	var i;
	while (R.length <= n || S.length <= n) {
		i = Math.min(R.length, S.length) - 1;
		current += 1;
		if (current === R[i] + S[i]) {
			R.push(current);
		} else {
			S.push(current);
		}
	}
}

var ffr = function(n) {
	extend_sequences(n);
	return R[n];
};

var ffs = function(n) {
	extend_sequences(n);
	return S[n];
};

for (var i = 1; i <=10; i += 1) {
   console.log('R('+ i +') = ' + ffr(i));
}

var int_array = [];

for (var i = 1; i <= 40; i += 1) {
	int_array.push(ffr(i));
}
for (var i = 1; i <= 960; i += 1) {
	int_array.push(ffs(i));
}

int_array.sort(function(a,b){return a-b;});

for (var i = 1; i <= 1000; i += 1) {
	if (int_array[i-1] !== i) {
		throw "Something's wrong!"
	} else { console.log("1000 integer check ok."); }
}


Hofstadter Q sequence

The Hofstadter Q sequence is defined as:
:: \begin{align}
Q(1)&=Q(2)=1, \\
Q(n)&=Q\big(n-Q(n-1)\big)+Q\big(n-Q(n-2)\big), \quad n>2.
\end{align}

It is defined like the [[Fibonacci sequence]], but whereas the next term in the Fibonacci sequence is the sum of the previous two terms, in the Q sequence the previous two terms tell you how far to go back in the Q sequence to find the two numbers to sum to make the next term of the sequence.

;Task:
* Confirm and display that the first ten terms of the sequence are: 1, 1, 2, 3, 3, 4, 5, 5, 6, and 6
* Confirm and display that the 1000th term is:   502

;Optional extra credit
* Count and display how many times a member of the sequence is less than its preceding term for terms up to and including the 100,000th term.
* Ensure that the extra credit solution   ''safely''   handles being initially asked for an '''n'''th term where   '''n'''   is large.
(This point is to ensure that caching and/or recursion limits, if it is a concern, is correctly handled).

Solution:
var hofstadterQ = function() {
   var memo = [1,1,1];
   var Q    = function (n) {
      var result = memo[n];
      if (typeof result !== 'number') {
         result  = Q(n - Q(n-1)) + Q(n - Q(n-2));
         memo[n] = result;
      }
      return result;
   };
   return Q;
}();

for (var i = 1; i <=10; i += 1) {
   console.log('Q('+ i +') = ' + hofstadterQ(i));
}

console.log('Q(1000) = ' + hofstadterQ(1000));


Horner's rule for polynomial evaluation

A fast scheme for evaluating a polynomial such as:
: -19+7x-4x^2+6x^3\,
when
: x=3\;.
is to arrange the computation as follows:
: ((((0) x + 6) x + (-4)) x + 7) x + (-19)\;
And compute the result from the innermost brackets outwards as in this pseudocode:
 coefficients ''':=''' [-19, 7, -4, 6] ''# list coefficients of all x^0..x^n in order''
 x ''':=''' 3
 accumulator ''':=''' 0
 '''for''' i '''in''' ''length''(coefficients) '''downto''' 1 '''do'''
     ''# Assumes 1-based indexing for arrays''
     accumulator ''':=''' ( accumulator * x ) + coefficients[i]
 '''done'''
 ''# accumulator now has the answer''

'''Task Description'''
:Create a routine that takes a list of coefficients of a polynomial in order of increasing powers of x; together with a value of x to compute its value at, and return the value of the polynomial at that value using Horner's rule.

Cf. [[Formal power series]]

Solution:
function horner(coeffs, x) {
    return coeffs.reduceRight( function(acc, coeff) { return(acc * x + coeff) }, 0);
}
console.log(horner([-19,7,-4,6],3));  // ==> 128


Identity matrix

Build an   identity matrix   of a size known at run-time.

An ''identity matrix'' is a square matrix of size '''''n'' x ''n''''',
where the diagonal elements are all '''1'''s (ones),
and all the other elements are all '''0'''s (zeroes).

I_n = \begin{bmatrix}
  1      & 0      & 0      & \cdots & 0      \\
  0      & 1      & 0      & \cdots & 0      \\
  0      & 0      & 1      & \cdots & 0      \\
  \vdots & \vdots & \vdots & \ddots & \vdots \\
  0      & 0      & 0      & \cdots & 1      \\
\end{bmatrix}

;Related tasks:
*   [[Spiral matrix]]
*   [[Zig-zag matrix]]
*   [[Ulam_spiral_(for_primes)]]

Solution:
(() => {

    // identityMatrix :: Int -> [[Int]]
    const identityMatrix = n =>
        Array.from({
            length: n
        }, (_, i) => Array.from({
            length: n
        }, (_, j) => i !== j ? 0 : 1));

    // ----------------------- TEST ------------------------
    return identityMatrix(5)
        .map(JSON.stringify)
        .join('\n');
})();


Include a file

Demonstrate the language's ability to include source code from other files.

;See Also

* [[Compiler/Simple file inclusion pre processor]]

Solution:
var s = document.createElement('script');
s.type = 'application/javascript';

// path to the desired file
s.src = 'http://code.jquery.com/jquery-1.6.2.js';
document.body.appendChild(s);


Intersecting number wheels

A number wheel has:
* A ''name'' which is an uppercase letter.
* A set of ordered ''values'' which are either ''numbers'' or ''names''.

A ''number'' is generated/yielded from a named wheel by:
:1. Starting at the first value of the named wheel and advancing through subsequent values and wrapping around to the first value to form a "wheel":
::1.a If the value is a number, yield it.
::1.b If the value is a name, yield the next value from the named wheel
::1.c Advance the position of this wheel.

Given the wheel
: A: 1 2 3
the number 1 is first generated, then 2, then 3, 1, 2, 3, 1, ...

'''Note:''' When more than one wheel is defined as a set of intersecting wheels then the
first named wheel is assumed to be the one that values are generated from.

;Examples:
Given the wheels:
    A: 1 B 2
    B: 3 4
The series of numbers generated starts:
    1, 3, 2, 1, 4, 2, 1, 3, 2, 1, 4, 2, 1, 3, 2...

The intersections of number wheels can be more complex, (and might loop forever),
and wheels may be multiply connected.

'''Note:''' If a named wheel is referenced more than
once by one or many other wheels, then there is only one position of the wheel
that is advanced by each and all references to it.

E.g.
  A:  1 D D
  D:  6 7 8
  Generates:
    1 6 7 1 8 6 1 7 8 1 6 7 1 8 6 1 7 8 1 6 ...

;Task:
Generate and show the first twenty terms of the sequence of numbers generated
from these groups:

    Intersecting Number Wheel group:
      A:  1 2 3

    Intersecting Number Wheel group:
      A:  1 B 2
      B:  3 4

    Intersecting Number Wheel group:
      A:  1 D D
      D:  6 7 8

    Intersecting Number Wheel group:
      A:  1 B C
      B:  3 4
      C:  5 B

Show your output here, on this page.

Solution:
Map-accumulation of a recursive digit-search,
over an array of given length and arbitrary contents.


Intersecting number wheels

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

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

        // clockWorkTick :: Dict -> (Dict, Char)
        const clockWorkTick = wheelMap => {
            // The new configuration of the wheels, tupled with
            // a digit found by recursive descent from a single
            // click of the first wheel.
            const click = wheels => wheelName => {
                const
                    wheel = wheels[wheelName] || ['?'],
                    v = wheel[0];
                return bool(click)(Tuple)(isDigit(v) || '?' === v)(
                    insertDict(wheelName)(
                        leftRotate(wheel)
                    )(wheels)
                )(v);
            };
            return click(wheelMap)('A');
        };

        // leftRotate ::[a] -> [a]
        const leftRotate = xs =>
            // The head of the list appended
            // to the tail of of the list.
            0 < xs.length ? (
                xs.slice(1).concat(xs[0])
            ) : [];

        // TEST -------------------------------------------
        // State of each wheel-set after 20 clicks,
        // paired with the resulting series of characters.

        const tuple = uncurry(Tuple);
        const wheelLists = [
            [tuple('A', '123')],
            [tuple('A', '1B2'), tuple('B', '34')],
            [tuple('A', '1DD'), tuple('D', '678')],
            [tuple('A', '1BC'), tuple('B', '34'), tuple('C', '5B')]
        ];

        console.log([
            'Series and state of each wheel-set after 20 clicks:\n',
            unlines(
                map(tuples => showWheels(
                    mapAccumL(
                        compose(constant, clockWorkTick)
                    )(dictFromList(tuples))(replicate(20)(''))
                ))(wheelLists)
            ),
            '\nInitial state of each wheel-set:\n',
            map(map(compose(
                JSON.stringify,
                dictFromList,
                x => [Array.from(x)]
            )))(wheelLists).join('\n')
        ].join('\n'));
    };

    // DISPLAY FORMATTING ---------------------------------

    // showWheels :: (Dict, [Char]) -> String
    const showWheels = tpl =>
        JSON.stringify(
            Array.from(secondArrow(concat)(tpl))
        );

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

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

    // bool :: a -> a -> Bool -> a
    const bool = f => t => p =>
        p ? t : f;

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

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

    // constant :: a -> b -> a
    const constant = k => _ => k;

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

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

    // insertDict :: String -> a -> Dict -> Dict
    const insertDict = k => v => dct =>
        Object.assign({}, dct, {
            [k]: v
        });

    // isDigit :: Char -> Bool
    const isDigit = c => {
        const n = c.codePointAt(0);
        return 48 <= n && 57 >= n;
    };

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

    // Map-accumulation is a combination of map and a catamorphism;
    // it applies a function to each element of a list, passing an
    // accumulating parameter from left to right, and returning a final
    // value of this accumulator together with the new list.

    // mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
    const mapAccumL = f => acc => xs =>
        xs.reduce((a, x) => {
            const pair = f(a[0])(x);
            return Tuple(pair[0])(a[1].concat(pair[1]));
        }, Tuple(acc)([]));

    // replicate :: Int -> a -> [a]
    const replicate = n => x =>
        Array.from({
            length: n
        }, () => x);

    // uncurry :: (a -> b -> c) -> ((a, b) -> c)
    const uncurry = f =>
        (x, y) => f(x)(y);

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

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


JSON

Load a JSON string into a data structure.
Also, create a new data structure and serialize it into JSON.

Use objects and arrays (as appropriate for your language)
and make sure your JSON is valid (https://jsonformatter.org).

Solution:
var data = JSON.parse('{ "foo": 1, "bar": [10, "apples"] }');

var sample = { "blue": [1,2], "ocean": "water" };
var json_string = JSON.stringify(sample);


Jewels and stones

Create a function which takes two string parameters: 'stones' and 'jewels' and returns an integer.

Both strings can contain any number of upper or lower case letters. However, in the case of 'jewels', all letters must be distinct.

The function should count (and return) how many 'stones' are 'jewels' or, in other words, how many letters in 'stones' are also letters in 'jewels'.

Note that:
:# Only letters in the ISO basic Latin alphabet i.e. 'A to Z' or 'a to z' need be considered.
:# A lower case letter is considered to be different from its upper case equivalent for this purpose, i.e., 'a' != 'A'.
:# The parameters do not need to have exactly the same names.
:# Validating the arguments is unnecessary.

So, for example, if passed "aAAbbbb" for 'stones' and "aA" for 'jewels', the function should return 3.

This task was inspired by this problem.

Solution:
(() => {

    // jewelCount :: String -> String -> Int
    const jewelCount = (j, s) => {
        const js = j.split('');
        return s.split('')
            .reduce((a, c) => js.includes(c) ? a + 1 : a, 0)
    };

    // TEST -----------------------------------------------
    return [
            ['aA', 'aAAbbbb'],
            ['z', 'ZZ']
        ]
        .map(x => jewelCount(...x))
})();


Julia set

Task
Generate and draw a Julia set.

;Related tasks
*   Mandelbrot Set

Solution:
var maxIterations = 450, minX = -.5, maxX = .5,
    minY = -.5, maxY = .5, wid, hei, ctx,
    jsX = 0.285, jsY = 0.01;

function remap( x, t1, t2, s1, s2 ) {
    var f = ( x - t1 ) / ( t2 - t1 ),
        g = f * ( s2 - s1 ) + s1;
    return g;
}
function getColor( c ) {
    var r, g, b, p = c / 32,
        l = ~~( p * 6 ), o = p * 6 - l,
        q = 1 - o;

    switch( l % 6 ) {
        case 0: r = 1; g = o; b = 0; break;
        case 1: r = q; g = 1; b = 0; break;
        case 2: r = 0; g = 1; b = o; break;
        case 3: r = 0; g = q; b = 1; break;
        case 4: r = o; g = 0; b = 1; break;
        case 5: r = 1; g = 0; b = q; break;
    }
    var c = "#" + ( "00" + ( ~~( r * 255 ) ).toString( 16 ) ).slice( -2 ) +
                  ( "00" + ( ~~( g * 255 ) ).toString( 16 ) ).slice( -2 ) +
                  ( "00" + ( ~~( b * 255 ) ).toString( 16 ) ).slice( -2 );
    return (c);
}
function drawFractal() {
    var a, as, za, b, bs, zb, cnt, clr
    for( var j = 0; j < hei; j++ ) {
        for( var i = 0; i < wid; i++ ) {
            a = remap( i, 0, wid, minX, maxX )
            b = remap( j, 0, hei, minY, maxY )
            cnt = 0;
            while( ++cnt < maxIterations ) {
                za = a * a; zb = b * b;
                if( za + zb > 4 ) break;
                as = za - zb; bs = 2 * a * b;
                a = as + jsX; b = bs + jsY;
            }
            if( cnt < maxIterations ) {
                ctx.fillStyle = getColor( cnt );
            }
            ctx.fillRect( i, j, 1, 1 );
        }
    }
}
function init() {
    var canvas = document.createElement( "canvas" );
    wid = hei = 800;
    canvas.width = wid; canvas.height = hei;
    ctx = canvas.getContext( "2d" );
    ctx.fillStyle = "black"; ctx.fillRect( 0, 0, wid, hei );
    document.body.appendChild( canvas );
    drawFractal();
}


Kaprekar numbers

A positive integer is a Kaprekar number if:
* It is   '''1'''     (unity)
* The decimal representation of its square may be split once into two parts consisting of positive integers which sum to the original number.
Note that a split resulting in a part consisting purely of 0s is not valid,
as 0 is not considered positive.

;Example Kaprekar numbers:
* 2223 is a Kaprekar number, as 2223 * 2223 = 4941729, 4941729 may be split to 494 and 1729, and 494 + 1729 = 2223.
* The series of Kaprekar numbers is known as A006886, and begins as 1, 9, 45, 55, ....

;Example process:
10000 (1002) splitting from left to right:
* The first split is [1, 0000], and is invalid; the 0000 element consists entirely of 0s, and 0 is not considered positive.
* Slight optimization opportunity: When splitting from left to right, once the right part consists entirely of 0s, no further testing is needed; all further splits would also be invalid.

;Task:
Generate and show all Kaprekar numbers less than 10,000.

;Extra credit:
Optionally, count (and report the count of) how many Kaprekar numbers are less than 1,000,000.

;Extra extra credit:
The concept of Kaprekar numbers is not limited to base 10 (i.e. decimal numbers);
if you can, show that Kaprekar numbers exist in other bases too.

For this purpose, do the following:
* Find all Kaprekar numbers for base 17 between 1 and 1,000,000 (one million);
* Display each of them in base 10 representation;
* Optionally, using base 17 representation (use letters 'a' to 'g' for digits 10(10) to 16(10)), display each of the numbers, its square, and where to split the square.

For example, 225(10) is "d4" in base 17, its square "a52g", and a5(17) + 2g(17) = d4(17), so the display would be something like:225   d4  a52g  a5 + 2g

;Reference:
* The Kaprekar Numbers by Douglas E. Iannucci (2000). PDF version

;Related task:
*   [[Casting out nines]]

Solution:
function kaprekar( s, e, bs, pbs ) {
	bs = bs || 10; pbs = pbs || 10
	const toString = n => n.toString(pbs).toUpperCase()
	document.write('start:',toString(s), ' end:',toString(e), ' base:',bs, ' printBase:',pbs, '
' )
	for (var k=0, n=s; n<=e; n+=1) if (isKaprekar(n, bs)) k+=1, document.write(toString(n), ' ')
	document.write('
found ', k, ' numbers

')
}

kaprekar( 1, 99 )
kaprekar( 1, 255, 16)
kaprekar( 1, 255, 16, 16)
kaprekar( 1, 288, 17, 17)


Kernighans large earthquake problem

Brian Kernighan, in a lecture at the University of Nottingham, described a problem on which this task is based.

;Problem:
You are given a a data file of thousands of lines; each of three `whitespace` separated fields: a date, a one word name and the magnitude of the event.

Example lines from the file would be lines like:
8/27/1883    Krakatoa            8.8
5/18/1980    MountStHelens       7.6
3/13/2009    CostaRica           5.1

;Task:
* Create a program or script invocation to find all the events with magnitude greater than 6
* Assuming an appropriate name e.g. "data.txt" for the file:
:# Either: Show how your program is invoked to process a data file of that name.
:# Or: Incorporate the file name into the program, (as it is assumed that the program is single use).

Solution:
const fs = require("fs");
const readline = require("readline");

const args = process.argv.slice(2);
if (!args.length) {
    console.error("must supply file name");
    process.exit(1);
}

const fname = args[0];

const readInterface = readline.createInterface({
    input: fs.createReadStream(fname),
    console: false,
});

readInterface.on("line", (line) => {
    const fields = line.split(/\s+/);
    if (+fields[fields.length - 1] > 6) {
        console.log(line);
    }
});


Keyboard input/Obtain a Y or N response

Obtain a valid   '''Y'''   or   '''N'''   response from the [[input device::keyboard]].

The keyboard should be flushed, so that any outstanding key-presses are removed, preventing any existing   '''Y'''   or   '''N'''   key-press from being evaluated.

The response should be obtained as soon as   '''Y'''   or   '''N'''   are pressed, and there should be no need to press an   enter   key.

Solution:
const readline = require('readline');
readline.emitKeypressEvents(process.stdin);
process.stdin.setRawMode(true);

var wait_key = async function() {
  return await new Promise(function(resolve,reject) {
    var key_listen = function(str,key) {
      process.stdin.removeListener('keypress', key_listen);
      resolve(str);
    }
    process.stdin.on('keypress', key_listen);
  });
}

var done = function() {
  process.exit();
}

var go = async function() {
  do {
    console.log('Press any key...');
    var key = await wait_key();
    console.log("Key pressed is",key);
    await new Promise(function(resolve) { setTimeout(resolve,1000); });
  } while(key != 'y');
  done();
}

go();


Knight's tour

Task
Problem: you have a standard 8x8 chessboard, empty but for a single knight on some square.   Your task is to emit a series of legal knight moves that result in the knight visiting every square on the chessboard exactly once. Note that it is ''not'' a requirement that the tour be "closed"; that is, the knight need not end within a single move of its start position.

Input and output may be textual or graphical, according to the conventions of the programming environment.  If textual, squares should be indicated in algebraic notation.  The output should indicate the order in which the knight visits the squares, starting with the initial position.  The form of the output may be a diagram of the board with the squares numbered according to visitation sequence, or a textual list of algebraic coordinates in order, or even an actual animation of the knight moving around the chessboard.

Input: starting square

Output: move sequence

;Related tasks
* [[A* search algorithm]]
* [[N-queens problem]]
* [[Solve a Hidato puzzle]]
* [[Solve a Holy Knight's tour]]
* [[Solve a Hopido puzzle]]
* [[Solve a Numbrix puzzle]]
* [[Solve the no connection puzzle]]

Solution:
class KnightTour {
 constructor() {
  this.width = 856;
  this.height = 856;
  this.cellCount = 8;
  this.size = 0;
  this.knightPiece = "\u2658";
  this.knightPos = {
   x: 0,
   y: 0
  };
  this.ctx = null;
  this.step = this.width / this.cellCount;
  this.lastTime = 0;
  this.wait;
  this.delay;
  this.success;
  this.jumps;
  this.directions = [];
  this.visited = [];
  this.path = [];
  document.getElementById("start").addEventListener("click", () => {
   this.startHtml();
  });
  this.init();
  this.drawBoard();
 }

 drawBoard() {
  let a = false, xx, yy;
  for (let y = 0; y < this.cellCount; y++) {
   for (let x = 0; x < this.cellCount; x++) {
    if (a) {
     this.ctx.fillStyle = "#607db8";
    } else {
     this.ctx.fillStyle = "#aecaf0";
    }
    a = !a;
    xx = x * this.step;
    yy = y * this.step;
    this.ctx.fillRect(xx, yy, xx + this.step, yy + this.step);
   }
   if (!(this.cellCount & 1)) a = !a;
  }
  if (this.path.length) {
   const s = this.step >> 1;
   this.ctx.lineWidth = 3;
   this.ctx.fillStyle = "black";
   this.ctx.beginPath();
   this.ctx.moveTo(this.step * this.knightPos.x + s, this.step * this.knightPos.y + s);
   let a, b, v = this.path.length - 1;
   for (; v > -1; v--) {
    a = this.path[v].pos.x * this.step + s;
    b = this.path[v].pos.y * this.step + s;
    this.ctx.lineTo(a, b);
    this.ctx.fillRect(a - 5, b - 5, 10, 10);
   }
   this.ctx.stroke();
  }
 }

 createMoves(pos) {
  const possibles = [];
  let x = 0,
   y = 0,
   m = 0,
   l = this.directions.length;
  for (; m < l; m++) {
   x = pos.x + this.directions[m].x;
   y = pos.y + this.directions[m].y;
   if (x > -1 && x < this.cellCount && y > -1 && y < this.cellCount && !this.visited[x + y * this.cellCount]) {
    possibles.push({
     x,
     y
    })
   }
  }
  return possibles;
 }

 warnsdorff(pos) {
  const possibles = this.createMoves(pos);
  if (possibles.length < 1) return [];
  const moves = [];
  for (let p = 0, l = possibles.length; p < l; p++) {
   let ps = this.createMoves(possibles[p]);
   moves.push({
    len: ps.length,
    pos: possibles[p]
   });
  }
  moves.sort((a, b) => {
   return b.len - a.len;
  });
  return moves;
 }

 startHtml() {
  this.cellCount = parseInt(document.getElementById("cellCount").value);
  this.size = Math.floor(this.width / this.cellCount)
  this.wait = this.delay = parseInt(document.getElementById("delay").value);
  this.step = this.width / this.cellCount;
  this.ctx.font = this.size + "px Arial";
  document.getElementById("log").innerText = "";
  document.getElementById("path").innerText = "";
  this.path = [];
  this.jumps = 1;
  this.success = true;
  this.visited = [];
  const cnt = this.cellCount * this.cellCount;
  for (let a = 0; a < cnt; a++) {
   this.visited.push(false);
  }
  const kx = parseInt(document.getElementById("knightx").value),
   ky = parseInt(document.getElementById("knighty").value);
  this.knightPos = {
   x: (kx > this.cellCount || kx < 0) ? Math.floor(Math.random() * this.cellCount) : kx,
   y: (ky > this.cellCount || ky < 0) ? Math.floor(Math.random() * this.cellCount) : ky
  };
  this.mainLoop = (time = 0) => {
   const dif = time - this.lastTime;
   this.lastTime = time;
   this.wait -= dif;
   if (this.wait > 0) {
    requestAnimationFrame(this.mainLoop);
    return;
   }
   this.wait = this.delay;
   let moves;
   if (this.success) {
    moves = this.warnsdorff(this.knightPos);
   } else {
    if (this.path.length > 0) {
     const path = this.path[this.path.length - 1];
     moves = path.m;
     if (moves.length < 1) this.path.pop();
     this.knightPos = path.pos
     this.visited[this.knightPos.x + this.knightPos.y * this.cellCount] = false;
     this.jumps--;
     this.wait = this.delay;
    } else {
     document.getElementById("log").innerText = "Can't find a solution!";
     return;
    }
   }
   this.drawBoard();
   const ft = this.step - (this.step >> 3);
   this.ctx.fillStyle = "#000";
   this.ctx.fillText(this.knightPiece, this.knightPos.x * this.step, this.knightPos.y * this.step + ft);
   if (moves.length < 1) {
    if (this.jumps === this.cellCount * this.cellCount) {
     document.getElementById("log").innerText = "Tour finished!";
     let str = "";
     for (let z of this.path) {
      str += `${1 + z.pos.x + z.pos.y * this.cellCount}, `;
     }
     str += `${1 + this.knightPos.x + this.knightPos.y * this.cellCount}`;
     document.getElementById("path").innerText = str;
     return;
    } else {
     this.success = false;
    }
   } else {
    this.visited[this.knightPos.x + this.knightPos.y * this.cellCount] = true;
    const move = moves.pop();
    this.path.push({
     pos: this.knightPos,
     m: moves
    });
    this.knightPos = move.pos
    this.success = true;
    this.jumps++;
   }
   requestAnimationFrame(this.mainLoop);
  };
  this.mainLoop();
 }

 init() {
  const canvas = document.createElement("canvas");
  canvas.id = "cv";
  canvas.width = this.width;
  canvas.height = this.height;
  this.ctx = canvas.getContext("2d");
  document.getElementById("out").appendChild(canvas);
  this.directions = [{
    x: -1,
    y: -2
   }, {
    x: -2,
    y: -1
   }, {
    x: 1,
    y: -2
   }, {
    x: 2,
    y: -1
   },
   {
    x: -1,
    y: 2
   }, {
    x: -2,
    y: 1
   }, {
    x: 1,
    y: 2
   }, {
    x: 2,
    y: 1
   }
  ];
 }
}
new KnightTour();


Knight's tour

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

    // knightsTour :: Int -> [(Int, Int)] -> [(Int, Int)]
    const knightsTour = rowLength => moves => {
        const go = path => {
            const
                findMoves = xy => difference(knightMoves(xy), path),
                warnsdorff = minimumBy(
                    comparing(compose(length, findMoves))
                ),
                options = findMoves(path[0]);
            return 0 < options.length ? (
                go([warnsdorff(options)].concat(path))
            ) : reverse(path);
        };

        // board :: [[(Int, Int)]]
        const board = concatMap(
            col => concatMap(
                row => [
                    [col, row]
                ],
                enumFromTo(1, rowLength)),
            enumFromTo(1, rowLength)
        );

        // knightMoves :: (Int, Int) -> [(Int, Int)]
        const knightMoves = ([x, y]) =>
            concatMap(
                ([dx, dy]) => {
                    const ab = [x + dx, y + dy];
                    return elem(ab, board) ? (
                        [ab]
                    ) : [];
                }, [
                    [-2, -1],
                    [-2, 1],
                    [-1, -2],
                    [-1, 2],
                    [1, -2],
                    [1, 2],
                    [2, -1],
                    [2, 1]
                ]
            );
        return go(moves);
    };

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

        // boardSize :: Int
        const boardSize = 8;

        // tour :: [(Int, Int)]
        const tour = knightsTour(boardSize)(
            [fromAlgebraic('e5')]
        );

        // report :: String
        const report = '(Board size ' +
            boardSize + '*' + boardSize + ')\n\n' +
            'Route: \n\n' +
            showRoute(boardSize)(tour) + '\n\n' +
            'Coverage and order: \n\n' +
            showCoverage(boardSize)(tour) + '\n\n';
        return (
            console.log(report),
            report
        );
    }

    // DISPLAY --------------------------------------------

    // algebraic :: (Int, Int) -> String
    const algebraic = ([x, y]) =>
        chr(x + 96) + y.toString();

    // fromAlgebraic :: String -> (Int, Int)
    const fromAlgebraic = s =>
        2 <= s.length ? (
            [ord(s[0]) - 96, parseInt(s.slice(1))]
        ) : undefined;

    // showCoverage :: Int -> [(Int, Int)] -> String
    const showCoverage = rowLength => xys => {
        const
            intMax = xys.length,
            w = 1 + intMax.toString().length
        return unlines(map(concat,
            chunksOf(
                rowLength,
                map(composeList([justifyRight(w, ' '), str, fst]),
                    sortBy(
                        mappendComparing([
                            compose(fst, snd),
                            compose(snd, snd)
                        ]),
                        zip(enumFromTo(1, intMax), xys)
                    )
                )
            )
        ));
    };

    // showRoute :: Int -> [(Int, Int)] -> String
    const showRoute = rowLength => xys => {
        const w = 1 + rowLength.toString().length;
        return unlines(map(
            xs => xs.join(' -> '),
            chunksOf(
                rowLength,
                map(compose(justifyRight(w, ' '), algebraic), xys)
            )
        ));
    };

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

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

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

    // chunksOf :: Int -> [a] -> [[a]]
    const chunksOf = (n, xs) =>
        enumFromThenTo(0, n, xs.length - 1)
        .reduce(
            (a, i) => a.concat([xs.slice(i, (n + i))]),
            []
        );

    // compare :: a -> a -> Ordering
    const compare = (a, b) =>
        a < b ? -1 : (a > b ? 1 : 0);

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

    // composeList :: [(a -> a)] -> (a -> a)
    const composeList = fs =>
        x => fs.reduceRight((a, f) => f(a), x, fs);

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

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

    // difference :: Eq a => [a] -> [a] -> [a]
    const difference = (xs, ys) => {
        const s = new Set(ys.map(str));
        return xs.filter(x => !s.has(str(x)));
    };

    // elem :: Eq a => a -> [a] -> Bool
    const elem = (x, xs) => xs.some(eq(x))

    // enumFromThenTo :: Int -> Int -> Int -> [Int]
    const enumFromThenTo = (x1, x2, y) => {
        const d = x2 - x1;
        return Array.from({
            length: Math.floor(y - x2) / d + 2
        }, (_, i) => x1 + (d * i));
    };

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

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

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

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

    // mappendComparing :: [(a -> b)] -> (a -> a -> Ordering)
    const mappendComparing = fs =>
        (x, y) => fs.reduce(
            (ordr, f) => (ordr || compare(f(x), f(y))),
            0
        );

    // minimumBy :: (a -> a -> Ordering) -> [a] -> a
    const minimumBy = f => xs =>
        xs.reduce((a, x) => undefined === a ? x : (
            0 > f(x, a) ? x : a
        ), undefined);

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

    // reverse :: [a] -> [a]
    const reverse = xs =>
        'string' !== typeof xs ? (
            xs.slice(0).reverse()
        ) : xs.split('').reverse().join('');

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

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

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

    // take :: Int -> [a] -> [a]
    // take :: Int -> String -> String
    const take = (n, xs) =>
        xs.slice(0, n);

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

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

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

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


Koch curve

Draw a Koch curve. See details: Koch curve

Solution: Generates SVG. To view, save to a file with the extension '.svg', and open in a browser.


Koch curve

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

    // kochSnowflake :: Int -> (Float, Float) -> (Float, Float)
    //                      -> [(Float, Float)]
    const kochSnowflake = n => a => b => {
        // List of points on a Koch snowflake of order n, derived
        // from an equilateral triangle with base a b.
        const points = [a, equilateralApex(a)(b), b];
        return concat(
            zipWith(kochCurve(n))(points)(
                points.slice(1).concat([points[0]])
            )
        );
    };

    // koch :: Int -> (Float, Float) -> (Float, Float)
    //             -> [(Float, Float)]
    const kochCurve = n => ab => xy => {
        // A Koch curve of order N, starting at the point
        // (a, b), and ending at the point (x, y).
        const go = n => ([ab, xy]) =>
            0 !== n ? (() => {
                const [mp, mq] = midThirdOfLine(ab)(xy);
                const points = [
                    ab,
                    mp,
                    equilateralApex(mp)(mq),
                    mq,
                    xy
                ];
                return zip(points)(points.slice(1))
                    .flatMap(go(n - 1))
            })() : [xy];
        return [ab].concat(go(n)([ab, xy]));
    };

    // equilateralApex :: (Float, Float) -> (Float, Float) -> (Float, Float)
    const equilateralApex = p => q =>
        rotatedPoint(Math.PI / 3)(p)(q);

    // rotatedPoint :: Float -> (Float, Float) ->
    //        (Float, Float) -> (Float, Float)
    const rotatedPoint = theta => ([ox, oy]) => ([a, b]) => {
        // The point ab rotated theta radians
        // around the origin xy.
        const [dx, dy] = rotatedVector(theta)(
            [a - ox, oy - b]
        );
        return [ox + dx, oy - dy];
    };

    // rotatedVector :: Float -> (Float, Float) -> (Float, Float)
    const rotatedVector = theta => ([x, y]) =>
        // The vector xy rotated by theta radians.
        [
            x * Math.cos(theta) - y * Math.sin(theta),
            x * Math.sin(theta) + y * Math.cos(theta)
        ];

    // midThirdOfLine :: (Float, Float) -> (Float, Float)
    //                 -> ((Float, Float), (Float, Float))
    const midThirdOfLine = ab => xy => {
        // Second of three equal segments of
        // the line between ab and xy.
        const
            vector = zipWith(dx => x => (dx - x) / 3)(xy)(ab),
            f = zipWith(add)(vector),
            p = f(ab);
        return [p, f(p)];
    };

    // TEST -----------------------------------------------
    // main :: IO ()
    const main = () =>
        // SVG showing a Koch snowflake of order 4.
        console.log(
            svgFromPoints(1024)(
                kochSnowflake(5)(
                    [200, 600]
                )([800, 600])
            )
        );

    // SVG ----------------------------------------------

    // svgFromPoints :: Int -> [(Int, Int)] -> String
    const svgFromPoints = w => ps => [
        '<svg xmlns="http://www.w3.org/2000/svg"',
        `width="500" height="500" viewBox="5 5 ${w} ${w}">`,
        `<path d="M${
        ps.flatMap(p => p.map(n => n.toFixed(2))).join(' ')
    }" `,
        'stroke-width="2" stroke="red" fill="transparent"/>',
        '</svg>'
    ].join('\n');

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

    // add :: Num -> Num -> Num
    const add = a => b => a + b;

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

    // zip :: [a] -> [b] -> [(a, b)]
    const zip = xs => ys =>
        xs.slice(
            0, Math.min(xs.length, ys.length)
        ).map((x, i) => [x, ys[i]]);

    // zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
    const zipWith = f => xs => ys =>
        xs.slice(
            0, Math.min(xs.length, ys.length)
        ).map((x, i) => f(x)(ys[i]));

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


Largest int from concatenated ints

Given a set of positive integers, write a function to order the integers in such a way that the concatenation of the numbers forms the largest possible integer and return this integer.

Use the following two sets of integers as tests   and   show your program output here.

:::::*   {1, 34, 3, 98, 9, 76, 45, 4}
:::::*   {54, 546, 548, 60}

;Possible algorithms:
# A solution could be found by trying all combinations and return the best.
# Another way to solve this is to note that in the best arrangement, for any two adjacent original integers '''X''' and '''Y''', the concatenation '''X''' followed by '''Y''' will be numerically greater than or equal to the concatenation '''Y''' followed by '''X.
# Yet another way to solve this is to pad the integers to the same size by repeating the digits then sort using these repeated integers as a sort key.

;See also:
*   Algorithms: What is the most efficient way to arrange the given numbers to form the biggest number?
*   Constructing the largest number possible by rearranging a list

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

     // maxCombine :: [Int] -> Int
     function maxCombine(xs) {
         return parseInt(
             xs.sort(
                 function (x, y) {
                     var a = x.toString(),
                         b = y.toString(),
                         ab = parseInt(a + b),
                         ba = parseInt(b + a);

                     return ab > ba ? -1 : (ab < ba ? 1 : 0);
                 }
             )
             .join(''), 10
         );
     }

     return [
        [1, 34, 3, 98, 9, 76, 45, 4],
        [54, 546, 548, 60]
     ].map(maxCombine);

 })();