100 doors

There are 100 doors in a row that are all initially closed.

You make 100 passes by the doors.

The first time through, visit every door and  ''toggle''  the door  (if the door is closed,  open it;   if it is open,  close it).

The second time, only visit every 2nd door   (door #2, #4, #6, ...),   and toggle it.

The third time, visit every 3rd door   (door #3, #6, #9, ...), etc,   until you only visit the 100th door.

;Task:
Answer the question:   what state are the doors in after the last pass?   Which are open, which are closed?

'''Alternate:'''
As noted in this page's   discussion page,   the only doors that remain open are those whose numbers are perfect squares.

Opening only those doors is an   optimization   that may also be expressed;
however, as should be obvious, this defeats the intent of comparing implementations across programming languages.

Solution:
(function (n) {
    "use strict";
    function finalDoors(n) {
        var lstRange = range(1, n);
        return lstRange
            .reduce(function (a, _, k) {
                var m = k + 1;
                return a.map(function (x, i) {
                    var j = i + 1;
                    return [j, j % m ? x[1] : !x[1]];
                });
            }, zip(
                lstRange,
                replicate(n, false)
            ));
    };
    function zip(xs, ys) {
        return xs.length === ys.length ? (
            xs.map(function (x, i) {
                return [x, ys[i]];
            })
        ) : undefined;
    }
    function replicate(n, a) {
        var v = [a],
            o = [];
        if (n < 1) return o;
        while (n > 1) {
            if (n & 1) o = o.concat(v);
            n >>= 1;
            v = v.concat(v);
        }
        return o.concat(v);
    }
    function range(m, n, delta) {
        var d = delta || 1,
            blnUp = n > m,
            lng = Math.floor((blnUp ? n - m : m - n) / d) + 1,
            a = Array(lng),
            i = lng;
        if (blnUp)
            while (i--) a[i] = (d * i) + m;
        else
            while (i--) a[i] = m - (d * i);
        return a;
    }
    return finalDoors(n)
        .filter(function (tuple) {
            return tuple[1];
        })
        .map(function (tuple) {
            return {
                door: tuple[0],
                open: tuple[1]
            };
        });

})(100);


100 doors

Solution:
"use strict";

// Doors can be open or closed.
const open = "O";
const closed = "C";

// There are 100 doors in a row that are all initially closed.
const doorsCount = 100;
const doors = [];
for (let i = 0; i < doorsCount; doors[i] = closed, i++);

// You make 100 passes by the doors, visiting every door and toggle the door (if
// the door is closed, open it; if it is open, close it), according to the rules
// of the task.
for (let pass = 1; pass <= doorsCount; pass++)
    for (let i = pass - 1; i < doorsCount; i += pass)
        doors[i] = doors[i] == open ? closed : open;

// Answer the question: what state are the doors in after the last pass?
doors.forEach((v, i) =>
    console.log(`Doors ${i + 1} are ${v == open ? 'opened' : 'closed'}.`));

// Which are open, which are closed?
let openKeyList = [];
let closedKeyList = [];
for (let door of doors.entries())
    if (door[1] == open)
        openKeyList.push(door[0] + 1);
    else
        closedKeyList.push(door[0] + 1);
console.log("These are open doors: " + openKeyList.join(", ") + ".");
console.log("These are closed doors: " + closedKeyList.join(", ") + ".");

// Assert:
const expected = [];
for (let i = 1; i * i <= doorsCount; expected.push(i * i), i++);
if (openKeyList.every((v, i) => v === expected[i]))
    console.log("The task is solved.")
else
    throw "These aren't the doors you're looking for.";


100 prisoners

The Problem:
* 100 prisoners are individually numbered 1 to 100
* A room having a cupboard of 100 opaque drawers numbered 1 to 100, that cannot be seen from outside.
* Cards numbered 1 to 100 are placed randomly, one to a drawer, and the drawers all closed; at the start.
* Prisoners start outside the room
:* They can decide some strategy before any enter the room.
:* Prisoners enter the room one by one, can open a drawer, inspect the card number in the drawer, then close the drawer.
:* A prisoner can open no more than 50 drawers.
:* A prisoner tries to find his own number.
:* A prisoner finding his own number is then held apart from the others.
* If '''all''' 100 prisoners find their own numbers then they will all be pardoned. If ''any'' don't then ''all'' sentences stand.

;The task:
# Simulate several thousand instances of the game where the prisoners randomly open drawers
# Simulate several thousand instances of the game where the prisoners use the optimal strategy mentioned in the Wikipedia article, of:
:* First opening the drawer whose outside number is his prisoner number.
:* If the card within has his number then he succeeds otherwise he opens the drawer with the same number as that of the revealed card. (until he opens his maximum).

Show and compare the computed probabilities of success for the two strategies, here, on this page.

;References:
# The unbelievable solution to the 100 prisoner puzzle standupmaths (Video).
# [[wp:100 prisoners problem]]
# 100 Prisoners Escape Puzzle DataGenetics.
# Random permutation statistics#One hundred prisoners on Wikipedia.

Solution:
"use strict";

// Simulate several thousand instances of the game:
const gamesCount = 2000;

// ...where the prisoners randomly open drawers.
const randomResults = playGame(gamesCount, randomStrategy);

// ...where the prisoners use the optimal strategy mentioned in the Wikipedia article.
const optimalResults = playGame(gamesCount, optimalStrategy);

// Show and compare the computed probabilities of success for the two strategies.
console.log(`Games count: ${gamesCount}`);
console.log(`Probability of success with "random" strategy: ${computeProbability(randomResults, gamesCount)}`);
console.log(`Probability of success with "optimal" strategy: ${computeProbability(optimalResults, gamesCount)}`);

function playGame(gamesCount, strategy, prisonersCount = 100) {
    const results = new Array();

    for (let game = 1; game <= gamesCount; game++) {
        // A room having a cupboard of 100 opaque drawers numbered 1 to 100, that cannot be seen from outside.
        // Cards numbered 1 to 100 are placed randomly, one to a drawer, and the drawers all closed; at the start.
        const drawers = initDrawers(prisonersCount);

        // A prisoner tries to find his own number.
        // Prisoners start outside the room.
        // They can decide some strategy before any enter the room.
        let found = 0;
        for (let prisoner = 1; prisoner <= prisonersCount; prisoner++, found++)
            if (!find(prisoner, drawers, strategy)) break;

        // If all 100 findings find their own numbers then they will all be pardoned. If any don't then all sentences stand.
        results.push(found == prisonersCount);
    }

    return results;
}

function find(prisoner, drawers, strategy) {
    // A prisoner can open no more than 50 drawers.
    const openMax = Math.floor(drawers.length / 2);

    // Prisoners start outside the room.
    let card;
    for (let open = 0; open < openMax; open++) {
        // A prisoner tries to find his own number.
        card = strategy(prisoner, drawers, card);

        // A prisoner finding his own number is then held apart from the others.
        if (card == prisoner)
            break;
    }

    return (card == prisoner);
}

function randomStrategy(prisoner, drawers, card) {
    // Simulate the game where the prisoners randomly open drawers.

    const min = 0;
    const max = drawers.length - 1;

    return drawers[draw(min, max)];
}

function optimalStrategy(prisoner, drawers, card) {
    // Simulate the game where the prisoners use the optimal strategy mentioned in the Wikipedia article.

    // First opening the drawer whose outside number is his prisoner number.
    // If the card within has his number then he succeeds...
    if (typeof card === "undefined")
        return drawers[prisoner - 1];

    // ...otherwise he opens the drawer with the same number as that of the revealed card.
    return drawers[card - 1];
}

function initDrawers(prisonersCount) {
    const drawers = new Array();
    for (let card = 1; card <= prisonersCount; card++)
        drawers.push(card);

    return shuffle(drawers);
}

function shuffle(drawers) {
    const min = 0;
    const max = drawers.length - 1;
    for (let i = min, j; i < max; i++)     {
        j = draw(min, max);
        if (i != j)
            [drawers[i], drawers[j]] = [drawers[j], drawers[i]];
    }

    return drawers;
}

function draw(min, max) {
    // See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

function computeProbability(results, gamesCount) {
    return Math.round(results.filter(x => x == true).length * 10000 / gamesCount) / 100;
}


15 puzzle game

Implement the Fifteen Puzzle Game.

The   '''15-puzzle'''   is also known as:
:::*   '''Fifteen Puzzle'''
:::*   '''Gem Puzzle'''
:::*   '''Boss Puzzle'''
:::*   '''Game of Fifteen'''
:::*   '''Mystic Square'''
:::*   '''14-15 Puzzle'''
:::*   and some others.

;Related Tasks:
:*   15 Puzzle Solver
:*   [[16 Puzzle Game]]

Solution:
var board, zx, zy, clicks, possibles, clickCounter, oldzx = -1, oldzy = -1;
function getPossibles() {
    var ii, jj, cx = [-1, 0, 1, 0], cy = [0, -1, 0, 1];
    possibles = [];
    for( var i = 0; i < 4; i++ ) {
        ii = zx + cx[i]; jj = zy + cy[i];
        if( ii < 0 || ii > 3 || jj < 0 || jj > 3 ) continue;
        possibles.push( { x: ii, y: jj } );
    }
}
function updateBtns() {
    var b, v, id;
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            id = "btn" + ( i + j * 4 );
            b = document.getElementById( id );
            v = board[i][j];
            if( v < 16 ) {
                b.innerHTML = ( "" + v );
                b.className = "button"
            }
            else {
                b.innerHTML = ( "" );
                b.className = "empty";
            }
        }
    }
    clickCounter.innerHTML = "Clicks: " + clicks;
}
function shuffle() {
    var v = 0, t;
    do {
        getPossibles();
        while( true ) {
            t = possibles[Math.floor( Math.random() * possibles.length )];
            console.log( t.x, oldzx, t.y, oldzy )
            if( t.x != oldzx || t.y != oldzy ) break;
        }
        oldzx = zx; oldzy = zy;
        board[zx][zy] = board[t.x][t.y];
        zx = t.x; zy = t.y;
        board[zx][zy] = 16;
    } while( ++v < 200 );
}
function restart() {
    shuffle();
    clicks = 0;
    updateBtns();
}
function checkFinished() {
    var a = 0;
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            if( board[i][j] < a ) return false;
            a = board[i][j];
        }
    }
    return true;
}
function btnHandle( e ) {
    getPossibles();
    var c = e.target.i, r = e.target.j, p = -1;
    for( var i = 0; i < possibles.length; i++ ) {
        if( possibles[i].x == c && possibles[i].y == r ) {
            p = i;
            break;
        }
    }
    if( p > -1 ) {
        clicks++;
        var t = possibles[p];
        board[zx][zy] = board[t.x][t.y];
        zx = t.x; zy = t.y;
        board[zx][zy] = 16;
        updateBtns();
        if( checkFinished() ) {
            setTimeout(function(){
                alert( "WELL DONE!" );
                restart();
            }, 1);
        }
    }
}
function createBoard() {
    board = new Array( 4 );
    for( var i = 0; i < 4; i++ ) {
        board[i] = new Array( 4 );
    }
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            board[i][j] = ( i + j * 4 ) + 1;
        }
    }
    zx = zy = 3; board[zx][zy] = 16;
}
function createBtns() {
    var b, d = document.createElement( "div" );
    d.className += "board";
    document.body.appendChild( d );
    for( var j = 0; j < 4; j++ ) {
        for( var i = 0; i < 4; i++ ) {
            b = document.createElement( "button" );
            b.id = "btn" + ( i + j * 4 );
            b.i = i; b.j = j;
            b.addEventListener( "click", btnHandle, false );
            b.appendChild( document.createTextNode( "" ) );
            d.appendChild( b );
        }
    }
    clickCounter = document.createElement( "p" );
    clickCounter.className += "txt";
    document.body.appendChild( clickCounter );
}
function start() {
    createBtns();
    createBoard();
    restart();
}


21 game

'''21''' is a two player game, the game is played by choosing
a number ('''1''', '''2''', or '''3''')  to be added to the ''running total''.

The game is won by the player whose chosen number causes the ''running total''
to reach ''exactly'' '''21'''.

The ''running total'' starts at zero.
One player will be the computer.

Players alternate supplying a number to be added to the ''running total''.

;Task:
Write a computer program that will:
::* do the prompting (or provide a button menu),
::* check for errors and display appropriate error messages,
::* do the additions (add a chosen number to the ''running total''),
::* display the ''running total'',
::* provide a mechanism for the player to quit/exit/halt/stop/close the program,
::* issue a notification when there is a winner, and
::* determine who goes first (maybe a random or user choice, or can be specified when the game begins).

Solution:
<!DOCTYPE html>

    <meta charset="UTF-8">
    <meta name="keywords"    content="Game 21">
    <meta name="description" content="
      21 is a two player game, the game is played by choosing a number
      (1, 2, or 3) to be added to the running total. The game is won by
      the player whose chosen number causes the running total to reach
      exactly 21. The running total starts at zero.
    ">

    <meta name="dc.publisher" content="Rosseta Code">
    <meta name="dc.date"      content="2020-07-23">
    <meta name="dc.created"   content="2020-07-23">
    <meta name="dc.modified"  content="2020-07-30">
    <title>
        21 Game
    </title>

    <meta http-equiv="cache-control" content="no-cache">

    21 Game in ECMA Script (Java Script)

    21 is a two player game, the game is played by choosing a number
    (1, 2, or 3) to be added to the running total. The game is won by
    the player whose chosen number causes the running total to reach
    exactly 21. The running total starts at zero.

 Use buttons to play.

      human last choice:
      <input type="text" id="human" readonly>

      AI last choice:
      <input type="text" id="AI" readonly>

      running total:
      <input type="text" id="runningTotalText" readonly>

      <button onclick="choice(1);" id="choice1"> one   </button>
      <button onclick="choice(2);" id="choice2"> two   </button>
      <button onclick="choice(3);" id="choice3"> three </button>
      <button onclick="restart();"> restart </button>

    No script, no fun. Turn on Javascript on.


24 game

The 24 Game tests one's mental arithmetic.

;Task
Write a program that displays four digits, each from 1 --> 9 (inclusive) with repetitions allowed.

The program should prompt for the player to enter an arithmetic expression using ''just'' those, and ''all'' of those four digits, used exactly ''once'' each. The program should ''check'' then evaluate the expression.

The goal is for the player to enter an expression that (numerically) evaluates to '''24'''.
*  Only the following operators/functions are allowed: multiplication, division, addition, subtraction
*  Division should use floating point or rational arithmetic, etc, to preserve remainders.
*  Brackets are allowed, if using an infix expression evaluator.
*  Forming multiple digit numbers from the supplied digits is ''disallowed''. (So an answer of 12+12 when given 1, 2, 2, and 1 is wrong).
*  The order of the digits when given does not have to be preserved.

;Notes
* The type of expression evaluator used is not mandated. An RPN evaluator is equally acceptable for example.
* The task is not for the program to generate the expression, or test whether an expression is even possible.

;Related tasks
* [[24 game/Solve]]

;Reference
* The 24 Game on h2g2.

Solution:
function twentyfour(numbers, input) {
    var invalidChars = /[^\d\+\*\/\s-\(\)]/;

    var validNums = function(str) {
        // Create a duplicate of our input numbers, so that
        // both lists will be sorted.
        var mnums = numbers.slice();
        mnums.sort();

        // Sort after mapping to numbers, to make comparisons valid.
        return str.replace(/[^\d\s]/g, " ")
            .trim()
            .split(/\s+/)
            .map(function(n) { return parseInt(n, 10); })
            .sort()
            .every(function(v, i) { return v === mnums[i]; });
    };

    var validEval = function(input) {
        try {
            return eval(input);
        } catch (e) {
            return {error: e.toString()};
        }
    };

    if (input.trim() === "") return "You must enter a value.";
    if (input.match(invalidChars)) return "Invalid chars used, try again. Use only:\n + - * / ( )";
    if (!validNums(input)) return "Wrong numbers used, try again.";
    var calc = validEval(input);
    if (typeof calc !== 'number') return "That is not a valid input; please try again.";
    if (calc !== 24) return "Wrong answer: " + String(calc) + "; please try again.";
    return input + " == 24.  Congratulations!";
};

// I/O below.

while (true) {
    var numbers = [1, 2, 3, 4].map(function() {
        return Math.floor(Math.random() * 8 + 1);
    });

    var input = prompt(
        "Your numbers are:\n" + numbers.join(" ") +
        "\nEnter expression. (use only + - * / and parens).\n", +"'x' to exit.", "");

    if (input === 'x') {
        break;
    }
    alert(twentyfour(numbers, input));
}


24 game/Solve

Write a program that takes four digits, either from user input or by random generation, and computes arithmetic expressions following the rules of the [[24 game]].

Show examples of solutions generated by the program.

;Related task:
*   [[Arithmetic Evaluator]]

Solution:
var ar=[],order=[0,1,2],op=[],val=[];
var NOVAL=9999,oper="+-*/",out;

function rnd(n){return Math.floor(Math.random()*n)}

function say(s){
 try{document.write(s+"<br>")}
 catch(e){WScript.Echo(s)}
}

function getvalue(x,dir){
 var r=NOVAL;
 if(dir>0)++x;
 while(1){
  if(val[x]!=NOVAL){
   r=val[x];
   val[x]=NOVAL;
   break;
  }
  x+=dir;
 }
 return r*1;
}

function calc(){
 var c=0,l,r,x;
 val=ar.join('/').split('/');
 while(c<3){
  x=order[c];
  l=getvalue(x,-1);
  r=getvalue(x,1);
  switch(op[x]){
   case 0:val[x]=l+r;break;
   case 1:val[x]=l-r;break;
   case 2:val[x]=l*r;break;
   case 3:
   if(!r||l%r)return 0;
   val[x]=l/r;
  }
  ++c;
 }
 return getvalue(-1,1);
}

function shuffle(s,n){
 var x=n,p=eval(s),r,t;
 while(x--){
  r=rnd(n);
  t=p[x];
  p[x]=p[r];
  p[r]=t;
 }
}

function parenth(n){
 while(n>0)--n,out+='(';
 while(n<0)++n,out+=')';
}

function getpriority(x){
 for(var z=3;z--;)if(order[z]==x)return 3-z;
 return 0;
}

function showsolution(){
 var x=0,p=0,lp=0,v=0;
 while(x<4){
  if(x<3){
   lp=p;
   p=getpriority(x);
   v=p-lp;
   if(v>0)parenth(v);
  }
  out+=ar[x];
  if(x<3){
   if(v<0)parenth(v);
   out+=oper.charAt(op[x]);
  }
  ++x;
 }
 parenth(-p);
 say(out);
}

function solve24(s){
 var z=4,r;
 while(z--)ar[z]=s.charCodeAt(z)-48;
 out="";
 for(z=100000;z--;){
  r=rnd(256);
  op[0]=r&3;
  op[1]=(r>>2)&3;
  op[2]=(r>>4)&3;
  shuffle("ar",4);
  shuffle("order",3);
  if(calc()!=24)continue;
  showsolution();
  break;
 }
}

solve24("1234");
solve24("6789");
solve24("1127");


4-rings or 4-squares puzzle

Replace       '''a, b, c, d, e, f,'''   and
  '''g '''       with the decimal
digits   LOW   --->   HIGH
such that the sum of the letters inside of each of the four large squares add up to
the same sum.

            +--------------+      +--------------+
            |              |      |              |
            |      a       |      |      e       |
            |              |      |              |
            |          +---+------+---+      +---+---------+
            |          |   |      |   |      |   |         |
            |          | b |      | d |      | f |         |
            |          |   |      |   |      |   |         |
            |          |   |      |   |      |   |         |
            +----------+---+      +---+------+---+         |
                       |       c      |      |      g      |
                       |              |      |             |
                       |              |      |             |
                       +--------------+      +-------------+

Show all output here.

:*   Show all solutions for each letter being unique with
         LOW=1     HIGH=7
:*   Show all solutions for each letter being unique with
         LOW=3     HIGH=9
:*   Show only the   ''number''   of solutions when each letter can be non-unique
         LOW=0     HIGH=9

;Related task:
* [[Solve the no connection puzzle]]

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

    // ----------- 4-RINGS OR 4-SQUARES PUZZLE -----------

    // rings :: noRepeatedDigits -> DigitList -> solutions
    // rings :: Bool -> [Int] -> [[Int]]
    const rings = uniq =>
        digits => Boolean(digits.length) ? (
            () => {
                const ns = digits.sort(flip(compare));

                // CENTRAL DIGIT :: d
                return ns.flatMap(
                    ringTriage(uniq)(ns)
                );
            })() : [];

    const ringTriage = uniq => ns => d => {
        const
            h = head(ns),
            ts = ns.filter(x => (x + d) <= h);

        // LEFT OF CENTRE :: c and a
        return (
            uniq ? (delete_(d)(ts)) : ns
        )
        .flatMap(c => {
            const a = c + d;

            // RIGHT OF CENTRE :: e and g
            return a > h ? (
                []
            ) : (
                uniq ? (
                    difference(ts)([d, c, a])
                ) : ns
            )
            .flatMap(subTriage(uniq)([ns, h, a, c, d]));
        });
    };

    const subTriage = uniq =>
        ([ns, h, a, c, d]) => e => {
            const g = d + e;

            return ((g > h) || (
                uniq && (g === c))
            ) ? (
                    []
                ) : (() => {
                    const
                        agDelta = a - g,
                        bfs = uniq ? (
                            difference(ns)([
                                d, c, e, g, a
                            ])
                        ) : ns;

                    // MID LEFT, MID RIGHT :: b and f
                    return bfs.flatMap(b => {
                        const f = b + agDelta;

                        return (bfs).includes(f) && (
                            !uniq || ![
                                a, b, c, d, e, g
                            ].includes(f)
                        ) ? ([
                                [a, b, c, d, e, f, g]
                            ]) : [];
                    });
                })();
        };

    // ---------------------- TEST -----------------------
    const main = () => unlines([
        "rings(true, enumFromTo(1,7))\n",
        unlines(
            rings(true)(
                enumFromTo(1)(7)
            ).map(show)
        ),

        "\nrings(true, enumFromTo(3, 9))\n",
        unlines(
            rings(true)(
                enumFromTo(3)(9)
            ).map(show)
        ),

        "\nlength(rings(false, enumFromTo(0, 9)))\n",
        rings(false)(
            enumFromTo(0)(9)
        )
        .length
        .toString(),
        ""
    ]);

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

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

    // delete :: Eq a => a -> [a] -> [a]
    const delete_ = x => {
        // xs with first instance of x (if any) removed.
        const go = xs =>
            Boolean(xs.length) ? (
                (x === xs[0]) ? (
                    xs.slice(1)
                ) : [xs[0]].concat(go(xs.slice(1)))
            ) : [];

        return go;
    };

    // difference :: Eq a => [a] -> [a] -> [a]
    const difference = xs =>
        ys => {
            const s = new Set(ys);

            return xs.filter(x => !s.has(x));
        };

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

    // flip :: (a -> b -> c) -> b -> a -> c
    const flip = op =>
        // The binary function op with
        // its arguments reversed.
        1 !== op.length ? (
            (a, b) => op(b, a)
        ) : (a => b => op(b)(a));

    // head :: [a] -> a
    const head = xs =>
        // The first item (if any) in a list.
        Boolean(xs.length) ? (
            xs[0]
        ) : null;

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

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

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


99 bottles of beer

Display the complete lyrics for the song:     '''99 Bottles of Beer on the Wall'''.

;The beer song:
The lyrics follow this form:

:::              99 bottles of beer on the wall
:::              99 bottles of beer
:::              Take one down, pass it around
:::              98 bottles of beer on the wall

:::              98 bottles of beer on the wall
:::              98 bottles of beer
:::              Take one down, pass it around
:::              97 bottles of beer on the wall

... and so on, until reaching   '''0'''     (zero).

Grammatical support for   ''1 bottle of beer''   is optional.

As with any puzzle, try to do it in as creative/concise/comical a way
as possible (simple, obvious solutions allowed, too).

;See also:
*   http://99-bottles-of-beer.net/
*   [[:Category:99_Bottles_of_Beer]]
*   [[:Category:Programming language families]]
*   Wikipedia 99 bottles of beer

Solution:
function Bottles(count) {
  this.count = count || 99;
}

Bottles.prototype.take = function() {
  var verse = [
    this.count + " bottles of beer on the wall,",
    this.count + " bottles of beer!",
    "Take one down, pass it around",
    (this.count - 1) + " bottles of beer on the wall!"
  ].join("\n");

  console.log(verse);

  this.count--;
};

Bottles.prototype.sing = function() {
  while (this.count) {
    this.take();
  }
};

var bar = new Bottles(99);
bar.sing();


9 billion names of God the integer

This task is a variation of the short story by Arthur C. Clarke.

(Solvers should be aware of the consequences of completing this task.)

In detail, to specify what is meant by a   "name":
:The integer 1 has 1 name       "1".
:The integer 2 has 2 names   "1+1",   and   "2".
:The integer 3 has 3 names   "1+1+1",   "2+1",   and   "3".
:The integer 4 has 5 names   "1+1+1+1",   "2+1+1",   "2+2",   "3+1",   "4".
:The integer 5 has 7 names   "1+1+1+1+1",   "2+1+1+1",   "2+2+1",   "3+1+1",   "3+2",   "4+1",   "5".

;Task
Display the first 25 rows of a number triangle which begins:

                                      1
                                    1   1
                                  1   1   1
                                1   2   1   1
                              1   2   2   1   1
                            1   3   3   2   1   1

Where row   n   corresponds to integer   n,   and each column   C   in row   m   from left to right corresponds to the number of names beginning with   C.

A function   G(n)   should return the sum of the   n-th   row.

Demonstrate this function by displaying:   G(23),   G(123),   G(1234),   and   G(12345).

Optionally note that the sum of the   n-th   row   P(n)   is the      integer partition function.

Demonstrate this is equivalent to   G(n)   by displaying:   P(23),   P(123),   P(1234),   and   P(12345).

;Extra credit

If your environment is able, plot   P(n)   against   n   for   n=1\ldots 999.

;Related tasks
* [[Partition function P]]

Solution:
(function () {
    var cache = [
        [1]
    ];
//this was never needed.
   /* function PyRange(start, end, step) {
        step = step || 1;
        if (!end) {
            end = start;
            start = 0;
        }
        var arr = [];
        for (var i = start; i < end; i += step) arr.push(i);
        return arr;
    }*/

    function cumu(n) {
        var /*ra = PyRange(cache.length, n + 1),*/ //Seems there is a better version for this
            r, l, x, Aa, Mi;
       // for (ll in ra) { too pythony
       for (l=cache.length;l<n+1;l++) {
            r = [0];
//            l = ra[ll];
//            ran = PyRange(1, l + 1);
//            for (xx in ran) {
            for(x=1;x<l+1;x++){
//                x = ran[xx];
                r.push(r[r.length - 1] + (Aa = cache[l - x < 0 ? cache.length - (l - x) : l - x])[(Mi = Math.min(x, l - x)) < 0 ? Aa.length - Mi : Mi]);
            }
            cache.push(r);
        }
        return cache[n];
    }

    function row(n) {
        var r = cumu(n),
//            rra = PyRange(n),
            leArray = [],
            i;
//        for (ii in rra) {
        for (i=0;i<n;i++) {
//            i = rra[ii];
            leArray.push(r[i + 1] - r[i]);
        }
        return leArray;
    }

    console.log("Rows:");
    for (iterator = 1; iterator < 12; iterator++) {
        console.log(row(iterator));
    }

// PL clearly this was not tested:
//    console.log("Sums")[23, 123, 1234, 12345].foreach(function (a) {
    console.log("Sums");
    [23, 123, 1234, 12345].forEach(function (a) {
        var s = cumu(a);
        console.log(a, s[s.length - 1]);
    });
})()


A+B

'''A+B'''   --- a classic problem in programming contests,   it's given so contestants can gain familiarity with the online judging system being used.

;Task:
Given two integers,   '''A''' and '''B'''.

Their sum needs to be calculated.

;Input data:
Two integers are written in the input stream, separated by space(s):
: (-1000 \le A,B \le +1000)

;Output data:
The required output is one integer:   the sum of '''A''' and '''B'''.

;Example:
::{|class="standard"
 ! input
 ! output
 |-
 | 2 2
 | 4
 |-
 | 3 2
 | 5
 |}


ABC problem

You are given a collection of ABC blocks   (maybe like the ones you had when you were a kid).

There are twenty blocks with two letters on each block.

A complete alphabet is guaranteed amongst all sides of the blocks.

The sample collection of blocks:
  (B O)
  (X K)
  (D Q)
  (C P)
  (N A)
  (G T)
  (R E)
  (T G)
  (Q D)
  (F S)
  (J W)
  (H U)
  (V I)
  (A N)
  (O B)
  (E R)
  (F S)
  (L Y)
  (P C)
  (Z M)

;Task:
Write a function that takes a string (word) and determines whether the word can be spelled with the given collection of blocks.

The rules are simple:
::#   Once a letter on a block is used that block cannot be used again
::#   The function should be case-insensitive
::#   Show the output on this page for the following 7 words in the following example

;Example:
    >>> can_make_word("A")
    True
    >>> can_make_word("BARK")
    True
    >>> can_make_word("BOOK")
    False
    >>> can_make_word("TREAT")
    True
    >>> can_make_word("COMMON")
    False
    >>> can_make_word("SQUAD")
    True
    >>> can_make_word("CONFUSE")
    True

Solution:
(function (strWords) {

    var strBlocks =
        'BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM',
        blocks = strBlocks.split(' ');

    function abc(lstBlocks, strWord) {
        var lngChars = strWord.length;

        if (!lngChars) return [];

        var b = lstBlocks[0],
            c = strWord[0];

        return chain(lstBlocks, function (b) {
            return (b.indexOf(c.toUpperCase()) !== -1) ? [
                (b + ' ').concat(
                    abc(removed(b, lstBlocks), strWord.slice(1)))
            ] : [];
        })
    }

    // Monadic bind (chain) for lists
    function chain(xs, f) {
        return [].concat.apply([], xs.map(f));
    }

    // a -> [a] -> [a]
    function removed(x, xs) {
        var h = xs.length ? xs[0] : null,
            t = h ? xs.slice(1) : [];

        return h ? (
            h === x ? t : [h].concat(removed(x, t))
        ) : [];
    }

    function solution(strWord) {
        var strAttempt = abc(blocks, strWord)[0].split(',')[0];

        // two chars per block plus one space -> 3
        return strWord + ((strAttempt.length === strWord.length * 3) ?
            ' -> ' + strAttempt : ': [no solution]');
    }

    return strWords.split(' ').map(solution).join('\n');

})('A bark BooK TReAT COMMON squAD conFUSE');


ABC problem

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

    // ------------------- ABC BLOCKS --------------------

    // spellWith :: [(Char, Char)] -> [Char] -> [[(Char, Char)]]
    const spellWith = blocks =>
        wordChars => !Boolean(wordChars.length) ? [
            []
        ] : (() => {
            const [x, ...xs] = wordChars;

            return blocks.flatMap(
                b => b.includes(x) ? (
                    spellWith(
                        deleteBy(
                            p => q => (p[0] === q[0]) && (
                                p[1] === q[1]
                            )
                        )(b)(blocks)
                    )(xs)
                    .flatMap(bs => [b, ...bs])
                ) : []
            );
        })();

    // ---------------------- TEST -----------------------
    const main = () => {
        const blocks = (
            "BO XK DQ CP NA GT RE TG QD FS JW HU VI AN OB ER FS LY PC ZM"
        ).split(" ");

        return [
                "", "A", "BARK", "BoOK", "TrEAT",
                "COmMoN", "SQUAD", "conFUsE"
            ]
            .map(
                x => JSON.stringify([
                    x, !Boolean(
                        spellWith(blocks)(
                            [...x.toLocaleUpperCase()]
                        )
                        .length
                    )
                ])
            )
            .join("\n");
    };

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

    // deleteBy :: (a -> a -> Bool) -> a -> [a] -> [a]
    const deleteBy = fEq =>
        x => {
            const go = xs => Boolean(xs.length) ? (
                fEq(x)(xs[0]) ? (
                    xs.slice(1)
                ) : [xs[0], ...go(xs.slice(1))]
            ) : [];

            return go;
        };

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


ASCII art diagram converter

Given the RFC 1035 message diagram from Section 4.1.1 (Header section format) as a string:
http://www.ietf.org/rfc/rfc1035.txt

 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                      ID                       |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    QDCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    ANCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    NSCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
 |                    ARCOUNT                    |
 +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+

Where (every column of the table is 1 bit):

 ID is 16 bits
 QR = Query (0) or Response (1)
 Opcode = Four bits defining kind of query:
   0:    a standard query (QUERY)
   1:    an inverse query (IQUERY)
   2:    a server status request (STATUS)
   3-15: reserved for future use
 AA = Authoritative Answer bit
 TC = Truncation bit
 RD = Recursion Desired bit
 RA = Recursion Available bit
 Z = Reserved
 RCODE = Response code
 QC = Question Count
 ANC = Answer Count
 AUC = Authority Count
 ADC = Additional Count

Write a function, member function, class or template that accepts a similar multi-line string as input to define a data structure or something else able to decode or store a header with that specified bit structure.

If your language has macros, introspection, code generation, or powerful enough templates, then accept such string at compile-time to define the header data structure statically.

Such "Header" function or template should accept a table with 8, 16, 32 or 64 columns, and any number of rows. For simplicity the only allowed symbols to define the table are + - | (plus, minus, pipe), and whitespace. Lines of the input string composed just of whitespace should be ignored. Leading and trailing whitespace in the input string should be ignored, as well as  before and after each table row. The box for each bit of the diagram takes four chars "+--+". The code should perform a little of validation of the input string, but for brevity a full validation is not required.

Bonus: perform a thoroughly validation of the input string.

Solution:
// ------------------------------------------------------------[ Boilerplate ]--
const trimWhitespace = s => s.trim();
const isNotEmpty = s => s !== '';
const stringLength = s => s.length;
const hexToBin4 = s => parseInt(s, 16).toString(2).padStart(4, '0');
const concatHexToBin = (binStr, hexStr) => binStr.concat('', hexToBin4(hexStr));
const alignRight = n => s => `${s}`.padStart(n, ' ');
const alignLeft = n => s => `${s}`.padEnd(n, ' ');
const repeatChar = c => n => c.padStart(n, c);
const joinWith = c => arr => arr.join(c);
const joinNl = joinWith('\n');
const joinSp = joinWith(' ');

const printDiagramInfo = map => {
  const pName = alignLeft(8);
  const p5 = alignRight(5);
  const line = repeatChar('-');
  const res = [];
  res.push(joinSp([pName('Name'), p5('Size'), p5('Start'), p5('End')]));
  res.push(joinSp([line(8), line(5), line(5), line(5)]));
  [...map.values()].forEach(({label, bitLength, start, end}) => {
    res.push(joinSp([pName(label), p5(bitLength), p5(start), p5(end)]));
  })
  return res;
}

// -------------------------------------------------------------------[ Main ]--
const parseDiagram = dia => {

  const arr = dia.split('\n').map(trimWhitespace).filter(isNotEmpty);

  const hLine = arr[0];
  const bitTokens = hLine.split('+').map(trimWhitespace).filter(isNotEmpty);
  const bitWidth = bitTokens.length;
  const bitTokenWidth = bitTokens[0].length;

  const fields = arr.filter(e => e !== hLine);
  const allFields = fields.reduce((p, c) => [...p, ...c.split('|')], [])
      .filter(isNotEmpty);

  const lookupMap = Array(bitWidth).fill('').reduce((p, c, i) => {
    const v = i + 1;
    const stringWidth = (v * bitTokenWidth) + (v - 1);
    p.set(stringWidth, v);
    return p;
  }, new Map())

  const fieldMetaMap = allFields.reduce((p, e, i) => {
    const bitLength = lookupMap.get(e.length);
    const label = trimWhitespace(e);
    const start = i ? p.get(i - 1).end + 1 : 0;
    const end = start - 1 + bitLength;
    p.set(i, {label, bitLength, start, end})
    return p;
  }, new Map());

  const pName = alignLeft(8);
  const pBit = alignRight(5);
  const pPat = alignRight(18);
  const line = repeatChar('-');
  const nl = '\n';
  return hexStr => {
    const binString = [...hexStr].reduce(concatHexToBin, '');

    const res = printDiagramInfo(fieldMetaMap);
    res.unshift(joinNl(['Diagram:', ...arr, nl]));
    res.push(joinNl([nl, 'Test string in hex:', hexStr]));
    res.push(joinNl(['Test string in binary:', binString, nl]));
    res.push(joinSp([pName('Name'), pBit('Size'), pPat('Pattern')]));
    res.push(joinSp([line(8), line(5), line(18)]));

    [...fieldMetaMap.values()].forEach(({label, bitLength, start, end}) => {
      res.push(joinSp(
          [pName(label), pBit(bitLength),
            pPat(binString.substr(start, bitLength))]))
    })
    return joinNl(res);
  }
}

// --------------------------------------------------------------[ Run tests ]--

const dia = `
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                      ID                       |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    QDCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ANCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    NSCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                    ARCOUNT                    |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
`;

const parser = parseDiagram(dia);

parser('78477bbf5496e12e1bf169a4');


AVL tree

{{wikipedia|AVL tree}}

In computer science, an '''AVL tree''' is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; at no time do they differ by more than one because rebalancing is done ensure this is the case. Lookup, insertion, and deletion all take O(log ''n'') time in both the average and worst cases, where n is the number of nodes in the tree prior to the operation. Insertions and deletions may require the tree to be rebalanced by one or more tree rotations. Note the tree of nodes comprise a set, so duplicate node keys are not allowed.

AVL trees are often compared with red-black trees because they support the same set of operations and because red-black trees also take O(log ''n'') time for the basic operations.  Because AVL trees are more rigidly balanced, they are faster than red-black trees for lookup-intensive applications. Similar to red-black trees, AVL trees are height-balanced, but in general not weight-balanced nor m-balanced; that is, sibling nodes can have hugely differing numbers of descendants.

;Task:
Implement an AVL tree in the language of choice, and provide at least basic operations.

;Related task
[[Red_black_tree_sort]]

Solution:
function tree(less, val, more) {
  return {
    depth: 1+Math.max(less.depth, more.depth),
    less: less,
    val: val,
    more: more,
  };
}

function node(val) {
  return tree({depth: 0}, val, {depth: 0});
}

function insert(x,y) {
  if (0 == y.depth) return x;
  if (0 == x.depth) return y;
  if (1 == x.depth && 1 == y.depth) {
    switch (Math.sign(y.val)-x.val) {
      case -1: return tree(y, x.val, {depth: 0});
      case 0: return y;
      case 1: return tree(x, y.val, {depth: 0});
    }
  }
  switch (Math.sign(y.val-x.val)) {
    case -1: return balance(insert(x.less, y), x.val, x.more);
    case 0: return balance(insert(x.less, y.less), x.val, insert(x.more, y.more));
    case 1: return balance(x.less. x.val, insert(x.more, y));
  }
}

function balance(less,val,more) {
  if (2 > Math.abs(less.depth-more.depth))
    return tree(less,val,more);
  if (more.depth > less.depth) {
    if (more.more.depth >= more.less.depth) {
      // 'more' was heavy
      return moreHeavy(less, val, more);
    } else {
      return moreHeavy(less,val,lessHeavy(more.less, more.val, more.more));
    }
  } else {
    if(less.less.depth >= less.more.depth) {
      return lessHeavy(less, val, more);
    } else {
      return lessHeavy(moreHeavy(less.less, less.val, less.more), val, more);
    }
  }
}

function moreHeavy(less,val,more) {
  return tree(tree(less,val,more.less), more.val, more.more)
}

function lessHeavy(less,val,more) {
  return tree(less.less, less.val, tree(less.more, val, more));
}

function remove(val, y) {
  switch (y.depth) {
    case 0: return y;
    case 1:
      if (val == y.val) {
        return y.less;
      } else {
        return y;
      }
    default:
      switch (Math.sign(y.val - val)) {
        case -1: return balance(y.less, y.val, remove(val, y.more));
        case  0: return insert(y.less, y.more);
        case  1: return balance(remove(val, y.less), y.val, y.more)
      }
  }
}

function lookup(val, y) {
  switch (y.depth) {
    case 0: return y;
    case 1: if (val == y.val) {
      return y;
    } else {
      return {depth: 0};
    }
    default:
      switch (Math.sign(y.val-val)) {
        case -1: return lookup(val, y.more);
        case  0: return y;
        case  1: return lookup(val, y.less);
      }
  }
}


Abbreviations, automatic

The use of   abbreviations    (also sometimes called synonyms, nicknames, AKAs, or aliases)    can be an
easy way to add flexibility when specifying or using commands, sub-commands, options, etc.

It would make a list of words easier to maintain   (as words are added, changed, and/or deleted)   if
the minimum abbreviation length of that list could be automatically (programmatically) determined.

For this task, use the list (below) of the days-of-the-week names that are expressed in about a hundred languages   (note that there is a blank line in the list).

Sunday Monday Tuesday Wednesday Thursday Friday Saturday
Sondag Maandag Dinsdag Woensdag Donderdag Vrydag Saterdag
E_djele E_hene E_marte E_merkure E_enjte E_premte E_shtune
Ehud Segno Maksegno Erob Hamus Arbe Kedame
Al_Ahad Al_Ithinin Al_Tholatha'a Al_Arbia'a Al_Kamis Al_Gomia'a Al_Sabit
Guiragui Yergou_shapti Yerek_shapti Tchorek_shapti Hink_shapti Ourpat Shapat
domingu llunes martes miercoles xueves vienres sabadu
Bazar_gUnU Birinci_gUn Ckinci_gUn UcUncU_gUn DOrdUncU_gUn Bes,inci_gUn Altonco_gUn
Igande Astelehen Astearte Asteazken Ostegun Ostiral Larunbat
Robi_bar Shom_bar Mongal_bar Budhh_bar BRihashpati_bar Shukro_bar Shoni_bar
Nedjelja Ponedeljak Utorak Srijeda Cxetvrtak Petak Subota
Disul Dilun Dimeurzh Dimerc'her Diriaou Digwener Disadorn
nedelia ponedelnik vtornik sriada chetvartak petak sabota
sing_kei_yaht sing_kei_yat sing_kei_yee sing_kei_saam sing_kei_sie sing_kei_ng sing_kei_luk
Diumenge Dilluns Dimarts Dimecres Dijous Divendres Dissabte
Dzeenkk-eh Dzeehn_kk-ehreh Dzeehn_kk-ehreh_nah_kay_dzeeneh Tah_neesee_dzeehn_neh Deehn_ghee_dzee-neh Tl-oowey_tts-el_dehlee Dzeentt-ahzee
dy_Sul dy_Lun dy_Meurth dy_Mergher dy_You dy_Gwener dy_Sadorn
Dimanch Lendi Madi Mekredi Jedi Vandredi Samdi
nedjelja ponedjeljak utorak srijeda cxetvrtak petak subota
nede^le ponde^li utery str^eda c^tvrtek patek sobota
Sondee Mondee Tiisiday Walansedee TOOsedee Feraadee Satadee
s0ndag mandag tirsdag onsdag torsdag fredag l0rdag
zondag maandag dinsdag woensdag donderdag vrijdag zaterdag
Diman^co Lundo Mardo Merkredo ^Jaudo Vendredo Sabato
pUhapaev esmaspaev teisipaev kolmapaev neljapaev reede laupaev

Diu_prima Diu_sequima Diu_tritima Diu_quartima Diu_quintima Diu_sextima Diu_sabbata
sunnudagur manadagur tysdaguy mikudagur hosdagur friggjadagur leygardagur
Yek_Sham'beh Do_Sham'beh Seh_Sham'beh Cha'har_Sham'beh Panj_Sham'beh Jom'eh Sham'beh
sunnuntai maanantai tiistai keskiviiko torsktai perjantai lauantai
dimanche lundi mardi mercredi jeudi vendredi samedi
Snein Moandei Tiisdei Woansdei Tonersdei Freed Sneon
Domingo Segunda_feira Martes Mercores Joves Venres Sabado
k'vira orshabati samshabati otkhshabati khutshabati p'arask'evi shabati
Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag
Kiriaki' Defte'ra Tri'ti Teta'rti Pe'mpti Paraskebi' Sa'bato
ravivaar somvaar mangalvaar budhvaar guruvaar shukravaar shanivaar
popule po`akahi po`alua po`akolu po`aha po`alima po`aono
Yom_rishon Yom_sheni Yom_shlishi Yom_revi'i Yom_chamishi Yom_shishi Shabat
ravivara somavar mangalavar budhavara brahaspativar shukravara shanivar
vasarnap hetfo kedd szerda csutortok pentek szombat
Sunnudagur Manudagur +ridjudagur Midvikudagar Fimmtudagur FOstudagur Laugardagur
sundio lundio mardio merkurdio jovdio venerdio saturdio
Minggu Senin Selasa Rabu Kamis Jumat Sabtu
Dominica Lunedi Martedi Mercuridi Jovedi Venerdi Sabbato
De_Domhnaigh De_Luain De_Mairt De_Ceadaoin De_ardaoin De_hAoine De_Sathairn
domenica lunedi martedi mercoledi giovedi venerdi sabato
Nichiyou_bi Getzuyou_bi Kayou_bi Suiyou_bi Mokuyou_bi Kin'you_bi Doyou_bi
Il-yo-il Wol-yo-il Hwa-yo-il Su-yo-il Mok-yo-il Kum-yo-il To-yo-il
Dies_Dominica Dies_Lunae Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Saturni
sve-tdien pirmdien otrdien tresvdien ceturtdien piektdien sestdien
Sekmadienis Pirmadienis Antradienis Trec^iadienis Ketvirtadienis Penktadienis S^es^tadienis
Wangu Kazooba Walumbe Mukasa Kiwanuka Nnagawonye Wamunyi
xing-_qi-_ri xing-_qi-_yi-. xing-_qi-_er xing-_qi-_san-. xing-_qi-_si xing-_qi-_wuv. xing-_qi-_liu
Jedoonee Jelune Jemayrt Jecrean Jardaim Jeheiney Jesam
Jabot Manre Juje Wonje Taije Balaire Jarere
geminrongo minomishi martes mierkoles misheushi bernashi mishabaro
Ahad Isnin Selasa Rabu Khamis Jumaat Sabtu
sphndag mandag tirsdag onsdag torsdag fredag lphrdag
lo_dimenge lo_diluns lo_dimarc lo_dimercres lo_dijous lo_divendres lo_dissabte
djadomingo djaluna djamars djarason djaweps djabierna djasabra
Niedziela Poniedzial/ek Wtorek S,roda Czwartek Pia,tek Sobota
Domingo segunda-feire terca-feire quarta-feire quinta-feire sexta-feira sabado
Domingo Lunes martes Miercoles Jueves Viernes Sabado
Duminica Luni Mart'i Miercuri Joi Vineri Sambata
voskresenie ponedelnik vtornik sreda chetverg pyatnitsa subbota
Sunday Di-luain Di-mairt Di-ciadain Di-ardaoin Di-haoine Di-sathurne
nedjelja ponedjeljak utorak sreda cxetvrtak petak subota
Sontaha Mmantaha Labobedi Laboraro Labone Labohlano Moqebelo
Iridha- Sandhudha- Anga.haruwa-dha- Badha-dha- Brahaspa.thindha- Sikura-dha- Sena.sura-dha-
nedel^a pondelok utorok streda s^tvrtok piatok sobota
Nedelja Ponedeljek Torek Sreda Cxetrtek Petek Sobota
domingo lunes martes miercoles jueves viernes sabado
sonde mundey tude-wroko dride-wroko fode-wroko freyda Saturday
Jumapili Jumatatu Jumanne Jumatano Alhamisi Ijumaa Jumamosi
sondag mandag tisdag onsdag torsdag fredag lordag
Linggo Lunes Martes Miyerkoles Huwebes Biyernes Sabado
Le-pai-jit Pai-it Pai-ji Pai-san Pai-si Pai-gO. Pai-lak
wan-ar-tit wan-tjan wan-ang-kaan wan-phoet wan-pha-ru-hat-sa-boh-die wan-sook wan-sao
Tshipi Mosupologo Labobedi Laboraro Labone Labotlhano Matlhatso
Pazar Pazartesi Sali Car,samba Per,sembe Cuma Cumartesi
nedilya ponedilok vivtorok sereda chetver pyatnytsya subota
Chu?_Nha.t Thu*_Hai Thu*_Ba Thu*_Tu* Thu*_Na'm Thu*_Sau Thu*_Ba?y
dydd_Sul dyds_Llun dydd_Mawrth dyds_Mercher dydd_Iau dydd_Gwener dyds_Sadwrn
Dibeer Altine Talaata Allarba Al_xebes Aljuma Gaaw
iCawa uMvulo uLwesibini uLwesithathu uLuwesine uLwesihlanu uMgqibelo
zuntik montik dinstik mitvokh donershtik fraytik shabes
iSonto uMsombuluko uLwesibili uLwesithathu uLwesine uLwesihlanu uMgqibelo
Dies_Dominica Dies_Lunae Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Saturni
Bazar_gUnU Bazar_aertaesi Caers,aenbae_axs,amo Caers,aenbae_gUnU CUmae_axs,amo CUmae_gUnU CUmae_Senbae
Sun Moon Mars Mercury Jove Venus Saturn
zondag maandag dinsdag woensdag donderdag vrijdag zaterdag
KoseEraa GyoOraa BenEraa Kuoraa YOwaaraa FeEraa Memenaa
Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Sonnabend
Domingo Luns Terza_feira Corta_feira Xoves Venres Sabado
Dies_Solis Dies_Lunae Dies_Martis Dies_Mercurii Dies_Iovis Dies_Veneris Dies_Sabbatum
xing-_qi-_tian xing-_qi-_yi-. xing-_qi-_er xing-_qi-_san-. xing-_qi-_si xing-_qi-_wuv. xing-_qi-_liu
djadomingu djaluna djamars djarason djaweps djabierne djasabra
Killachau Atichau Quoyllurchau Illapachau Chaskachau Kuychichau Intichau

''Caveat:   The list (above) most surely contains errors (or, at the least, differences) of what the actual (or true) names for the days-of-the-week.''

To make this Rosetta Code task page as small as possible, if processing the complete list, read the days-of-the-week from a file (that is created from the above list).

Notes concerning the above list of words
::*   each line has a list of days-of-the-week for a language, separated by at least one blank
::*   the words on each line happen to be in order, from Sunday --> Saturday
::*   most lines have words in mixed case and some have all manner of accented words and other characters
::*   some words were translated to the nearest character that was available to ''code page''   '''437'''
::*   the characters in the words are not restricted except that they may not have imbedded blanks
::*   for this example, the use of an underscore ('''_''') was used to indicate a blank in a word

;Task:
::*   The list of words   (days of the week)   needn't be verified/validated.
::*   Write a function to find the (numeric) minimum length abbreviation for each line that would make abbreviations unique.
::*   A blank line   (or a null line)   should return a null string.
::*   Process and show the output for at least the first '''five''' lines of the file.
::*   Show all output here.

Solution:
Array.prototype.hasDoubles = function() {
  let arr = this.slice();
  while (arr.length > 1) {
    let cur = arr.shift();
    if (arr.includes(cur)) return true;
  }
  return false;
}

function getMinAbbrLen(arr) {
  if (arr.length <= 1) return '';
  let testArr = [],
      len = 0, i;
  do {
    len++;
    for (i = 0; i < arr.length; i++)
      testArr[i] = arr[i].substr(0, len);
  } while (testArr.hasDoubles());
  return len;
}

// testing
for (let x = 0; x < list.length; x++) {
  let days = list[x].split(' '),
      l    = getMinAbbrLen(days);
  for (let y = 0; y < days.length; y++)
    days[y] = days[y].substring(0, l);
  document.write(`<p>(${l}): ${days.join('. ')}.</p>`);
}


Abbreviations, easy

This task is an easier (to code) variant of the Rosetta Code task:    [[Abbreviations, simple]].

For this task, the following   ''command table''   will be used:
    Add ALTer  BAckup Bottom  CAppend Change SCHANGE  CInsert CLAst COMPress COpy
    COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find
    NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput
    Join SPlit SPLTJOIN  LOAD  Locate CLocate  LOWercase UPPercase  LPrefix MACRO
    MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD  Query  QUIT
    READ  RECover REFRESH RENum REPeat  Replace CReplace  RESet  RESTore  RGTLEFT
    RIght LEft  SAVE  SET SHift SI  SORT  SOS  STAck STATus  TOP TRAnsfer Type Up

Notes concerning the above   ''command table'':
::*   it can be thought of as one long literal string   (with blanks at end-of-lines)
::*   it may have superfluous blanks
::*   it may be in any case (lower/upper/mixed)
::*   the order of the words in the   ''command table''   must be preserved as shown
::*   the user input(s) may be in any case (upper/lower/mixed)
::*   commands will be restricted to the Latin alphabet   (A --> Z,   a --> z)
::*   A valid abbreviation is a word that has:
:::*   at least the minimum length of the number of capital letters of the word in the ''command table''
:::*   compares equal (regardless of case) to the leading characters of the word in the ''command table''
:::*   a length not longer than the word in the ''command table''
::::*   '''ALT''',   '''aLt''',   '''ALTE''',   and   '''ALTER'''   are all abbreviations of   '''ALTer'''
::::*   '''AL''',   '''ALF''',   '''ALTERS''',   '''TER''',   and   '''A'''    aren't valid abbreviations of   '''ALTer'''
::::*   The number of capital letters in   '''ALTer'''   indicates that any abbreviation for   '''ALTer'''   must be at least three letters
::::*   Any word longer than five characters can't be an abbreviation for   '''ALTer'''
::::*   '''o''',    '''ov''',    '''oVe''',    '''over''',    '''overL''',    '''overla'''   are all acceptable abbreviations for   '''Overlay'''
::*   if there isn't any lowercase letters in the word in the ''command table'',   then there isn't an abbreviation permitted

;Task:
::*   The command table needn't be verified/validated.
::*   Write a function to validate if the user "words"   (given as input)   are valid   (in the ''command table'').
::*   If the word   is   valid,   then return the full uppercase version of that "word".
::*   If the word        isn't     valid,   then return the lowercase string:    '''*error*'''        (7 characters).
::*   A blank input   (or a null input)   should return a null string.
::*   Show all output here.

;An example test case to be used for this task:
For a user string of:
  riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin
the computer program should return the string:
  RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

Solution:
var abr=`Add ALTer  BAckup Bottom  CAppend Change SCHANGE  CInsert CLAst COMPress COpy
   COUnt COVerlay CURsor DELete CDelete Down DUPlicate Xedit EXPand EXTract Find
   NFind NFINDUp NFUp CFind FINdup FUp FOrward GET Help HEXType Input POWerinput
   Join SPlit SPLTJOIN  LOAD  Locate CLocate  LOWercase UPPercase  LPrefix MACRO
   MErge MODify MOve MSG Next Overlay PARSE PREServe PURge PUT PUTD  Query  QUIT
   READ  RECover REFRESH RENum REPeat  Replace CReplace  RESet  RESTore  RGTLEFT
   RIght LEft  SAVE  SET SHift SI  SORT  SOS  STAck STATus  TOP TRAnsfer Type Up`
   .split(/\W+/).map(_=>_.trim())
function escapeRegex(string) {
    return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
var input = prompt();
console.log(input.length==0?null:input.trim().split(/\s+/)
            .map(
              (s=>abr.filter(
                a=>(new RegExp('^'+escapeRegex(s),'i'))
                  .test(a)&&s.length>=a.match(/^[A-Z]+/)[0].length
				  )[0])
				)
            .map(_=>typeof _=="undefined"?"*error*":_).join(' ')
			)


Abbreviations, simple

The use of   abbreviations    (also sometimes called synonyms, nicknames, AKAs, or aliases)    can be an
easy way to add flexibility when specifying or using commands, sub-commands, options, etc.

For this task, the following   ''command table''   will be used:
    add 1  alter 3  backup 2  bottom 1  Cappend 2  change 1  Schange  Cinsert 2  Clast 3
    compress 4 copy 2 count 3 Coverlay 3 cursor 3  delete 3 Cdelete 2  down 1  duplicate
    3 xEdit 1 expand 3 extract 3  find 1 Nfind 2 Nfindup 6 NfUP 3 Cfind 2 findUP 3 fUP 2
    forward 2  get  help 1 hexType 4  input 1 powerInput 3  join 1 split 2 spltJOIN load
    locate 1 Clocate 2 lowerCase 3 upperCase 3 Lprefix 2  macro  merge 2 modify 3 move 2
    msg  next 1 overlay 1 parse preserve 4 purge 3 put putD query 1 quit  read recover 3
    refresh renum 3 repeat 3 replace 1 Creplace 2 reset 3 restore 4 rgtLEFT right 2 left
    2  save  set  shift 2  si  sort  sos  stack 3 status 4 top  transfer 3  type 1  up 1

Notes concerning the above   ''command table'':
::*   it can be thought of as one long literal string   (with blanks at end-of-lines)
::*   it may have superfluous blanks
::*   it may be in any case (lower/upper/mixed)
::*   the order of the words in the   ''command table''   must be preserved as shown
::*   the user input(s) may be in any case (upper/lower/mixed)
::*   commands will be restricted to the Latin alphabet   (A --> Z,   a --> z)
::*   a command is followed by an optional number, which indicates the minimum abbreviation
::*   A valid abbreviation is a word that has:
:::*   at least the minimum length of the word's minimum number in the ''command table''
:::*   compares equal (regardless of case) to the leading characters of the word in the ''command table''
:::*   a length not longer than the word in the ''command table''
::::*   '''ALT''',   '''aLt''',   '''ALTE''',   and   '''ALTER'''   are all abbreviations of   '''ALTER 3'''
::::*   '''AL''',   '''ALF''',   '''ALTERS''',   '''TER''',   and   '''A'''    aren't valid abbreviations of   '''ALTER 3'''
::::*   The   '''3'''   indicates that any abbreviation for   '''ALTER'''   must be at least three characters
::::*   Any word longer than five characters can't be an abbreviation for   '''ALTER'''
::::*   '''o''',    '''ov''',    '''oVe''',    '''over''',    '''overL''',    '''overla'''   are all acceptable abbreviations for   '''overlay 1'''
::*   if there isn't a number after the command,   then there isn't an abbreviation permitted

;Task:
::*   The command table needn't be verified/validated.
::*   Write a function to validate if the user "words"   (given as input)   are valid   (in the ''command table'').
::*   If the word   is   valid,   then return the full uppercase version of that "word".
::*   If the word        isn't     valid,   then return the lowercase string:    '''*error*'''        (7 characters).
::*   A blank input   (or a null input)   should return a null string.
::*   Show all output here.

;An example test case to be used for this task:
For a user string of:
  riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin
the computer program should return the string:
  RIGHT REPEAT *error* PUT MOVE RESTORE *error* *error* *error* POWERINPUT

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

    // withExpansions :: [(String, Int)] -> String -> String
    const withExpansions = tbl => s =>
        unwords(map(expanded(tbl), words(s)));

    // expanded :: [(String, Int)] -> String -> String
    const expanded = tbl => s => {
        const
            lng = s.length,
            u = toUpper(s),
            p = wn => {
                const [w, n] = Array.from(wn);
                return lng >= n && isPrefixOf(u, w);
            }
        return maybe(
            '*error*',
            fst,
            0 < lng ? (
                find(p, tbl)
            ) : Just(Tuple([], 0))
        );
    };

    // cmdsFromString :: String -> [(String, Int)]
    const cmdsFromString = s =>
        fst(foldr(
            (w, a) => {
                const [xs, n] = Array.from(a);
                return isDigit(head(w)) ? (
                    Tuple(xs, parseInt(w, 10))
                ) : Tuple(
                    [Tuple(toUpper(w), n)].concat(xs),
                    0
                );
            },
            Tuple([], 0),
            words(s)
        ));

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

        // table :: [(String, Int)]
        const table = cmdsFromString(
            `add 1  alter 3  backup 2  bottom 1  Cappend 2  change 1
            Schange Cinsert 2  Clast 3 compress 4 copy 2 count 3 Coverlay 3
            cursor 3  delete 3 Cdelete 2  down 1  duplicate 3 xEdit 1 expand 3
            extract 3  find 1 Nfind 2 Nfindup 6 NfUP 3 Cfind 2 findUP 3 fUP 2
            forward 2  get  help 1 hexType 4 input 1 powerInput 3  join 1
            split 2 spltJOIN load locate 1 Clocate 2 lowerCase 3 upperCase 3
            Lprefix 2  macro  merge 2 modify 3 move 2 msg  next 1 overlay 1
            parse preserve 4 purge 3 put putD query 1 quit read recover 3
            refresh renum 3 repeat 3 replace 1 Creplace 2 reset 3 restore 4
            rgtLEFT right 2 left 2  save  set  shift 2  si  sort  sos stack 3
            status 4 top  transfer 3  type 1  up 1`
        );

        return fTable(
            'Abbreviation tests:\n',
            s => "'" + s + "'",
            s => "\n\t'" + s + "'",
            withExpansions(table),
            [
                'riG   rePEAT copies  put mo   rest    types   fup.    6      poweRin',
                ''
            ]
        );
    };

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

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

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

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

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

    // find :: (a -> Bool) -> [a] -> Maybe a
    const find = (p, xs) => {
        for (let i = 0, lng = xs.length; i < lng; i++) {
            if (p(xs[i])) return Just(xs[i]);
        }
        return Nothing();
    };

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

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

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

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

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

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

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

    // isPrefixOf takes two lists or strings and returns
    // true iff the first is a prefix of the second.

    // isPrefixOf :: [a] -> [a] -> Bool
    // isPrefixOf :: String -> String -> Bool
    const isPrefixOf = (xs, ys) => {
        const go = (xs, ys) => {
            const intX = xs.length;
            return 0 < intX ? (
                ys.length >= intX ? xs[0] === ys[0] && go(
                    xs.slice(1), ys.slice(1)
                ) : false
            ) : true;
        };
        return 'string' !== typeof xs ? (
            go(xs, ys)
        ) : ys.startsWith(xs);
    };

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

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

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

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

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

    // maybe :: b -> (a -> b) -> Maybe a -> b
    const maybe = (v, f, m) =>
        m.Nothing ? v : f(m.Just);

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

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

    // toUpper :: String -> String
    const toUpper = s => s.toLocaleUpperCase();

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

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

    // words :: String -> [String]
    const words = s => s.split(/\s+/);

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

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

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


Abundant odd numbers

An Abundant number is a number '''n''' for which the   ''sum of divisors''   '''s(n) > 2n''',
or,   equivalently,   the   ''sum of proper divisors''   (or aliquot sum)       '''s(n) > n'''.

;E.G.:
'''12'''   is abundant, it has the proper divisors     '''1,2,3,4 & 6'''     which sum to   '''16'''   ( > '''12''' or '''n''');
       or alternately,   has the sigma sum of   '''1,2,3,4,6 & 12'''   which sum to   '''28'''   ( > '''24''' or '''2n''').

Abundant numbers are common, though '''even''' abundant numbers seem to be much more common than '''odd''' abundant numbers.

To make things more interesting, this task is specifically about finding   ''odd abundant numbers''.

;Task
*Find and display here: at least the first 25 abundant odd numbers and either their proper divisor sum or sigma sum.
*Find and display here: the one thousandth abundant odd number and either its proper divisor sum or sigma sum.
*Find and display here: the first abundant odd number greater than one billion (109) and either its proper divisor sum or sigma sum.

;References:
:*   OEIS:A005231: Odd abundant numbers (odd numbers n whose sum of divisors exceeds 2n)
:*   American Journal of Mathematics, Vol. 35, No. 4 (Oct., 1913), pp. 413-422 - Finiteness of the Odd Perfect and Primitive Abundant Numbers with n Distinct Prime Factors (LE Dickson)

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

        // abundantTuple :: Int -> [(Int, Int)]
        const abundantTuple = n => {
            // Either a list containing the tuple of N
            // and its divisor sum (if n is abundant),
            // or otherwise an empty list.
            const x = divisorSum(n);
            return n < x ? ([
                Tuple(n)(x)
            ]) : [];
        };

        // divisorSum :: Int -> Int
        const divisorSum = n => {
            // Sum of the divisors of n.
            const
                floatRoot = Math.sqrt(n),
                intRoot = Math.floor(floatRoot),
                lows = filter(x => 0 === n % x)(
                    enumFromTo(1)(intRoot)
                );
            return sum(lows.concat(map(quot(n))(
                intRoot === floatRoot ? (
                    lows.slice(1, -1)
                ) : lows.slice(1)
            )));
        };

        // TEST ---------------------------------------
        console.log(
            'First 25 abundant odd numbers, with their divisor sums:'
        )
        console.log(unlines(map(showTuple)(
            take(25)(
                concatMapGen(abundantTuple)(
                    enumFromThen(1)(3)
                )
            )
        )));
        console.log(
            '\n\n1000th abundant odd number, with its divisor sum:'
        )
        console.log(showTuple(
            take(1)(drop(999)(
                concatMapGen(abundantTuple)(
                    enumFromThen(1)(3)
                )
            ))[0]
        ))
        console.log(
            '\n\nFirst abundant odd number above 10^9, with divisor sum:'
        )
        const billion = Math.pow(10, 9);
        console.log(showTuple(
            take(1)(
                concatMapGen(abundantTuple)(
                    enumFromThen(1 + billion)(3 + billion)
                )
            )[0]
        ))
    };

    // GENERAL REUSABLE FUNCTIONS -------------------------

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

    // concatMapGen :: (a -> [b]) -> Gen [a] -> Gen [b]
    const concatMapGen = f =>
        function*(xs) {
            let
                x = xs.next(),
                v = undefined;
            while (!x.done) {
                v = f(x.value);
                if (0 < v.length) {
                    yield v[0];
                }
                x = xs.next();
            }
        };

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

    // dropAround :: (a -> Bool) -> [a] -> [a]
    // dropAround :: (Char -> Bool) -> String -> String
    const dropAround = p => xs => dropWhile(p)(
        dropWhileEnd(p)(xs)
    );

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

    // dropWhileEnd :: (a -> Bool) -> [a] -> [a]
    // dropWhileEnd :: (Char -> Bool) -> String -> String
    const dropWhileEnd = p => xs => {
        let i = xs.length;
        while (i-- && p(xs[i])) {}
        return xs.slice(0, i + 1);
    };

    // enumFromThen :: Int -> Int -> Gen [Int]
    const enumFromThen = x =>
        // A non-finite stream of integers,
        // starting with x and y, and continuing
        // with the same interval.
        function*(y) {
            const d = y - x;
            let v = y + d;
            yield x;
            yield y;
            while (true) {
                yield v;
                v = d + v;
            }
        };

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

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

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

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

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

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

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

    // showTuple :: Tuple -> String
    const showTuple = tpl =>
        '(' + enumFromTo(0)(tpl.length - 1)
        .map(x => unQuoted(show(tpl[x])))
        .join(',') + ')';

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

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

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

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

    // unQuoted :: String -> String
    const unQuoted = s =>
        dropAround(x => 34 === x.codePointAt(0))(
            s
        );

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


Accumulator factory

{{requires|Mutable State}}

A problem posed by Paul Graham is that of creating a function that takes a single (numeric) argument and which returns another function that is an accumulator. The returned accumulator function in turn also takes a single numeric argument, and returns the sum of all the numeric values passed in so far to that accumulator (including the initial value passed when the accumulator was created).

;Rules:
The detailed rules are at http://paulgraham.com/accgensub.html and are reproduced here for simplicity (with additions in ''small italic text'').
:Before you submit an example, make sure the function

:# Takes a number n and returns a function (lets call it g), that takes a number i, and returns n incremented by the accumulation of i from every call of function g(i).Although these exact function and parameter names need not be used
:# Works for any numeric type-- i.e. can take both ints and floats and returns functions that can take both ints and floats. (It is not enough simply to convert all input to floats. An accumulator that has only seen integers must return integers.) ''(i.e., if the language doesn't allow for numeric polymorphism, you have to use overloading or something like that)''
:# Generates functions that return the sum of every number ever passed to them, not just the most recent. ''(This requires a piece of state to hold the accumulated value, which in turn means that pure functional languages can't be used for this task.)''
:# Returns a real function, meaning something that you can use wherever you could use a function you had defined in the ordinary way in the text of your program. ''(Follow your language's conventions here.)''
:# Doesn't store the accumulated value or the returned functions in a way that could cause them to be inadvertently modified by other code. ''(No global variables or other such things.)''
: E.g. if after the example, you added the following code (in a made-up language) ''where the factory function is called foo'':
:: x = foo(1);
x(5);
foo(3);
print x(2.3);
: It should print 8.3. ''(There is no need to print the form of the accumulator function returned by foo(3); it's not part of the task at all.)''

;Task:
Create a function that implements the described rules.

It need not handle any special error cases not described above. The simplest way to implement the task as described is typically to use a closure, providing the language supports them.

Where it is not possible to hold exactly to the constraints above, describe the deviations.

Solution:
function accumulator(sum) {
  return function(n) {
    return sum += n;
  }
}
var x = accumulator(1);
x(5);
console.log(accumulator(3).toString() + '<br>');
console.log(x(2.3));


Amb

Define and give an example of the Amb operator.

The Amb operator (short for "ambiguous") expresses nondeterminism. This doesn't refer to randomness (as in "nondeterministic universe") but is closely related to the term as it is used in automata theory ("non-deterministic finite automaton").

The Amb operator takes a variable number of expressions (or values if that's simpler in the language) and yields a correct one which will satisfy a constraint in some future computation, thereby avoiding failure.

Problems whose solution the Amb operator naturally expresses can be approached with other tools, such as explicit nested iterations over data sets, or with pattern matching. By contrast, the Amb operator appears integrated into the language. Invocations of Amb are not wrapped in any visible loops or other search patterns; they appear to be independent.

Essentially Amb(x, y, z) splits the computation into three possible futures: a future in which the value x is yielded, a future in which the value y is yielded and a future in which the value z is yielded. The future which leads to a successful subsequent computation is chosen. The other "parallel universes" somehow go away.   Amb called with no arguments fails.

For simplicity, one of the domain values usable with Amb may denote failure, if that is convenient. For instance, it is convenient if a Boolean false denotes failure, so that Amb(false) fails, and thus constraints can be expressed using Boolean expressions like Amb(x * y == 8) which unless x and y add to four.

A pseudo-code program which satisfies this constraint might look like:

let x = Amb(1, 2, 3)
let y = Amb(7, 6, 4, 5)
Amb(x * y = 8)
print x, y

The output is 2 4 because Amb(1, 2, 3) correctly chooses the future in which x has value 2, Amb(7, 6, 4, 5) chooses 4 and consequently Amb(x * y = 8) produces a success.

Alternatively, failure could be represented using strictly Amb():

unless x * y = 8 do Amb()

Or else Amb could take the form of two operators or functions: one for producing values and one for enforcing constraints:

let x = Ambsel(1, 2, 3)
let y = Ambsel(4, 5, 6)
Ambassert(x * y = 8)
print x, y

where Ambassert behaves like Amb() if the Boolean expression is false, otherwise it allows the future computation to take place, without yielding any value.

The task is to somehow implement Amb, and demonstrate it with a program which chooses one word from each of the following four sets of character strings to generate a four-word sentence:

#"the" "that" "a"
#"frog" "elephant" "thing"
#"walked" "treaded" "grows"
#"slowly" "quickly"

The constraint to be satisfied is that the last character of each word (other than the last) is the same as the first character of its successor.

The only successful sentence is "that thing grows slowly"; other combinations do not satisfy the constraint and thus fail.

The goal of this task isn't to simply process the four lists of words with explicit, deterministic program flow such as nested iteration, to trivially demonstrate the correct output. The goal is to implement the Amb operator, or a facsimile thereof that is possible within the language limitations.

Solution:
function ambRun(func) {
    var choices = [];
    var index;

    function amb(values) {
        if (values.length == 0) {
            fail();
        }
        if (index == choices.length) {
            choices.push({i: 0,
                          count: values.length});
        }
        var choice = choices[index++];
        return values[choice.i];
    }

    function fail() { throw fail; }

    while (true) {
        try {
            index = 0;
            return func(amb, fail);
        } catch (e) {
            if (e != fail) {
                throw e;
            }
            var choice;
            while ((choice = choices.pop()) && ++choice.i == choice.count) {}
            if (choice == undefined) {
                return undefined;
            }
            choices.push(choice);
        }
    }
}

ambRun(function(amb, fail) {
    function linked(s1, s2) {
        return s1.slice(-1) == s2.slice(0, 1);
    }

    var w1 = amb(["the", "that", "a"]);
    var w2 = amb(["frog", "elephant", "thing"]);
    if (!linked(w1, w2)) fail();

    var w3 = amb(["walked", "treaded", "grows"]);
    if (!linked(w2, w3)) fail();

    var w4 = amb(["slowly", "quickly"]);
    if (!linked(w3, w4)) fail();

    return [w1, w2, w3, w4].join(' ');
});  // "that thing grows slowly"


Anagrams/Deranged anagrams

Two or more words are said to be anagrams if they have the same characters, but in a different order.

By analogy with derangements we define a  ''deranged anagram'' as two words with the same characters, but in which the same character does ''not'' appear in the same position in both words.

;Task

Use the word list at unixdict to find and display the longest deranged anagram.

;Related
* [[Permutations/Derangements]]
* Best shuffle

{{Related tasks/Word plays}}

Solution:
#!/usr/bin/env js

function main() {
    var wordList = read('unixdict.txt').split(/\s+/);
    var anagrams = findAnagrams(wordList);
    var derangedAnagrams = findDerangedAnagrams(anagrams);
    var longestPair = findLongestDerangedPair(derangedAnagrams);
    print(longestPair.join(' '));

}

function findLongestDerangedPair(danas) {
    var longestLen = danas[0][0].length;
    var longestPair = danas[0];
    for (var i in danas) {
        if (danas[i][0].length > longestLen) {
            longestLen = danas[i][0].length;
            longestPair = danas[i];
        }
    }
    return longestPair;
}

function findDerangedAnagrams(anagrams) {
    var deranged = [];

    function isDeranged(w1, w2) {
        for (var c = 0; c < w1.length; c++) {
            if (w1[c] == w2[c]) {
                return false;
            }
        }
        return true;
    }

    function findDeranged(anas) {
        for (var a = 0; a < anas.length; a++) {
            for (var b = a + 1; b < anas.length; b++) {
                if (isDeranged(anas[a], anas[b])) {
                    deranged.push([anas[a], anas[b]]);
                }
            }
        }
    }

    for (var a in anagrams) {
        var anas = anagrams[a];
        findDeranged(anas);
    }

    return deranged;
}

function findAnagrams(wordList) {
    var anagrams = {};

    for (var wordNum in wordList) {
        var word = wordList[wordNum];
        var key = word.split('').sort().join('');
        if (!(key in anagrams)) {
            anagrams[key] = [];
        }
        anagrams[key].push(word);
    }

    for (var a in anagrams) {
        if (anagrams[a].length < 2) {
            delete(anagrams[a]);
        }
    }

    return anagrams;
}

main();


Angle difference between two bearings

Finding the angle between two bearings is often confusing.[https://stackoverflow.com/questions/16180595/find-the-angle-between-two-bearings]

;Task:
Find the angle which is the result of the subtraction '''b2 - b1''', where '''b1''' and '''b2''' are the bearings.

Input bearings are expressed in the range   '''-180'''   to   '''+180'''   degrees.
The  result  is also expressed in the range   '''-180'''   to   '''+180'''   degrees.

Compute the angle for the following pairs:
*  20 degrees ('''b1''') and 45 degrees ('''b2''')
* -45 and  45
* -85 and  90
* -95 and  90
* -45 and 125
* -45 and 145
*  29.4803 and  -88.6381
* -78.3251 and -159.036

;Optional extra:
Allow the input bearings to be any (finite) value.

;Test cases:
*  -70099.74233810938   and   29840.67437876723
* -165313.6666297357    and   33693.9894517456
*    1174.8380510598456 and -154146.66490124757
*   60175.77306795546   and   42213.07192354373

Solution:
function relativeBearing(b1Rad, b2Rad)
{
	b1y = Math.cos(b1Rad);
	b1x = Math.sin(b1Rad);
	b2y = Math.cos(b2Rad);
	b2x = Math.sin(b2Rad);
	crossp = b1y * b2x - b2y * b1x;
	dotp = b1x * b2x + b1y * b2y;
	if(crossp > 0.)
		return Math.acos(dotp);
	return -Math.acos(dotp);
}

function test()
{
	var deg2rad = 3.14159265/180.0;
	var rad2deg = 180.0/3.14159265;
	return "Input in -180 to +180 range\n"
		+relativeBearing(20.0*deg2rad, 45.0*deg2rad)*rad2deg+"\n"
		+relativeBearing(-45.0*deg2rad, 45.0*deg2rad)*rad2deg+"\n"
		+relativeBearing(-85.0*deg2rad, 90.0*deg2rad)*rad2deg+"\n"
		+relativeBearing(-95.0*deg2rad, 90.0*deg2rad)*rad2deg+"\n"
		+relativeBearing(-45.0*deg2rad, 125.0*deg2rad)*rad2deg+"\n"
		+relativeBearing(-45.0*deg2rad, 145.0*deg2rad)*rad2deg+"\n"

		+relativeBearing(29.4803*deg2rad, -88.6381*deg2rad)*rad2deg+"\n"
		+relativeBearing(-78.3251*deg2rad, -159.036*deg2rad)*rad2deg+"\n"

		+ "Input in wider range\n"
		+relativeBearing(-70099.74233810938*deg2rad, 29840.67437876723*deg2rad)*rad2deg+"\n"
		+relativeBearing(-165313.6666297357*deg2rad, 33693.9894517456*deg2rad)*rad2deg+"\n"
		+relativeBearing(1174.8380510598456*deg2rad, -154146.66490124757*deg2rad)*rad2deg+"\n"
		+relativeBearing(60175.77306795546*deg2rad, 42213.07192354373*deg2rad)*rad2deg+"\n";

}


Anti-primes

The anti-primes
(or highly composite numbers, sequence A002182 in the OEIS)
are the natural numbers with more factors than any smaller than itself.

;Task:
Generate and show here, the first twenty anti-primes.

;Related tasks:
:*   [[Factors of an integer]]
:*   [[Sieve of Eratosthenes]]

Solution:
function factors(n) {
  var factors = [];
  for (var i = 1; i <= n; i++) {
    if (n % i == 0) {
      factors.push(i);
    }
  }
  return factors;
}

function generateAntiprimes(n) {
  var antiprimes = [];
  var maxFactors = 0;
  for (var i = 1; antiprimes.length < n; i++) {
    var ifactors = factors(i);
    if (ifactors.length > maxFactors) {
      antiprimes.push(i);
      maxFactors = ifactors.length;
    }
  }
  return antiprimes;
}

function go() {
  var number = document.getElementById("n").value;
  document.body.removeChild(document.getElementById("result-list"));
  document.body.appendChild(showList(generateAntiprimes(number)));
}

function showList(array) {
  var list = document.createElement("ul");
  list.id = "result-list";
  for (var i = 0; i < array.length; i++) {
    var item = document.createElement("li");
    item.appendChild(document.createTextNode(array[i]));
    list.appendChild(item);
  }
  return list;
}


Arithmetic-geometric mean

{{wikipedia|Arithmetic-geometric mean}}

;Task:
Write a function to compute the arithmetic-geometric mean of two numbers.

The arithmetic-geometric mean of two numbers can be (usefully) denoted as \mathrm{agm}(a,g), and is equal to the limit of the sequence:
: a_0 = a; \qquad g_0 = g
: a_{n+1} = \tfrac{1}{2}(a_n + g_n); \quad g_{n+1} = \sqrt{a_n g_n}.
Since the limit of a_n-g_n tends (rapidly) to zero with iterations, this is an efficient method.

Demonstrate the function by calculating:
:\mathrm{agm}(1,1/\sqrt{2})

;Also see:
*   mathworld.wolfram.com/Arithmetic-Geometric Mean

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

    // ARITHMETIC-GEOMETRIC MEAN

    // agm :: Num a => a -> a -> a
    let agm = (a, g) => {
            let abs = Math.abs,
                sqrt = Math.sqrt;

            return until(
                    m => abs(m.an - m.gn) < tolerance,
                    m => {
                        return {
                            an: (m.an + m.gn) / 2,
                            gn: sqrt(m.an * m.gn)
                        };
                    }, {
                        an: (a + g) / 2,
                        gn: sqrt(a * g)
                    }
                )
                .an;
        },

        // GENERIC

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

    // TEST

    let tolerance = 0.000001;

    return agm(1, 1 / Math.sqrt(2));

})();


Arithmetic evaluation

Create a program which parses and evaluates arithmetic expressions.
;Requirements:
* An abstract-syntax tree (AST) for the expression must be created from parsing the input.
* The AST must be used in evaluation, also, so the input may not be directly evaluated (e.g. by calling eval or a similar language feature.)
* The expression will be a string or list of symbols like "(1+3)*7".
* The four symbols + - * / must be supported as binary operators with conventional precedence rules.
* Precedence-control parentheses must also be supported.

;Note:
For those who don't remember, mathematical precedence is as follows:
* Parentheses
* Multiplication/Division (left to right)
* Addition/Subtraction (left to right)

;C.f:
* [[24 game Player]].
* [[Parsing/RPN calculator algorithm]].
* [[Parsing/RPN to infix conversion]].

Solution:
function evalArithmeticExp(s) {
  s = s.replace(/\s/g,'').replace(/^\+/,'');
  var rePara = /\([^\(\)]*\)/;
  var exp = s.match(rePara);

  while (exp = s.match(rePara)) {
    s = s.replace(exp[0], evalExp(exp[0]));
  }
  return evalExp(s);

  function evalExp(s) {
    s = s.replace(/[\(\)]/g,'');
    var reMD = /\d+\.?\d*\s*[\*\/]\s*[+-]?\d+\.?\d*/;
    var reM = /\*/;
    var reAS = /-?\d+\.?\d*\s*[\+-]\s*[+-]?\d+\.?\d*/;
    var reA  = /\d\+/;
    var exp;

    while (exp = s.match(reMD)) {
      s = exp[0].match(reM)? s.replace(exp[0], multiply(exp[0])) : s.replace(exp[0], divide(exp[0]));
    }

    while (exp = s.match(reAS)) {
      s = exp[0].match(reA)? s.replace(exp[0], add(exp[0])) : s.replace(exp[0], subtract(exp[0]));
    }

    return '' + s;

    function multiply(s, b) {
      b = s.split('*');
      return b[0] * b[1];
    }

    function divide(s, b) {
      b = s.split('/');
      return b[0] / b[1];
    }

    function add(s, b) {
      s = s.replace(/^\+/,'').replace(/\++/,'+');
      b = s.split('+');
      return Number(b[0]) + Number(b[1]);
    }

    function subtract(s, b) {
      s = s.replace(/\+-|-\+/g,'-');

      if (s.match(/--/)) {
        return add(s.replace(/--/,'+'));
      }
      b = s.split('-');
      return b.length == 3? -1 * b[1] - b[2] : b[0] - b[1];
    }
  }
}


Array length

Determine the amount of elements in an array.

As an example use an array holding the strings 'apple' and 'orange'.

Solution:
function last(list, defaultValue) {
   return list.length ?list[list.length-1] :defaultValue;
}


Ascending primes

Generate and show all primes with strictly ascending decimal digits.

Aside: Try solving without peeking at existing solutions. I had a weird idea for generating
a prime sieve faster, which needless to say didn't pan out. The solution may be p(r)etty trivial
but generating them quickly is at least mildly interesting.
Tip: filtering all 7,027,260 primes below 123,456,789 probably won't kill you, but there is
at least one significantly better and much faster way, needing a mere 511 odd/prime tests.

;See also
;* OEIS:A052015 - Primes with distinct digits in ascending order

;Related:
*[[Primes with digits in nondecreasing order]] (infinite series allowing duplicate digits, whereas this isn't and doesn't)
*[[Pandigital prime]] (whereas this is the smallest, with gaps in the used digits being permitted)

Solution:
<!DOCTYPE html>
<html>
<body>
  <noscript>
    No script, no fun. Turn on Javascript on.
  </noscript>

  <script>
  (()=>{

    function isPrime(n) {
      if (n == 2)
          return true;
      if (n == 1 || n % 2 == 0)
          return false;
      root = Math.sqrt(n)
      for (let k = 3; k <= root; k += 2)
          if (n % k == 0)
              return false;
      return true;
    }

    let queue = [];
    let primes = [];

    for (let k = 1; k <= 9; k++)
      queue.push(k);

    while (queue.length != 0)
    {
        let n = queue.shift();
        if (isPrime(n))
          primes.push(n);
        for (let k = n % 10 + 1; k <= 9; k++)
          queue.push(n * 10 + k);
    }

    document.writeln(primes);

  })();
  </script>

</body>
</html>


Associative array/Merging

Define two associative arrays, where one represents the following "base" data:

::::: {| class="wikitable"
|+
| '''Key''' || '''Value'''
|-
| "name" || "Rocket Skates"
|-
| "price" || 12.75
|-
| "color" || "yellow"
|}

And the other represents "update" data:

::::: {| class="wikitable"
|+
| '''Key''' || '''Value'''
|-
| "price" || 15.25
|-
| "color" || "red"
|-
| "year" || 1974
|}

Merge these into a new associative array that contains every key found in either of the source ones.  Each key should map to the value in the second (update) table if that exists, or else to the value in the first (base) table.  If possible, do this in a way that does not mutate the original two associative arrays.  Obviously this should be done in a way that would work for any data, not just the specific data given here, but in this example the result should be:

::::: {| class="wikitable"
|+
| '''Key''' || '''Value'''
|-
| "name" || "Rocket Skates"
|-
| "price" || 15.25
|-
| "color" || "red"
|-
| "year" || 1974
|}

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

    console.log(JSON.stringify(
        Object.assign({}, // Fresh dictionary.
            { // Base.
                "name": "Rocket Skates",
                "price": 12.75,
                "color": "yellow"
            }, { // Update.
                "price": 15.25,
                "color": "red",
                "year": 1974
            }
        ),
        null, 2
    ))
})();