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:
#include <cstdlib>   // for rand
#include <algorithm> // for random_shuffle
#include <iostream>  // for output

using namespace std;

class cupboard {
public:
    cupboard() {
        for (int i = 0; i < 100; i++)
            drawers[i] = i;
        random_shuffle(drawers, drawers + 100);
    }

    bool playRandom();
    bool playOptimal();

private:
    int drawers[100];
};

bool cupboard::playRandom() {
    bool openedDrawers[100] = { 0 };
    for (int prisonerNum = 0; prisonerNum < 100; prisonerNum++) { // loops through prisoners numbered 0 through 99
        bool prisonerSuccess = false;
        for (int i = 0; i < 100 / 2; i++) {  // loops through 50 draws for each prisoner
            int drawerNum = rand() % 100;
            if (!openedDrawers[drawerNum]) {
                openedDrawers[drawerNum] = true;
                break;
            }
            if (drawers[drawerNum] == prisonerNum) {
                prisonerSuccess = true;
                break;
            }
        }
        if (!prisonerSuccess)
            return false;
    }
    return true;
}

bool cupboard::playOptimal() {
    for (int prisonerNum = 0; prisonerNum < 100; prisonerNum++) {
        bool prisonerSuccess = false;
        int checkDrawerNum = prisonerNum;
        for (int i = 0; i < 100 / 2; i++) {
            if (drawers[checkDrawerNum] == prisonerNum) {
                prisonerSuccess = true;
                break;
            } else
                checkDrawerNum = drawers[checkDrawerNum];
        }
        if (!prisonerSuccess)
            return false;
    }
    return true;
}

double simulate(char strategy) {
    int numberOfSuccesses = 0;
    for (int i = 0; i < 10000; i++) {
        cupboard d;
        if ((strategy == 'R' && d.playRandom()) || (strategy == 'O' && d.playOptimal())) // will run playRandom or playOptimal but not both because of short-circuit evaluation
            numberOfSuccesses++;
    }

    return numberOfSuccesses * 100.0 / 10000;
}

int main() {
    cout << "Random strategy:  " << simulate('R') << " %" << endl;
    cout << "Optimal strategy: " << simulate('O') << " %" << endl;
    system("PAUSE"); // for Windows
    return 0;
}


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:
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <iostream>
class p15 {
public :
    void play() {
        bool p = true;
        std::string a;
        while( p ) {
            createBrd();
            while( !isDone() ) { drawBrd();getMove(); }
            drawBrd();
            std::cout << "\n\nCongratulations!\nPlay again (Y/N)?";
            std::cin >> a; if( a != "Y" && a != "y" ) break;
        }
    }
private:
    void createBrd() {
        int i = 1; std::vector<int> v;
        for( ; i < 16; i++ ) { brd[i - 1] = i; }
        brd[15] = 0; x = y = 3;
        for( i = 0; i < 1000; i++ ) {
            getCandidates( v );
            move( v[rand() % v.size()] );
            v.clear();
        }
    }
    void move( int d ) {
        int t = x + y * 4;
        switch( d ) {
            case 1: y--; break;
            case 2: x++; break;
            case 4: y++; break;
            case 8: x--;
        }
        brd[t] = brd[x + y * 4];
        brd[x + y * 4] = 0;
    }
    void getCandidates( std::vector<int>& v ) {
        if( x < 3 ) v.push_back( 2 ); if( x > 0 ) v.push_back( 8 );
        if( y < 3 ) v.push_back( 4 ); if( y > 0 ) v.push_back( 1 );
    }
    void drawBrd() {
        int r; std::cout << "\n\n";
        for( int y = 0; y < 4; y++ ) {
            std::cout << "+----+----+----+----+\n";
            for( int x = 0; x < 4; x++ ) {
                r = brd[x + y * 4];
                std::cout << "| ";
                if( r < 10 ) std::cout << " ";
                if( !r ) std::cout << "  ";
                else std::cout << r << " ";
            }
            std::cout << "|\n";
        }
        std::cout << "+----+----+----+----+\n";
    }
    void getMove() {
        std::vector<int> v; getCandidates( v );
        std::vector<int> p; getTiles( p, v ); unsigned int i;
        while( true ) {
            std::cout << "\nPossible moves: ";
            for( i = 0; i < p.size(); i++ ) std::cout << p[i] << " ";
            int z; std::cin >> z;
            for( i = 0; i < p.size(); i++ )
                if( z == p[i] ) { move( v[i] ); return; }
        }
    }
    void getTiles( std::vector<int>& p, std::vector<int>& v ) {
        for( unsigned int t = 0; t < v.size(); t++ ) {
            int xx = x, yy = y;
            switch( v[t] ) {
                case 1: yy--; break;
                case 2: xx++; break;
                case 4: yy++; break;
                case 8: xx--;
            }
            p.push_back( brd[xx + yy * 4] );
        }
    }
    bool isDone() {
        for( int i = 0; i < 15; i++ ) {
            if( brd[i] != i + 1 ) return false;
        }
        return true;
    }
    int brd[16], x, y;
};
int main( int argc, char* argv[] ) {
    srand( ( unsigned )time( 0 ) );
    p15 p; p.play(); return 0;
}


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:
/**
 *  Game 21 - an example in C++ language for Rosseta Code.
 *
 *  This version is an example of MVP architecture. The user input, as well as
 *  the AI opponent, is handled by separate passive subclasses of abstract class
 *  named Controller. It can be noticed that the architecture support OCP,
 *  for an example the AI module can be "easily" replaced by another AI etc.
 *
 *  BTW, it would be better to place each class in its own file. But it would
 *  be less convinient for Rosseta Code, where "one solution" mean "one file".
 */

#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
#include <limits>

using namespace std;

#define _(STR) STR

class Model
{
protected:

    int oldTotal;
    int newTotal;
    int lastMove;

public:

    static const int GOAL = 21;
    static const int NUMBER_OF_PLAYERS = 2;

    Model()
    {
        newTotal = 0;
        oldTotal = 0;
        lastMove = 0;
    }

    void update(int move)
    {
        oldTotal = newTotal;
        newTotal = oldTotal + move;
        lastMove = move;
    }

    int getOldTotal()
    {
        return oldTotal;
    }

    int getNewTotal()
    {
        return newTotal;
    }

    int getLastMove()
    {
        return lastMove;
    }

    bool isEndGame()
    {
        return newTotal == GOAL;
    }
};

class View
{
public:

    void update(string comment, Model* model)
    {
        cout << setw(8) << comment << ": "
            << model->getNewTotal()
            << " = "
            << model->getOldTotal()
            << " + "
            << model->getLastMove() << endl
            << endl;
    }

    void newGame(string player)
    {
        cout << _("----NEW GAME----") << endl
            << endl
            << _("The running total is currently zero.") << endl
            << endl
            << _("The first move is ") << player << _(" move.") << endl
            << endl;
    }

    void endGame(string name)
    {
        cout << endl << _("The winner is ") << name << _(".") << endl
            << endl
            << endl;
    }
};

class Controller
{
public:

    virtual string getName() = 0;
    virtual int getMove(Model* model) = 0;
};

class AI : public Controller
{
public:

    string getName()
    {
        return _("AI");
    }

    int getMove(Model* model)
    {
        int n = model->getNewTotal();
        for (int i = 1; i <= 3; i++)
            if (n + i == Model::GOAL)
                return i;
        for (int i = 1; i <= 3; i++)
            if ((n + i - 1) % 4 == 0)
                return i;
        return 1 + rand() % 3;
    }
};

class Human : public Controller
{
public:

    string getName()
    {
        return _("human");
    }

    int getMove(Model* model)
    {
        int n = model->getNewTotal();
        int value;
        while (true) {
            if (n == Model::GOAL - 1)
                cout << _("enter 1 to play (or enter 0 to exit game): ");
            else if (n == Model::GOAL - 2)
                cout << _("enter 1 or 2 to play (or enter 0 to exit game): ");
            else
                cout << _("enter 1 or 2 or 3 to play (or enter 0 to exit game): ");
            cin >> value;
            if (!cin.fail()) {
                if (value == 0)
                    exit(0);
                else if (value >= 1 && value <= 3 && n + value <= Model::GOAL)
                {
                    cout << endl;
                    return value;
                }
            }
            cout << _("Your answer is not a valid choice.") << endl;
            cin.clear();
            cin.ignore((streamsize)numeric_limits<int>::max, '\n');
        }
    }
};

class Presenter
{
protected:

    Model* model;
    View* view;
    Controller** controllers;

public:

    Presenter(Model* model, View* view, Controller** controllers)
    {
        this->model = model;
        this->view = view;
        this->controllers = controllers;
    }

    void run()
    {
        int player = rand() % Model::NUMBER_OF_PLAYERS;
        view->newGame(controllers[player]->getName());

        while (true)
        {
            Controller* controller = controllers[player];
            model->update(controller->getMove(model));
            view->update(controller->getName(), model);
            if (model->isEndGame())
            {
                view->endGame(controllers[player]->getName());
                break;
            }
            player = (player + 1) % Model::NUMBER_OF_PLAYERS;
        }
    }
};

int main(int argc, char* argv)
{
    srand(time(NULL));

    while (true)
    {
        Model* model = new Model();
        View* view = new View();
        Controller* controllers[Model::NUMBER_OF_PLAYERS];
        controllers[0] = new Human();
        for (int i = 1; i < Model::NUMBER_OF_PLAYERS; i++)
            controllers[i] = new AI();
        Presenter* presenter = new Presenter(model, view, controllers);

        presenter->run();

        delete model;
        delete view;
        delete controllers[0];
        delete controllers[1];
        delete presenter;
    }
    return EXIT_SUCCESS; // dead code
}


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:
#include <random>
#include <iostream>
#include <stack>
#include <set>
#include <string>
#include <functional>
using namespace std;

class RPNParse
{
public:
  stack<double> stk;
  multiset<int> digits;

  void op(function<double(double,double)> f)
  {
    if(stk.size() < 2)
      throw "Improperly written expression";
    int b = stk.top(); stk.pop();
    int a = stk.top(); stk.pop();
    stk.push(f(a, b));
  }

  void parse(char c)
  {
    if(c >= '0' && c <= '9')
    {
      stk.push(c - '0');
      digits.insert(c - '0');
    }
    else if(c == '+')
      op([](double a, double b) {return a+b;});
    else if(c == '-')
      op([](double a, double b) {return a-b;});
    else if(c == '*')
      op([](double a, double b) {return a*b;});
    else if(c == '/')
      op([](double a, double b) {return a/b;});
  }

  void parse(string s)
  {
    for(int i = 0; i < s.size(); ++i)
      parse(s[i]);
  }

  double getResult()
  {
    if(stk.size() != 1)
      throw "Improperly written expression";
    return stk.top();
  }
};

int main()
{
  random_device seed;
  mt19937 engine(seed());
  uniform_int_distribution<> distribution(1, 9);
  auto rnd = bind(distribution, engine);

  multiset<int> digits;
  cout << "Make 24 with the digits: ";
  for(int i = 0; i < 4; ++i)
  {
    int n = rnd();
    cout << " " << n;
    digits.insert(n);
  }
  cout << endl;

  RPNParse parser;

  try
  {
    string input;
    getline(cin, input);
    parser.parse(input);

    if(digits != parser.digits)
      cout << "Error: Not using the given digits" << endl;
    else
    {
      double r = parser.getResult();
      cout << "Result: " << r << endl;

      if(r > 23.999 && r < 24.001)
        cout << "Good job!" << endl;
      else
        cout << "Try again." << endl;
    }
  }
  catch(char* e)
  {
    cout << "Error: " << e << endl;
  }
  return 0;
}


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:
//C++14/17
#include <algorithm>//std::for_each
#include <iostream> //std::cout
#include <numeric>  //std::iota
#include <vector>   //std::vector, save solutions
#include <list>     //std::list, for fast erase

using std::begin, std::end, std::for_each;

//Generates all the valid solutions for the problem in the specified range [from, to)
std::list<std::vector<int>> combinations(int from, int to)
{
    if (from > to)
        return {};                          //Return nothing if limits are invalid

    auto pool = std::vector<int>(to - from);//Here we'll save our values
    std::iota(begin(pool), end(pool), from);//Populates pool

    auto solutions = std::list<std::vector<int>>{};   //List for the solutions

    //Brute-force calculation of valid values...
    for (auto a : pool)
        for (auto b : pool)
            for (auto c : pool)
                for (auto d : pool)
                    for (auto e : pool)
                        for (auto f : pool)
                            for (auto g : pool)
                                if ( a      == c + d
                                  && b + c  == e + f
                                  && d + e  ==     g )
                                    solutions.push_back({a, b, c, d, e, f, g});
    return solutions;
}

//Filter the list generated from "combinations" and return only lists with no repetitions
std::list<std::vector<int>> filter_unique(int from, int to)
{
    //Helper lambda to check repetitions:
    //If the count is > 1 for an element, there must be a repetition inside the range
    auto has_non_unique_values = [](const auto & range, auto target)
    {
        return std::count( begin(range), end(range), target) > 1;
    };

    //Generates all the solutions...
    auto results = combinations(from, to);

    //For each solution, find duplicates inside
    for (auto subrange = cbegin(results); subrange != cend(results); ++subrange)
    {
        bool repetition = false;

        //If some element is repeated, repetition becomes true
        for (auto x : *subrange)
            repetition |= has_non_unique_values(*subrange, x);

        if (repetition)    //If repetition is true, remove the current subrange from the list
        {
            results.erase(subrange);        //Deletes subrange from solutions
            --subrange;                     //Rewind to the last subrange analysed
        }
    }

    return results; //Finally return remaining results
}

template <class Container> //Template for the sake of simplicity
inline void print_range(const Container & c)
{
    for (const auto & subrange : c)
    {
        std::cout << "[";
        for (auto elem : subrange)
            std::cout << elem << ' ';
        std::cout << "\b]\n";
    }
}

int main()
{
    std::cout << "Unique-numbers combinations in range 1-7:\n";
    auto solution1 = filter_unique(1, 8);
    print_range(solution1);
    std::cout << "\nUnique-numbers combinations in range 3-9:\n";
    auto solution2 = filter_unique(3,10);
    print_range(solution2);
    std::cout << "\nNumber of combinations in range 0-9: "
              << combinations(0, 10).size() << "." << std::endl;

    return 0;
}


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:
// Calculate hypotenuse n of OTT assuming only nothingness, unity, and hyp[n-1] if n>1
// Nigel Galloway, May 6th., 2013
#include <gmpxx.h>
int N{123456};
mpz_class hyp[N-3];
const mpz_class G(const int n,const int g){return g>n?0:(g==1 or n-g<2)?1:hyp[n-g-2];};
void G_hyp(const int n){for(int i=0;i<N-2*n-1;i++) n==1?hyp[n-1+i]=1+G(i+n+1,n+1):hyp[n-1+i]+=G(i+n+1,n+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
 |}

Solution:
// Input file: input.txt
// Output file: output.txt
#include <fstream>
using namespace std;
int main()
{
   ifstream in("input.txt");
   ofstream out("output.txt");
   int a, b;
   in >> a >> b;
   out << a + b << endl;
   return 0;
}


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:
#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <cctype>

typedef std::pair<char,char> item_t;
typedef std::vector<item_t> list_t;

bool can_make_word(const std::string& w, const list_t& vals) {
    std::set<uint32_t> used;
    while (used.size() < w.size()) {
        const char c = toupper(w[used.size()]);
        uint32_t x = used.size();
        for (uint32_t i = 0, ii = vals.size(); i < ii; ++i) {
            if (used.find(i) == used.end()) {
                if (toupper(vals[i].first) == c || toupper(vals[i].second) == c) {
                    used.insert(i);
                    break;
                }
            }
        }
        if (x == used.size()) break;
    }
    return used.size() == w.size();
}

int main() {
    list_t vals{ {'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'} };
    std::vector<std::string> words{"A","BARK","BOOK","TREAT","COMMON","SQUAD","CONFUSE"};
    for (const std::string& w : words) {
        std::cout << w << ": " << std::boolalpha << can_make_word(w,vals) << ".\n";
    }
}


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:
#include <array>
#include <bitset>
#include <iostream>

using namespace std;

struct FieldDetails {string_view Name; int NumBits;};

// parses the ASCII diagram and returns the field name, bit sizes, and the
// total byte size
template <const char *T> consteval auto ParseDiagram()
{
    // trim the ASCII diagram text
    constexpr string_view rawArt(T);
    constexpr auto firstBar = rawArt.find("|");
    constexpr auto lastBar = rawArt.find_last_of("|");
    constexpr auto art = rawArt.substr(firstBar, lastBar - firstBar);
    static_assert(firstBar < lastBar, "ASCII Table has no fields");

    // make an array for all of the fields
    constexpr auto numFields =
        count(rawArt.begin(), rawArt.end(), '|') -
        count(rawArt.begin(), rawArt.end(), '\n') / 2;
    array<FieldDetails, numFields> fields;

    // parse the diagram
    bool isValidDiagram = true;
    int startDiagramIndex = 0;
    int totalBits = 0;
    for(int i = 0; i < numFields; )
    {
        auto beginningBar = art.find("|", startDiagramIndex);
        auto endingBar = art.find("|", beginningBar + 1);
        auto field = art.substr(beginningBar + 1, endingBar - beginningBar - 1);
        if(field.find("-") == field.npos)
        {
            int numBits = (field.size() + 1) / 3;
            auto nameStart = field.find_first_not_of(" ");
            auto nameEnd = field.find_last_not_of(" ");
            if (nameStart > nameEnd || nameStart == string_view::npos)
            {
                // the table cannot be parsed
                isValidDiagram = false;
                field = ""sv;
            }
            else
            {
                field = field.substr(nameStart, 1 + nameEnd - nameStart);
            }
            fields[i++] = FieldDetails {field, numBits};
            totalBits += numBits;
        }
        startDiagramIndex = endingBar;
    }

    int numRawBytes = isValidDiagram ? (totalBits - 1) / 8 + 1 : 0;
    return make_pair(fields, numRawBytes);
}

// encode the values of the fields into a raw data array
template <const char *T> auto Encode(auto inputValues)
{
    constexpr auto parsedDiagram = ParseDiagram<T>();
    static_assert(parsedDiagram.second > 0, "Invalid ASCII talble");
    array<unsigned char, parsedDiagram.second> data;

    int startBit = 0;
    int i = 0;
    for(auto value : inputValues)
    {
        const auto &field = parsedDiagram.first[i++];
        int remainingValueBits = field.NumBits;
        while(remainingValueBits > 0)
        {
            // pack the bits from an input field into the data array
            auto [fieldStartByte, fieldStartBit] = div(startBit, 8);
            int unusedBits = 8 - fieldStartBit;
            int numBitsToEncode = min({unusedBits, 8, field.NumBits});
            int divisor = 1 << (remainingValueBits - numBitsToEncode);
            unsigned char bitsToEncode = value / divisor;
            data[fieldStartByte] <<= numBitsToEncode;
            data[fieldStartByte] |= bitsToEncode;
            value %= divisor;
            startBit += numBitsToEncode;
            remainingValueBits -= numBitsToEncode;
        }
    }

    return data;
}

// decode the raw data into the format of the ASCII diagram
template <const char *T> void Decode(auto data)
{
    cout << "Name      Bit Pattern\n";
    cout << "=======   ================\n";
    constexpr auto parsedDiagram = ParseDiagram<T>();
    static_assert(parsedDiagram.second > 0, "Invalid ASCII talble");

    int startBit = 0;
    for(const auto& field : parsedDiagram.first)
    {
        // unpack the bits from the data into a single field
        auto [fieldStartByte, fieldStartBit] = div(startBit, 8);
        unsigned char firstByte = data[fieldStartByte];
        firstByte <<= fieldStartBit;
        firstByte >>= fieldStartBit;
        int64_t value = firstByte;
        auto endBit = startBit + field.NumBits;
        auto [fieldEndByte, fieldEndBit] = div(endBit, 8);
        fieldEndByte = min(fieldEndByte, (int)(ssize(data) - 1));
        for(int index = fieldStartByte + 1; index <= fieldEndByte; index++)
        {
            value <<= 8;
            value += data[index];
        }
        value >>= fieldEndBit;
        startBit = endBit;

        cout << field.Name <<
            string_view("        ", (7 - field.Name.size())) << "   " <<
            string_view(bitset<64>(value).to_string()).substr(64 - field.NumBits, 64) <<  "\n";
    }

}

int main(void)
{
    static constexpr char art[] = R"(
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                      ID                       |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |QR|   Opcode  |AA|TC|RD|RA|   Z    |   RCODE   |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    QDCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ANCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    NSCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
    |                    ARCOUNT                    |
    +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+)";

    // using the table above, encode the data below
    auto rawData = Encode<art> (initializer_list<int64_t> {
        30791,
        0, 15, 0, 1, 1, 1, 3, 15,
        21654,
        57646,
        7153,
        27044
    });

    cout << "Raw encoded data in hex:\n";
    for (auto v : rawData) printf("%.2X", v);
    cout << "\n\n";

    cout << "Decoded raw data:\n";
    Decode<art>(rawData);
}


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:
#include <algorithm>
#include <iostream>

/* AVL node */
template <class T>
class AVLnode {
public:
    T key;
    int balance;
    AVLnode *left, *right, *parent;

    AVLnode(T k, AVLnode *p) : key(k), balance(0), parent(p),
                        left(NULL), right(NULL) {}

    ~AVLnode() {
        delete left;
        delete right;
    }
};

/* AVL tree */
template <class T>
class AVLtree {
public:
    AVLtree(void);
    ~AVLtree(void);
    bool insert(T key);
    void deleteKey(const T key);
    void printBalance();

private:
    AVLnode<T> *root;

    AVLnode<T>* rotateLeft          ( AVLnode<T> *a );
    AVLnode<T>* rotateRight         ( AVLnode<T> *a );
    AVLnode<T>* rotateLeftThenRight ( AVLnode<T> *n );
    AVLnode<T>* rotateRightThenLeft ( AVLnode<T> *n );
    void rebalance                  ( AVLnode<T> *n );
    int height                      ( AVLnode<T> *n );
    void setBalance                 ( AVLnode<T> *n );
    void printBalance               ( AVLnode<T> *n );
};

/* AVL class definition */
template <class T>
void AVLtree<T>::rebalance(AVLnode<T> *n) {
    setBalance(n);

    if (n->balance == -2) {
        if (height(n->left->left) >= height(n->left->right))
            n = rotateRight(n);
        else
            n = rotateLeftThenRight(n);
    }
    else if (n->balance == 2) {
        if (height(n->right->right) >= height(n->right->left))
            n = rotateLeft(n);
        else
            n = rotateRightThenLeft(n);
    }

    if (n->parent != NULL) {
        rebalance(n->parent);
    }
    else {
        root = n;
    }
}

template <class T>
AVLnode<T>* AVLtree<T>::rotateLeft(AVLnode<T> *a) {
    AVLnode<T> *b = a->right;
    b->parent = a->parent;
    a->right = b->left;

    if (a->right != NULL)
        a->right->parent = a;

    b->left = a;
    a->parent = b;

    if (b->parent != NULL) {
        if (b->parent->right == a) {
            b->parent->right = b;
        }
        else {
            b->parent->left = b;
        }
    }

    setBalance(a);
    setBalance(b);
    return b;
}

template <class T>
AVLnode<T>* AVLtree<T>::rotateRight(AVLnode<T> *a) {
    AVLnode<T> *b = a->left;
    b->parent = a->parent;
    a->left = b->right;

    if (a->left != NULL)
        a->left->parent = a;

    b->right = a;
    a->parent = b;

    if (b->parent != NULL) {
        if (b->parent->right == a) {
            b->parent->right = b;
        }
        else {
            b->parent->left = b;
        }
    }

    setBalance(a);
    setBalance(b);
    return b;
}

template <class T>
AVLnode<T>* AVLtree<T>::rotateLeftThenRight(AVLnode<T> *n) {
    n->left = rotateLeft(n->left);
    return rotateRight(n);
}

template <class T>
AVLnode<T>* AVLtree<T>::rotateRightThenLeft(AVLnode<T> *n) {
    n->right = rotateRight(n->right);
    return rotateLeft(n);
}

template <class T>
int AVLtree<T>::height(AVLnode<T> *n) {
    if (n == NULL)
        return -1;
    return 1 + std::max(height(n->left), height(n->right));
}

template <class T>
void AVLtree<T>::setBalance(AVLnode<T> *n) {
    n->balance = height(n->right) - height(n->left);
}

template <class T>
void AVLtree<T>::printBalance(AVLnode<T> *n) {
    if (n != NULL) {
        printBalance(n->left);
        std::cout << n->balance << " ";
        printBalance(n->right);
    }
}

template <class T>
AVLtree<T>::AVLtree(void) : root(NULL) {}

template <class T>
AVLtree<T>::~AVLtree(void) {
    delete root;
}

template <class T>
bool AVLtree<T>::insert(T key) {
    if (root == NULL) {
        root = new AVLnode<T>(key, NULL);
    }
    else {
        AVLnode<T>
            *n = root,
            *parent;

        while (true) {
            if (n->key == key)
                return false;

            parent = n;

            bool goLeft = n->key > key;
            n = goLeft ? n->left : n->right;

            if (n == NULL) {
                if (goLeft) {
                    parent->left = new AVLnode<T>(key, parent);
                }
                else {
                    parent->right = new AVLnode<T>(key, parent);
                }

                rebalance(parent);
                break;
            }
        }
    }

    return true;
}

template <class T>
void AVLtree<T>::deleteKey(const T delKey) {
    if (root == NULL)
        return;

    AVLnode<T>
        *n       = root,
        *parent  = root,
        *delNode = NULL,
        *child   = root;

    while (child != NULL) {
        parent = n;
        n = child;
        child = delKey >= n->key ? n->right : n->left;
        if (delKey == n->key)
            delNode = n;
    }

    if (delNode != NULL) {
        delNode->key = n->key;

        child = n->left != NULL ? n->left : n->right;

        if (root->key == delKey) {
            root = child;
        }
        else {
            if (parent->left == n) {
                parent->left = child;
            }
            else {
                parent->right = child;
            }

            rebalance(parent);
        }
    }
}

template <class T>
void AVLtree<T>::printBalance() {
    printBalance(root);
    std::cout << std::endl;
}

int main(void)
{
    AVLtree<int> t;

    std::cout << "Inserting integer values 1 to 10" << std::endl;
    for (int i = 1; i <= 10; ++i)
        t.insert(i);

    std::cout << "Printing balance: ";
    t.printBalance();
}


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:
#include <iomanip>
#include <iostream>
#include <fstream>
#include <map>
#include <sstream>
#include <string>
#include <vector>

std::vector<std::string> split(const std::string& str, char delimiter) {
    std::vector<std::string> tokens;
    std::string token;
    std::istringstream tokenStream(str);
    while (std::getline(tokenStream, token, delimiter)) {
        tokens.push_back(token);
    }
    return tokens;
}

int main() {
    using namespace std;
    string line;
    int i = 0;

    ifstream in("days_of_week.txt");
    if (in.is_open()) {
        while (getline(in, line)) {
            i++;
            if (line.empty()) {
                continue;
            }

            auto days = split(line, ' ');
            if (days.size() != 7) {
                throw std::runtime_error("There aren't 7 days in line " + i);
            }

            map<string, int> temp;
            for (auto& day : days) {
                if (temp.find(day) != temp.end()) {
                    cerr << " ∞  " << line << '\n';
                    continue;
                }
                temp[day] = 1;
            }

            int len = 1;
            while (true) {
                temp.clear();
                for (auto& day : days) {
                    string key = day.substr(0, len);
                    if (temp.find(key) != temp.end()) {
                        break;
                    }
                    temp[key] = 1;
                }
                if (temp.size() == 7) {
                    cout << setw(2) << len << "  " << line << '\n';
                    break;
                }
                len++;
            }
        }
    }

    return 0;
}


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:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

const char* command_table =
  "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";

class command {
public:
    command(const std::string&, size_t);
    const std::string& cmd() const { return cmd_; }
    size_t min_length() const { return min_len_; }
    bool match(const std::string&) const;
private:
    std::string cmd_;
    size_t min_len_;
};

// cmd is assumed to be all uppercase
command::command(const std::string& cmd, size_t min_len)
    : cmd_(cmd), min_len_(min_len) {}

// str is assumed to be all uppercase
bool command::match(const std::string& str) const {
    size_t olen = str.length();
    return olen >= min_len_ && olen <= cmd_.length()
        && cmd_.compare(0, olen, str) == 0;
}

// convert string to uppercase
void uppercase(std::string& str) {
    std::transform(str.begin(), str.end(), str.begin(),
        [](unsigned char c) -> unsigned char { return std::toupper(c); });
}

size_t get_min_length(const std::string& str) {
    size_t len = 0, n = str.length();
    while (len < n && std::isupper(static_cast<unsigned char>(str[len])))
        ++len;
    return len;
}

class command_list {
public:
    explicit command_list(const char*);
    const command* find_command(const std::string&) const;
private:
    std::vector<command> commands_;
};

command_list::command_list(const char* table) {
    std::vector<command> commands;
    std::istringstream is(table);
    std::string word;
    while (is >> word) {
        // count leading uppercase characters
        size_t len = get_min_length(word);
        // then convert to uppercase
        uppercase(word);
        commands_.push_back(command(word, len));
    }
}

const command* command_list::find_command(const std::string& word) const {
    auto iter = std::find_if(commands_.begin(), commands_.end(),
        [&word](const command& cmd) { return cmd.match(word); });
    return (iter != commands_.end()) ? &*iter : nullptr;
}

std::string test(const command_list& commands, const std::string& input) {
    std::string output;
    std::istringstream is(input);
    std::string word;
    while (is >> word) {
        if (!output.empty())
            output += ' ';
        uppercase(word);
        const command* cmd_ptr = commands.find_command(word);
        if (cmd_ptr)
            output += cmd_ptr->cmd();
        else
            output += "*error*";
    }
    return output;
}

int main() {
    command_list commands(command_table);
    std::string input("riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin");
    std::string output(test(commands, input));
    std::cout << " input: " << input << '\n';
    std::cout << "output: " << output << '\n';
    return 0;
}


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:
#include <algorithm>
#include <cctype>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

const char* command_table =
  "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";

class command {
public:
    command(const std::string&, size_t);
    const std::string& cmd() const { return cmd_; }
    size_t min_length() const { return min_len_; }
    bool match(const std::string&) const;
private:
    std::string cmd_;
    size_t min_len_;
};

// cmd is assumed to be all uppercase
command::command(const std::string& cmd, size_t min_len)
    : cmd_(cmd), min_len_(min_len) {}

// str is assumed to be all uppercase
bool command::match(const std::string& str) const {
    size_t olen = str.length();
    return olen >= min_len_ && olen <= cmd_.length()
        && cmd_.compare(0, olen, str) == 0;
}

bool parse_integer(const std::string& word, int& value) {
    try {
        size_t pos;
        int i = std::stoi(word, &pos, 10);
        if (pos < word.length())
            return false;
        value = i;
        return true;
    } catch (const std::exception& ex) {
        return false;
    }
}

// convert string to uppercase
void uppercase(std::string& str) {
    std::transform(str.begin(), str.end(), str.begin(),
        [](unsigned char c) -> unsigned char { return std::toupper(c); });
}

class command_list {
public:
    explicit command_list(const char*);
    const command* find_command(const std::string&) const;
private:
    std::vector<command> commands_;
};

command_list::command_list(const char* table) {
    std::istringstream is(table);
    std::string word;
    std::vector<std::string> words;
    while (is >> word) {
        uppercase(word);
        words.push_back(word);
    }
    for (size_t i = 0, n = words.size(); i < n; ++i) {
        word = words[i];
        // if there's an integer following this word, it specifies the minimum
        // length for the command, otherwise the minimum length is the length
        // of the command string
        int len = word.length();
        if (i + 1 < n && parse_integer(words[i + 1], len))
            ++i;
        commands_.push_back(command(word, len));
    }
}

const command* command_list::find_command(const std::string& word) const {
    auto iter = std::find_if(commands_.begin(), commands_.end(),
        [&word](const command& cmd) { return cmd.match(word); });
    return (iter != commands_.end()) ? &*iter : nullptr;
}

std::string test(const command_list& commands, const std::string& input) {
    std::string output;
    std::istringstream is(input);
    std::string word;
    while (is >> word) {
        if (!output.empty())
            output += ' ';
        uppercase(word);
        const command* cmd_ptr = commands.find_command(word);
        if (cmd_ptr)
            output += cmd_ptr->cmd();
        else
            output += "*error*";
    }
    return output;
}

int main() {
    command_list commands(command_table);
    std::string input("riG   rePEAT copies  put mo   rest    types   fup.    6       poweRin");
    std::string output(test(commands, input));
    std::cout << " input: " << input << '\n';
    std::cout << "output: " << output << '\n';
    return 0;
}


Abelian sandpile model/Identity

Our sandpiles are based on a 3 by 3 rectangular grid giving nine areas that
contain a number from 0 to 3 inclusive. (The numbers are said to represent
grains of sand in each area of the sandpile).

E.g. s1 =

    1 2 0
    2 1 1
    0 1 3

and s2 =

    2 1 3
    1 0 1
    0 1 0

Addition on sandpiles is done by adding numbers in corresponding grid areas,
so for the above:

              1 2 0     2 1 3     3 3 3
    s1 + s2 = 2 1 1  +  1 0 1  =  3 1 2
              0 1 3     0 1 0     0 2 3

If the addition would result in more than 3 "grains of sand" in any area then
those areas cause the whole sandpile to become "unstable" and the sandpile
areas are "toppled" in an "avalanche" until the "stable" result is obtained.

Any unstable area (with a number >= 4), is "toppled" by loosing one grain of
sand to each of its four horizontal or vertical neighbours. Grains are lost
at the edge of the grid, but otherwise increase the number in neighbouring
cells by one, whilst decreasing the count in the toppled cell by four in each
toppling.

A toppling may give an adjacent area more than four grains of sand leading to
a chain of topplings called an "avalanche".
E.g.

    4 3 3     0 4 3     1 0 4     1 1 0     2 1 0
    3 1 2 ==> 4 1 2 ==> 4 2 2 ==> 4 2 3 ==> 0 3 3
    0 2 3     0 2 3     0 2 3     0 2 3     1 2 3

The final result is the stable sandpile on the right.

'''Note:''' The order in which cells are toppled does not affect the final result.

;Task:
* Create a class or datastructure and functions to represent and operate on sandpiles.
* Confirm the result of the avalanche of topplings shown above
* Confirm that s1 + s2 == s2 + s1  # Show the stable results
* If s3 is the sandpile with number 3 in every grid area, and s3_id is the following sandpile:

    2 1 2
    1 0 1
    2 1 2

* Show that s3 + s3_id == s3
* Show that s3_id + s3_id == s3_id

Show confirming output here, with your examples.

;References:
*    https://www.youtube.com/watch?v=1MtEUErz7Gg
*    https://en.wikipedia.org/wiki/Abelian_sandpile_model

Solution:
#include <algorithm>
#include <array>
#include <cassert>
#include <initializer_list>
#include <iostream>

constexpr size_t sp_rows = 3;
constexpr size_t sp_columns = 3;
constexpr size_t sp_cells = sp_rows * sp_columns;
constexpr int sp_limit = 4;

class abelian_sandpile {
    friend std::ostream& operator<<(std::ostream&, const abelian_sandpile&);

public:
    abelian_sandpile();
    explicit abelian_sandpile(std::initializer_list<int> init);
    void stabilize();
    bool is_stable() const;
    void topple();
    abelian_sandpile& operator+=(const abelian_sandpile&);
    bool operator==(const abelian_sandpile&);

private:
    int& cell_value(size_t row, size_t column) {
        return cells_[cell_index(row, column)];
    }
    static size_t cell_index(size_t row, size_t column) {
        return row * sp_columns + column;
    }
    static size_t row_index(size_t cell_index) {
        return cell_index/sp_columns;
    }
    static size_t column_index(size_t cell_index) {
        return cell_index % sp_columns;
    }

    std::array<int, sp_cells> cells_;
};

abelian_sandpile::abelian_sandpile() {
    cells_.fill(0);
}

abelian_sandpile::abelian_sandpile(std::initializer_list<int> init) {
    assert(init.size() == sp_cells);
    std::copy(init.begin(), init.end(), cells_.begin());
}

abelian_sandpile& abelian_sandpile::operator+=(const abelian_sandpile& other) {
    for (size_t i = 0; i < sp_cells; ++i)
        cells_[i] += other.cells_[i];
    stabilize();
    return *this;
}

bool abelian_sandpile::operator==(const abelian_sandpile& other) {
    return cells_ == other.cells_;
}

bool abelian_sandpile::is_stable() const {
    return std::none_of(cells_.begin(), cells_.end(),
                        [](int a) { return a >= sp_limit; });
}

void abelian_sandpile::topple() {
    for (size_t i = 0; i < sp_cells; ++i) {
        if (cells_[i] >= sp_limit) {
            cells_[i] -= sp_limit;
            size_t row = row_index(i);
            size_t column = column_index(i);
            if (row > 0)
                ++cell_value(row - 1, column);
            if (row + 1 < sp_rows)
                ++cell_value(row + 1, column);
            if (column > 0)
                ++cell_value(row, column - 1);
            if (column + 1 < sp_columns)
                ++cell_value(row, column + 1);
            break;
        }
    }
}

void abelian_sandpile::stabilize() {
    while (!is_stable())
        topple();
}

abelian_sandpile operator+(const abelian_sandpile& a, const abelian_sandpile& b) {
    abelian_sandpile c(a);
    c += b;
    return c;
}

std::ostream& operator<<(std::ostream& out, const abelian_sandpile& as) {
    for (size_t i = 0; i < sp_cells; ++i) {
        if (i > 0)
            out << (as.column_index(i) == 0 ? '\n' : ' ');
        out << as.cells_[i];
    }
    return out << '\n';
}

int main() {
    std::cout << std::boolalpha;

    std::cout << "Avalanche:\n";
    abelian_sandpile sp{4,3,3, 3,1,2, 0,2,3};
    while (!sp.is_stable()) {
        std::cout << sp << "stable? " << sp.is_stable() << "\n\n";
        sp.topple();
    }
    std::cout << sp << "stable? " << sp.is_stable() << "\n\n";

    std::cout << "Commutativity:\n";
    abelian_sandpile s1{1,2,0, 2,1,1, 0,1,3};
    abelian_sandpile s2{2,1,3, 1,0,1, 0,1,0};
    abelian_sandpile sum1(s1 + s2);
    abelian_sandpile sum2(s2 + s1);
    std::cout << "s1 + s2 equals s2 + s1? " << (sum1 == sum2) << "\n\n";
    std::cout << "s1 + s2 = \n" << sum1;
    std::cout << "\ns2 + s1 = \n" << sum2;
    std::cout << '\n';

    std::cout << "Identity:\n";
    abelian_sandpile s3{3,3,3, 3,3,3, 3,3,3};
    abelian_sandpile s3_id{2,1,2, 1,0,1, 2,1,2};
    abelian_sandpile sum3(s3 + s3_id);
    abelian_sandpile sum4(s3_id + s3_id);
    std::cout << "s3 + s3_id equals s3? " << (sum3 == s3) << '\n';
    std::cout << "s3_id + s3_id equals s3_id? " << (sum4 == s3_id) << "\n\n";
    std::cout << "s3 + s3_id = \n" << sum3;
    std::cout << "\ns3_id + s3_id = \n" << sum4;

    return 0;
}


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:
#include <algorithm>
#include <iostream>
#include <numeric>
#include <sstream>
#include <vector>

std::vector<int> divisors(int n) {
    std::vector<int> divs{ 1 };
    std::vector<int> divs2;

    for (int i = 2; i*i <= n; i++) {
        if (n%i == 0) {
            int j = n / i;
            divs.push_back(i);
            if (i != j) {
                divs2.push_back(j);
            }
        }
    }
    std::copy(divs2.crbegin(), divs2.crend(), std::back_inserter(divs));

    return divs;
}

int sum(const std::vector<int>& divs) {
    return std::accumulate(divs.cbegin(), divs.cend(), 0);
}

std::string sumStr(const std::vector<int>& divs) {
    auto it = divs.cbegin();
    auto end = divs.cend();
    std::stringstream ss;

    if (it != end) {
        ss << *it;
        it = std::next(it);
    }
    while (it != end) {
        ss << " + " << *it;
        it = std::next(it);
    }

    return ss.str();
}

int abundantOdd(int searchFrom, int countFrom, int countTo, bool printOne) {
    int count = countFrom;
    int n = searchFrom;
    for (; count < countTo; n += 2) {
        auto divs = divisors(n);
        int tot = sum(divs);
        if (tot > n) {
            count++;
            if (printOne && count < countTo) {
                continue;
            }
            auto s = sumStr(divs);
            if (printOne) {
                printf("%d < %s = %d\n", n, s.c_str(), tot);
            } else {
                printf("%2d. %5d < %s = %d\n", count, n, s.c_str(), tot);
            }
        }
    }
    return n;
}

int main() {
    using namespace std;

    const int max = 25;
    cout << "The first " << max << " abundant odd numbers are:\n";
    int n = abundantOdd(1, 0, 25, false);

    cout << "\nThe one thousandth abundant odd number is:\n";
    abundantOdd(n, 25, 1000, true);

    cout << "\nThe first abundant odd number above one billion is:\n";
    abundantOdd(1e9 + 1, 0, 1, true);

    return 0;
}


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:
#include <iostream>

class Acc
{
public:
    Acc(int init)
        : _type(intType)
        , _intVal(init)
    {}

    Acc(float init)
        : _type(floatType)
        , _floatVal(init)
    {}

    int operator()(int x)
    {
        if( _type == intType )
        {
            _intVal += x;
            return _intVal;
        }
        else
        {
            _floatVal += x;
            return static_cast<int>(_floatVal);
        }
    }

    float operator()(float x)
    {
        if( _type == intType )
        {
            _floatVal = _intVal + x;
            _type = floatType;
            return _floatVal;
        }
        else
        {
            _floatVal += x;
            return _floatVal;
        }
    }
private:
    enum {floatType, intType} _type;
    float _floatVal;
    int _intVal;
};

int main()
{
    Acc a(1);
    a(5);
    Acc(3);
    std::cout << a(2.3f);
    return 0;
}


Accumulator factory

Solution:
// still inside struct Accumulator_
	// various operator() implementations provide a de facto multimethod
	Accumulator_& operator()(int more)
	{
		if (auto i = CoerceInt(*val_))
			Set(+i + more);
		else if (auto d = CoerceDouble(*val_))
			Set(+d + more);
		else
			THROW("Accumulate(int) failed");
		return *this;
	}
	Accumulator_& operator()(double more)
	{
		if (auto d = CoerceDouble(*val_))
			Set(+d + more);
		else
			THROW("Accumulate(double) failed");
		return *this;
	}
	Accumulator_& operator()(const String_& more)
	{
		if (auto s = CoerceString(*val_))
			Set(+s + more);
		else
			THROW("Accumulate(string) failed");
		return *this;
	}
};


Aliquot sequence classifications

An aliquot sequence of a positive integer K is defined recursively as the first member
being K and subsequent members being the sum of the [[Proper divisors]] of the previous term.

:* If the terms eventually reach 0 then the series for K is said to '''terminate'''.

:There are several classifications for non termination:
:* If the second term is K then all future terms are also K and so the sequence repeats from the first term with period 1 and K is called '''perfect'''.
:* If the third term ''would'' be repeating K then the sequence repeats with period 2 and K is called '''amicable'''.
:* If the Nth term ''would'' be repeating K for the first time, with N > 3 then the sequence repeats with period N - 1 and K is called '''sociable'''.
:Perfect, amicable and sociable numbers eventually repeat the original number K; there are other repetitions...
:* Some K have a sequence that eventually forms a periodic repetition of period 1 but of a number other than K, for example 95 which forms the sequence 95, 25, 6, 6, 6, ... such K are called '''aspiring'''.
:* K that have a sequence that eventually forms a periodic repetition of period >= 2 but of a number other than K, for example 562 which forms the sequence 562, 284, 220, 284, 220, ... such K are called '''cyclic'''.

:And finally:
:* Some K form aliquot sequences that are not known to be either terminating or periodic; these K are to be called '''non-terminating'''. For the purposes of this task, K is to be classed as non-terminating if it has not been otherwise classed after generating '''16''' terms or if any term of the sequence is greater than 2**47 = 140,737,488,355,328.

;Task:
# Create routine(s) to generate the aliquot sequence of a positive integer enough to classify it according to the classifications given above.
# Use it to display the classification and sequences of the numbers one to ten inclusive.
# Use it to show the classification and sequences of the following integers, in order:
:: 11, 12, 28, 496, 220, 1184,  12496, 1264460, 790, 909, 562, 1064, 1488, and optionally 15355717786080.

Show all output on this page.

;Related tasks:
*   [[Abundant, deficient and perfect number classifications]]. (Classifications from only the first two members of the whole sequence).
*   [[Proper divisors]]
*   [[Amicable pairs]]

Solution:
#include <cstdint>
#include <iostream>
#include <string>

using integer = uint64_t;

// See https://en.wikipedia.org/wiki/Divisor_function
integer divisor_sum(integer n) {
    integer total = 1, power = 2;
    // Deal with powers of 2 first
    for (; n % 2 == 0; power *= 2, n /= 2)
        total += power;
    // Odd prime factors up to the square root
    for (integer p = 3; p * p <= n; p += 2) {
        integer sum = 1;
        for (power = p; n % p == 0; power *= p, n /= p)
            sum += power;
        total *= sum;
    }
    // If n > 1 then it's prime
    if (n > 1)
        total *= n + 1;
    return total;
}

// See https://en.wikipedia.org/wiki/Aliquot_sequence
void classify_aliquot_sequence(integer n) {
    constexpr int limit = 16;
    integer terms[limit];
    terms[0] = n;
    std::string classification("non-terminating");
    int length = 1;
    for (int i = 1; i < limit; ++i) {
        ++length;
        terms[i] = divisor_sum(terms[i - 1]) - terms[i - 1];
        if (terms[i] == n) {
            classification =
                (i == 1 ? "perfect" : (i == 2 ? "amicable" : "sociable"));
            break;
        }
        int j = 1;
        for (; j < i; ++j) {
            if (terms[i] == terms[i - j])
                break;
        }
        if (j < i) {
            classification = (j == 1 ? "aspiring" : "cyclic");
            break;
        }
        if (terms[i] == 0) {
            classification = "terminating";
            break;
        }
    }
    std::cout << n << ": " << classification << ", sequence: " << terms[0];
    for (int i = 1; i < length && terms[i] != terms[i - 1]; ++i)
        std::cout << ' ' << terms[i];
    std::cout << '\n';
}

int main() {
    for (integer i = 1; i <= 10; ++i)
        classify_aliquot_sequence(i);
    for (integer i : {11, 12, 28, 496, 220, 1184, 12496, 1264460, 790, 909, 562,
                      1064, 1488})
        classify_aliquot_sequence(i);
    classify_aliquot_sequence(15355717786080);
    classify_aliquot_sequence(153557177860800);
    return 0;
}


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:
#include <iostream>
#include <string_view>
#include <boost/hana.hpp>
#include <boost/hana/experimental/printable.hpp>

using namespace std;
namespace hana = boost::hana;

// Define the Amb function.  The first parameter is the constraint to be
// enforced followed by the potential values.
constexpr auto Amb(auto constraint, auto&& ...params)
{
  // create the set of all possible solutions
  auto possibleSolutions = hana::cartesian_product(hana::tuple(params...));

  // find one that matches the constraint
  auto foldOperation = [constraint](auto a, auto b)
  {
    bool meetsConstraint = constraint(a);
    return meetsConstraint ? a : b;
  };

  return hana::fold_right(possibleSolutions, foldOperation);
}

void AlgebraExample()
{
  // use a tuple to hold the possible values of each variable
  constexpr hana::tuple x{1, 2, 3};
  constexpr hana::tuple y{7, 6, 4, 5};

  // the constraint enforcing x * y == 8
  constexpr auto constraint = [](auto t)
  {
    return t[hana::size_c<0>] * t[hana::size_c<1>] == 8;
  };

  // find the solution using the Amb function
  auto result = Amb(constraint, x, y);

  cout << "\nx = " << hana::experimental::print(x);
  cout << "\ny = " << hana::experimental::print(y);
  cout << "\nx * y == 8: " << hana::experimental::print(result);
}

void StringExample()
{
  // the word lists to choose from
  constexpr hana::tuple words1 {"the"sv, "that"sv, "a"sv};
  constexpr hana::tuple words2 {"frog"sv, "elephant"sv, "thing"sv};
  constexpr hana::tuple words3 {"walked"sv, "treaded"sv, "grows"sv};
  constexpr hana::tuple words4 {"slowly"sv, "quickly"sv};

  // the constraint that the first letter of a word is the same as the last
  // letter of the previous word
  constexpr auto constraint = [](const auto t)
  {
    auto adjacent = hana::zip(hana::drop_back(t), hana::drop_front(t));
    return hana::all_of(adjacent, [](auto t)
    {
      return t[hana::size_c<0>].back() == t[hana::size_c<1>].front();
    });
  };

  // find the solution using the Amb function
  auto wordResult = Amb(constraint, words1, words2, words3, words4);

  cout << "\n\nWords 1: " << hana::experimental::print(words1);
  cout << "\nWords 2: " << hana::experimental::print(words2);
  cout << "\nWords 3: " << hana::experimental::print(words3);
  cout << "\nWords 4: " << hana::experimental::print(words4);
  cout << "\nSolution: " << hana::experimental::print(wordResult) << "\n";
}

int main()
{
  AlgebraExample();
  StringExample();
}


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:
#include <algorithm>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <string>

bool is_deranged(const std::string& left, const std::string& right)
{
    return (left.size() == right.size()) &&
        (std::inner_product(left.begin(), left.end(), right.begin(), 0, std::plus<int>(), std::equal_to<char>()) == 0);
}

int main()
{
    std::ifstream input("unixdict.txt");
    if (!input) {
        std::cerr << "can't open input file\n";
        return EXIT_FAILURE;
    }

    typedef std::set<std::string> WordList;
    typedef std::map<std::string, WordList> AnagraMap;
    AnagraMap anagrams;

    std::pair<std::string, std::string> result;
    size_t longest = 0;

    for (std::string value; input >> value; /**/) {
        std::string key(value);
        std::sort(key.begin(), key.end());

        if (longest < value.length()) { // is it a long candidate?
            if (0 < anagrams.count(key)) { // is it an anagram?
                for (const auto& prior : anagrams[key]) {
                    if (is_deranged(prior, value)) { // are they deranged?
                        result = std::make_pair(prior, value);
                        longest = value.length();
                    }
                }
            }
        }
        anagrams[key].insert(value);
    }

    std::cout << result.first << ' ' << result.second << '\n';
    return EXIT_SUCCESS;
}


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:
#include <cmath>
#include <iostream>
using namespace std;

double getDifference(double b1, double b2) {
	double r = fmod(b2 - b1, 360.0);
	if (r < -180.0)
		r += 360.0;
	if (r >= 180.0)
		r -= 360.0;
	return r;
}

int main()
{
	cout << "Input in -180 to +180 range" << endl;
	cout << getDifference(20.0, 45.0) << endl;
	cout << getDifference(-45.0, 45.0) << endl;
	cout << getDifference(-85.0, 90.0) << endl;
	cout << getDifference(-95.0, 90.0) << endl;
	cout << getDifference(-45.0, 125.0) << endl;
	cout << getDifference(-45.0, 145.0) << endl;
	cout << getDifference(-45.0, 125.0) << endl;
	cout << getDifference(-45.0, 145.0) << endl;
	cout << getDifference(29.4803, -88.6381) << endl;
	cout << getDifference(-78.3251, -159.036) << endl;

	cout << "Input in wider range" << endl;
	cout << getDifference(-70099.74233810938, 29840.67437876723) << endl;
	cout << getDifference(-165313.6666297357, 33693.9894517456) << endl;
	cout << getDifference(1174.8380510598456, -154146.66490124757) << endl;
	cout << getDifference(60175.77306795546, 42213.07192354373) << endl;

	return 0;
}


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:
#include <iostream>

int countDivisors(int n) {
    if (n < 2) return 1;
    int count = 2; // 1 and n
    for (int i = 2; i <= n/2; ++i) {
        if (n%i == 0) ++count;
    }
    return count;
}

int main() {
    int maxDiv = 0, count = 0;
    std::cout << "The first 20 anti-primes are:" << std::endl;
    for (int n = 1; count < 20; ++n) {
        int d = countDivisors(n);
        if (d > maxDiv) {
            std::cout << n << " ";
            maxDiv = d;
            count++;
        }
    }
    std::cout << std::endl;
    return 0;
}


Apply a digital filter (direct form II transposed)

Digital filters are used to apply a mathematical operation to a sampled signal. One of the common formulations is the "direct form II transposed" which can represent both infinite impulse response (IIR) and finite impulse response (FIR) filters, as well as being more numerically stable than other forms. [https://ccrma.stanford.edu/~jos/fp/Transposed_Direct_Forms.html]

;Task:

Filter a signal using an order 3 low-pass Butterworth filter. The coefficients for the filter are a=[1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17] and b = [0.16666667, 0.5, 0.5, 0.16666667]

The signal that needs filtering is the following vector: [-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973, -1.00700480494, -0.404707073677 ,0.800482325044, 0.743500089861, 1.01090520172, 0.741527555207, 0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641, -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589]

;See also:
[Wikipedia on Butterworth filters]

Solution:
#include <vector>
#include <iostream>
using namespace std;

void Filter(const vector<float> &b, const vector<float> &a, const vector<float> &in, vector<float> &out)
{

	out.resize(0);
	out.resize(in.size());

	for(int i=0; i < in.size(); i++)
	{
		float tmp = 0.;
		int j=0;
		out[i] = 0.f;
		for(j=0; j < b.size(); j++)
		{
			if(i - j < 0) continue;
			tmp += b[j] * in[i-j];
		}

		for(j=1; j < a.size(); j++)
		{
			if(i - j < 0) continue;
			tmp -= a[j]*out[i-j];
		}

		tmp /= a[0];
		out[i] = tmp;
	}
}

int main()
{
	vector<float> sig = {-0.917843918645,0.141984778794,1.20536903482,0.190286794412,-0.662370894973,-1.00700480494,\
		-0.404707073677,0.800482325044,0.743500089861,1.01090520172,0.741527555207,\
		0.277841675195,0.400833448236,-0.2085993586,-0.172842103641,-0.134316096293,\
		0.0259303398477,0.490105989562,0.549391221511,0.9047198589};

	//Constants for a Butterworth filter (order 3, low pass)
	vector<float> a = {1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17};
	vector<float> b = {0.16666667, 0.5, 0.5, 0.16666667};

	vector<float> result;
	Filter(b, a, sig, result);

	for(size_t i=0;i<result.size();i++)
		cout << result[i] << ",";
	cout << endl;

	return 0;
}


Approximate equality

Sometimes, when testing whether the solution to a task (for example, here on Rosetta Code) is correct, the
difference in floating point calculations between different language implementations becomes significant.

For example, a difference between '''32''' bit and '''64''' bit floating point calculations may appear by
about the 8th significant digit in base 10 arithmetic.

;Task:
Create a function which returns true if two floating point numbers are approximately equal.

The function should allow for differences in the magnitude of numbers, so that, for example,
'''100000000000000.01'''   may be approximately equal to   '''100000000000000.011''',
even though   '''100.01'''   is not approximately equal to   '''100.011'''.

If the language has such a feature in its standard library, this may be used instead of a custom function.

Show the function results with comparisons on the following pairs of values:
:#     100000000000000.01,                        100000000000000.011       (note: should return ''true'')
:#     100.01,                                    100.011                                                     (note: should return ''false'')
:#     10000000000000.001 / 10000.0,   1000000000.0000001000
:#     0.001,                                     0.0010000001
:#     0.000000000000000000000101,                0.0
:#      sqrt(2) * sqrt(2),                    2.0
:#     -sqrt(2) * sqrt(2),                        -2.0
:#     3.14159265358979323846,                    3.14159265358979324

Answers should be true for the first example and false in the second, so that just rounding the numbers to a fixed number of decimals should not be enough. Otherwise answers may vary and still be correct. See the Python code for one type of solution.

__TOC__

Solution:
#include <iomanip>
#include <iostream>
#include <cmath>

bool approxEquals(double a, double b, double e) {
    return fabs(a - b) < e;
}

void test(double a, double b) {
    constexpr double epsilon = 1e-18;
    std::cout << std::setprecision(21) << a;
    std::cout << ", ";
    std::cout << std::setprecision(21) << b;
    std::cout << " => ";
    std::cout << approxEquals(a, b, epsilon) << '\n';
}

int main() {
    test(100000000000000.01, 100000000000000.011);
    test(100.01, 100.011);
    test(10000000000000.001 / 10000.0, 1000000000.0000001000);
    test(0.001, 0.0010000001);
    test(0.000000000000000000000101, 0.0);
    test(sqrt(2.0) * sqrt(2.0), 2.0);
    test(-sqrt(2.0) * sqrt(2.0), -2.0);
    test(3.14159265358979323846, 3.14159265358979324);
    return 0;
}