Sum and product puzzle

Solution:
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>

std::ostream &operator<<(std::ostream &os, std::vector<std::pair<int, int>> &v) {
    for (auto &p : v) {
        auto sum = p.first + p.second;
        auto prod = p.first * p.second;
        os << '[' << p.first << ", " << p.second << "] S=" << sum << " P=" << prod;
    }
    return os << '\n';
}

void print_count(const std::vector<std::pair<int, int>> &candidates) {
    auto c = candidates.size();
    if (c == 0) {
        std::cout << "no candidates\n";
    } else if (c == 1) {
        std::cout << "one candidate\n";
    } else {
        std::cout << c << " candidates\n";
    }
}

auto setup() {
    std::vector<std::pair<int, int>> candidates;

    // numbers must be greater than 1
    for (int x = 2; x <= 98; x++) {
        // numbers must be unique, and sum no more than 100
        for (int y = x + 1; y <= 98; y++) {
            if (x + y <= 100) {
                candidates.push_back(std::make_pair(x, y));
            }
        }
    }

    return candidates;
}

void remove_by_sum(std::vector<std::pair<int, int>> &candidates, const int sum) {
    candidates.erase(std::remove_if(
        candidates.begin(), candidates.end(),
        [sum](const std::pair<int, int> &pair) {
            auto s = pair.first + pair.second;
            return s == sum;
        }
    ), candidates.end());
}

void remove_by_prod(std::vector<std::pair<int, int>> &candidates, const int prod) {
    candidates.erase(std::remove_if(
        candidates.begin(), candidates.end(),
        [prod](const std::pair<int, int> &pair) {
            auto p = pair.first * pair.second;
            return p == prod;
        }
    ), candidates.end());
}

void statement1(std::vector<std::pair<int, int>> &candidates) {
    std::map<int, int> uniqueMap;

    std::for_each(
        candidates.cbegin(), candidates.cend(),
        [&uniqueMap](const std::pair<int, int> &pair) {
            auto prod = pair.first * pair.second;
            uniqueMap[prod]++;
        }
    );

    bool loop;
    do {
        loop = false;
        for (auto &pair : candidates) {
            auto prod = pair.first * pair.second;
            if (uniqueMap[prod] == 1) {
                auto sum = pair.first + pair.second;
                remove_by_sum(candidates, sum);

                loop = true;
                break;
            }
        }
    } while (loop);
}

void statement2(std::vector<std::pair<int, int>> &candidates) {
    std::map<int, int> uniqueMap;

    std::for_each(
        candidates.cbegin(), candidates.cend(),
        [&uniqueMap](const std::pair<int, int> &pair) {
            auto prod = pair.first * pair.second;
            uniqueMap[prod]++;
        }
    );

    bool loop;
    do {
        loop = false;
        for (auto &pair : candidates) {
            auto prod = pair.first * pair.second;
            if (uniqueMap[prod] > 1) {
                remove_by_prod(candidates, prod);

                loop = true;
                break;
            }
        }
    } while (loop);
}

void statement3(std::vector<std::pair<int, int>> &candidates) {
    std::map<int, int> uniqueMap;

    std::for_each(
        candidates.cbegin(), candidates.cend(),
        [&uniqueMap](const std::pair<int, int> &pair) {
            auto sum = pair.first + pair.second;
            uniqueMap[sum]++;
        }
    );

    bool loop;
    do {
        loop = false;
        for (auto &pair : candidates) {
            auto sum = pair.first + pair.second;
            if (uniqueMap[sum] > 1) {
                remove_by_sum(candidates, sum);

                loop = true;
                break;
            }
        }
    } while (loop);
}

int main() {
    auto candidates = setup();
    print_count(candidates);

    statement1(candidates);
    print_count(candidates);

    statement2(candidates);
    print_count(candidates);

    statement3(candidates);
    print_count(candidates);

    std::cout << candidates;

    return 0;
}


Sum digits of an integer

Take a   Natural Number   in a given base and return the sum of its digits:
:*   '''1'''10                  sums to   '''1'''
:*   '''1234'''10       sums to   '''10'''
:*   '''fe'''16              sums to   '''29'''
:*   '''f0e'''16           sums to   '''29'''

Solution:
#include <iostream>
#include <cmath>
int SumDigits(const unsigned long long int digits, const int BASE = 10) {
    int sum = 0;
    unsigned long long int x = digits;
    for (int i = log(digits)/log(BASE); i>0; i--){
        const double z = std::pow(BASE,i);
	  const unsigned long long int t = x/z;
	  sum += t;
	  x -= t*z;
    }
    return x+sum;
}

int main() {
        std::cout << SumDigits(1) << ' '
                  << SumDigits(12345) << ' '
                  << SumDigits(123045) << ' '
                  << SumDigits(0xfe, 16) << ' '
                  << SumDigits(0xf0e, 16) << std::endl;
        return 0;
}


Sum multiples of 3 and 5

The objective is to write a function that finds the sum of all positive multiples of 3 or 5 below ''n''.

Show output for ''n'' = 1000.

This is is the same as Project Euler problem 1.

'''Extra credit:''' do this efficiently for ''n'' = 1e20 or higher.

Solution:
#include <iostream>

//--------------------------------------------------------------------------------------------------
typedef unsigned long long bigInt;

using namespace std;
//--------------------------------------------------------------------------------------------------
class m35
{
public:
    void doIt( bigInt i )
    {
	bigInt sum = 0;
	for( bigInt a = 1; a < i; a++ )
	    if( !( a % 3 ) || !( a % 5 ) ) sum += a;

	cout << "Sum is " << sum << " for n = " << i << endl << endl;
    }

    // this method uses less than half iterations than the first one
    void doIt_b( bigInt i )
    {
	bigInt sum = 0;
	for( bigInt a = 0; a < 28; a++ )
	{
	    if( !( a % 3 ) || !( a % 5 ) )
	    {
		sum += a;
		for( bigInt s = 30; s < i; s += 30 )
		    if( a + s < i ) sum += ( a + s );

	    }
	}
	cout << "Sum is " << sum << " for n = " << i << endl << endl;
    }
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
    m35 m; m.doIt( 1000 );
    return system( "pause" );
}


Sum of elements below main diagonal of matrix

Find and display the sum of elements that are below the main diagonal of a matrix.

The matrix should be a square matrix.

::: ---   Matrix to be used:   ---

      [[1,3,7,8,10],
       [2,4,16,14,4],
       [3,1,9,18,11],
       [12,14,17,18,20],
       [7,1,3,9,5]]

Solution:
#include <iostream>
#include <vector>

template<typename T>
T sum_below_diagonal(const std::vector<std::vector<T>>& matrix) {
    T sum = 0;
    for (std::size_t y = 0; y < matrix.size(); y++)
        for (std::size_t x = 0; x < matrix[y].size() && x < y; x++)
            sum += matrix[y][x];
    return sum;
}

int main() {
    std::vector<std::vector<int>> matrix = {
        {1,3,7,8,10},
        {2,4,16,14,4},
        {3,1,9,18,11},
        {12,14,17,18,20},
        {7,1,3,9,5}
    };

    std::cout << sum_below_diagonal(matrix) << std::endl;
    return 0;
}


Summarize and say sequence

There are several ways to generate a self-referential sequence. One very common one (the [[Look-and-say sequence]]) is to start with a positive integer, then generate the next term by concatenating enumerated groups of adjacent alike digits:
        0, 10, 1110, 3110, 132110, 1113122110, 311311222110 ...
The terms generated grow in length geometrically and never converge.

Another way to generate a self-referential sequence is to summarize the previous term.

Count how many of each alike digit there is, then concatenate the sum and digit for each of the sorted enumerated digits. Note that the first five terms are the same as for the previous sequence.
        0, 10, 1110, 3110, 132110, 13123110, 23124110 ...
Sort the digits largest to smallest. Do not include counts of digits that do not appear in the previous term.

Depending on the seed value, series generated this way always either converge to a stable value or to a short cyclical pattern. (For our purposes, I'll use converge to mean an element matches a previously seen element.) The sequence shown, with a seed value of 0, converges to a stable value of 1433223110 after 11 iterations. The seed value that converges most quickly is 22. It goes stable after the first element. (The next element is 22, which has been seen before.)

;Task:
Find all the positive integer seed values under 1000000, for the above convergent self-referential sequence, that takes the largest number of iterations before converging. Then print out the number of iterations and the sequence they return. Note that different permutations of the digits of the seed will yield the same sequence. For this task, assume leading zeros are not permitted.

Seed Value(s): 9009 9090 9900

Iterations: 21

Sequence: (same for all three seeds except for first element)
9009
2920
192210
19222110
19323110
1923123110
1923224110
191413323110
191433125110
19151423125110
19251413226110
1916151413325110
1916251423127110
191716151413326110
191726151423128110
19181716151413327110
19182716151423129110
29181716151413328110
19281716151423228110
19281716151413427110
19182716152413228110

;Related tasks:
*   [[Fours is the number of letters in the ...]]
*   [[Look-and-say sequence]]
*   [[Number names]]
*   [[Self-describing numbers]]
*   [[Spelling of ordinal numbers]]

;Also see:
*   The On-Line Encyclopedia of Integer Sequences.

Solution:
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <algorithm>

std::map<char, int> _map;
std::vector<std::string> _result;
size_t longest = 0;

void make_sequence( std::string n ) {
    _map.clear();
    for( std::string::iterator i = n.begin(); i != n.end(); i++ )
        _map.insert( std::make_pair( *i, _map[*i]++ ) );

    std::string z;
    for( std::map<char, int>::reverse_iterator i = _map.rbegin(); i != _map.rend(); i++ ) {
        char c = ( *i ).second + 48;
        z.append( 1, c );
        z.append( 1, i->first );
    }

    if( longest <= z.length() ) {
        longest = z.length();
        if( std::find( _result.begin(), _result.end(), z ) == _result.end() ) {
            _result.push_back( z );
            make_sequence( z );
        }
    }
}
int main( int argc, char* argv[] ) {
    std::vector<std::string> tests;
    tests.push_back( "9900" ); tests.push_back( "9090" ); tests.push_back( "9009" );
    for( std::vector<std::string>::iterator i = tests.begin(); i != tests.end(); i++ ) {
        make_sequence( *i );
        std::cout  << "[" << *i << "] Iterations: " << _result.size() + 1 << "\n";
        for( std::vector<std::string>::iterator j = _result.begin(); j != _result.end(); j++ ) {
            std::cout << *j << "\n";
        }
        std::cout << "\n\n";
    }
    return 0;
}


Summarize primes

Considering in order of length, n, all sequences of consecutive
primes, p, from 2 onwards, where p < 1000 and n>0, select those
sequences whose sum is prime, and for these display the length of the
sequence, the last item in the sequence, and the sum.

Solution:
#include <iostream>

bool is_prime(int n) {
    if (n < 2) {
        return false;
    }

    if (n % 2 == 0) {
        return n == 2;
    }
    if (n % 3 == 0) {
        return n == 3;
    }

    int i = 5;
    while (i * i <= n) {
        if (n % i == 0) {
            return false;
        }
        i += 2;

        if (n % i == 0) {
            return false;
        }
        i += 4;
    }

    return true;
}

int main() {
    const int start = 1;
    const int stop = 1000;

    int sum = 0;
    int count = 0;
    int sc = 0;

    for (int p = start; p < stop; p++) {
        if (is_prime(p)) {
            count++;
            sum += p;
            if (is_prime(sum)) {
                printf("The sum of %3d primes in [2, %3d] is %5d which is also prime\n", count, p, sum);
                sc++;
            }
        }
    }
    printf("There are %d summerized primes in [%d, %d)\n", sc, start, stop);

    return 0;
}


Super-d numbers

A super-d number is a positive, decimal (base ten) integer   '''n'''   such that   '''d x nd'''   has at least   '''d'''   consecutive digits   '''d'''   where
    2 <= d <= 9
For instance, 753 is a super-3 number because 3 x 7533 = 1280873331.

'''Super-d'''   numbers are also shown on   '''MathWorld'''(tm)   as   '''super-''d'' '''   or   '''super-''d'''''.

;Task:
:* Write a function/procedure/routine to find super-d numbers.
:* For   '''d=2'''   through   '''d=6''',   use the routine to show the first   '''10'''   super-d numbers.

;Extra credit:
:* Show the first   '''10'''   super-7, super-8, and/or super-9 numbers   (optional).

;See also:
:*   Wolfram MathWorld - Super-d Number.
:*   OEIS: A014569 - Super-3 Numbers.

Solution:
#include <iostream>
#include <sstream>
#include <vector>

uint64_t ipow(uint64_t base, uint64_t exp) {
    uint64_t result = 1;
    while (exp) {
        if (exp & 1) {
            result *= base;
        }
        exp >>= 1;
        base *= base;
    }
    return result;
}

int main() {
    using namespace std;

    vector<string> rd{ "22", "333", "4444", "55555", "666666", "7777777", "88888888", "999999999" };

    for (uint64_t ii = 2; ii < 5; ii++) {
        cout << "First 10 super-" << ii << " numbers:\n";
        int count = 0;

        for (uint64_t j = 3; /* empty */; j++) {
            auto k = ii * ipow(j, ii);
            auto kstr = to_string(k);
            auto needle = rd[(size_t)(ii - 2)];
            auto res = kstr.find(needle);
            if (res != string::npos) {
                count++;
                cout << j << ' ';
                if (count == 10) {
                    cout << "\n\n";
                    break;
                }
            }
        }
    }

    return 0;
}


Super-d numbers

Solution:
#include <iostream>
#include <gmpxx.h>

using big_int = mpz_class;

int main() {
    for (unsigned int d = 2; d <= 9; ++d) {
        std::cout << "First 10 super-" << d << " numbers:\n";
        std::string digits(d, '0' + d);
        big_int bignum;
        for (unsigned int count = 0, n = 1; count < 10; ++n) {
            mpz_ui_pow_ui(bignum.get_mpz_t(), n, d);
            bignum *= d;
            auto str(bignum.get_str());
            if (str.find(digits) != std::string::npos) {
                std::cout << n << ' ';
                ++count;
            }
        }
        std::cout << '\n';
    }
    return 0;
}


Super-d numbers

Solution:
#include <cstdio>
#include <sstream>
#include <chrono>

using namespace std;
using namespace chrono;

struct LI { uint64_t a, b, c, d, e; }; const uint64_t Lm = 1e18;
auto st = steady_clock::now(); LI k[10][10];

string padZ(uint64_t x, int n = 18) { string r = to_string(x);
  return string(max((int)(n - r.length()), 0), '0') + r; }

uint64_t ipow(uint64_t b, uint64_t e) { uint64_t r = 1;
  while (e) { if (e & 1) r *= b; e >>= 1; b *= b; } return r; }

uint64_t fa(uint64_t x) { // factorial
  uint64_t r = 1; while (x > 1) r *= x--; return r; }

void set(LI &d, uint64_t s) { // d = s
  d.a = s; d.b = d.c = d.d = d.e = 0; }

void inc(LI &d, LI s) { // d += s
  d.a += s.a; while (d.a >= Lm) { d.a -= Lm; d.b++; }
  d.b += s.b; while (d.b >= Lm) { d.b -= Lm; d.c++; }
  d.c += s.c; while (d.c >= Lm) { d.c -= Lm; d.d++; }
  d.d += s.d; while (d.d >= Lm) { d.d -= Lm; d.e++; }
  d.e += s.e;
}

string scale(uint32_t s, LI &x) { // multiplies x by s, converts to string
  uint64_t A = x.a * s, B = x.b * s, C = x.c * s, D = x.d * s, E = x.e * s;
  while (A >= Lm) { A -= Lm; B++; }
  while (B >= Lm) { B -= Lm; C++; }
  while (C >= Lm) { C -= Lm; D++; }
  while (D >= Lm) { D -= Lm; E++; }
  if (E > 0) return to_string(E) + padZ(D) + padZ(C) + padZ(B) + padZ(A);
  if (D > 0) return to_string(D) + padZ(C) + padZ(B) + padZ(A);
  if (C > 0) return to_string(C) + padZ(B) + padZ(A);
  if (B > 0) return to_string(B) + padZ(A);
  return to_string(A);
}

void fun(int d) {
  auto m = k[d]; string s = string(d, '0' + d); printf("%d: ", d);
  for (int i = d, c = 0; c < 10; i++) {
    if (scale((uint32_t)d, m[0]).find(s) != string::npos) {
      printf("%d ", i); ++c; }
    for (int j = d, k = d - 1; j > 0; j = k--) inc(m[k], m[j]);
  } printf("%ss\n", to_string(duration<double>(steady_clock::now() - st).count()).substr(0,5).c_str());
}

static void init() {
  for (int v = 1; v < 10; v++) {
    uint64_t f[v + 1], l[v + 1];
    for (int j = 0; j <= v; j++) {
      if (j == v) for (int y = 0; y <= v; y++)
          set(k[v][y], v != y ? (uint64_t)f[y] : fa(v));
      l[0] = f[0]; f[0] = ipow(j + 1, v);
      for (int a = 0, b = 1; b <= v; a = b++) {
        l[b] = f[b]; f[b] = f[a] - l[a];
      }
    }
  }
}

int main() {
  init();
  for (int i = 2; i <= 9; i++) fun(i);
}


Superpermutation minimisation

A superpermutation of N different characters is a string consisting of an arrangement of multiple copies of those N different characters in which every permutation of those characters can be found as a substring.

For example, representing the characters as A..Z, using N=2 we choose to use the first two characters 'AB'.
The permutations of 'AB' are the two, (i.e. two-factorial), strings: 'AB' and 'BA'.

A too obvious method of generating a superpermutation is to just join all the permutations together forming 'ABBA'.

A little thought will produce the shorter (in fact the shortest) superpermutation of 'ABA' - it contains 'AB' at the beginning and contains 'BA' from the middle to the end.

The "too obvious" method of creation generates a string of length N!*N. Using this as a yardstick, the task is to investigate other methods of generating superpermutations of N from 1-to-7 characters, that never generate larger superpermutations.

Show descriptions and comparisons of algorithms used here, and select the "Best" algorithm as being the one generating shorter superpermutations.

The problem of generating the shortest superpermutation for each N ''might'' be NP complete, although the minimal strings for small values of N have been found by brute -force searches.

;Reference:
* The Minimal Superpermutation Problem. by Nathaniel Johnston.
* oeis A180632 gives 0-5 as 0, 1, 3, 9, 33, 153. 6 is thought to be 872.
* Superpermutations - Numberphile. A video
* Superpermutations: the maths problem solved by 4chan - Standupmaths. A video of recent (2018) mathematical progress.
* New Superpermutations Discovered! Standupmaths & Numberphile.

Solution:
#include <array>
#include <iostream>
#include <vector>

constexpr int MAX = 12;

static std::vector<char> sp;
static std::array<int, MAX> count;
static int pos = 0;

int factSum(int n) {
    int s = 0;
    int x = 0;
    int f = 1;
    while (x < n) {
        f *= ++x;
        s += f;
    }
    return s;
}

bool r(int n) {
    if (n == 0) {
        return false;
    }
    char c = sp[pos - n];
    if (--count[n] == 0) {
        count[n] = n;
        if (!r(n - 1)) {
            return false;
        }
    }
    sp[pos++] = c;
    return true;
}

void superPerm(int n) {
    pos = n;
    int len = factSum(n);
    if (len > 0) {
        sp.resize(len);
    }
    for (size_t i = 0; i <= n; i++) {
        count[i] = i;
    }
    for (size_t i = 1; i <= n; i++) {
        sp[i - 1] = '0' + i;
    }
    while (r(n)) {}
}

int main() {
    for (size_t n = 0; n < MAX; n++) {
        superPerm(n);
        std::cout << "superPerm(" << n << ") len = " << sp.size() << '\n';
    }

    return 0;
}


Tarjan

{{wikipedia|Graph}}

Tarjan's algorithm is an algorithm in graph theory for finding the strongly connected components of a graph.

It runs in linear time, matching the time bound for alternative methods including Kosaraju's algorithm and the path-based strong component algorithm.

Tarjan's Algorithm is named for its discoverer, Robert Tarjan.

;References:
* The article on Wikipedia.

See also: [[Kosaraju]]

Solution:
//
// C++ implementation of Tarjan's strongly connected components algorithm
// See https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
//
#include <algorithm>
#include <iostream>
#include <list>
#include <string>
#include <vector>

struct noncopyable {
    noncopyable() {}
    noncopyable(const noncopyable&) = delete;
    noncopyable& operator=(const noncopyable&) = delete;
};

template <typename T>
class tarjan;

template <typename T>
class vertex : private noncopyable {
public:
    explicit vertex(const T& t) : data_(t) {}
    void add_neighbour(vertex* v) {
        neighbours_.push_back(v);
    }
    void add_neighbours(const std::initializer_list<vertex*>& vs) {
        neighbours_.insert(neighbours_.end(), vs);
    }
    const T& get_data() {
        return data_;
    }
private:
    friend tarjan<T>;
    T data_;
    int index_ = -1;
    int lowlink_ = -1;
    bool on_stack_ = false;
    std::vector<vertex*> neighbours_;
};

template <typename T>
class graph : private noncopyable {
public:
    vertex<T>* add_vertex(const T& t) {
        vertexes_.emplace_back(t);
        return &vertexes_.back();
    }
private:
    friend tarjan<T>;
    std::list<vertex<T>> vertexes_;
};

template <typename T>
class tarjan  : private noncopyable {
public:
    using component = std::vector<vertex<T>*>;
    std::list<component> run(graph<T>& graph) {
        index_ = 0;
        stack_.clear();
        strongly_connected_.clear();
        for (auto& v : graph.vertexes_) {
            if (v.index_ == -1)
                strongconnect(&v);
        }
        return strongly_connected_;
    }
private:
    void strongconnect(vertex<T>* v) {
        v->index_ = index_;
        v->lowlink_ = index_;
        ++index_;
        stack_.push_back(v);
        v->on_stack_ = true;
        for (auto w : v->neighbours_) {
            if (w->index_ == -1) {
                strongconnect(w);
                v->lowlink_ = std::min(v->lowlink_, w->lowlink_);
            }
            else if (w->on_stack_) {
                v->lowlink_ = std::min(v->lowlink_, w->index_);
            }
        }
        if (v->lowlink_ == v->index_) {
            strongly_connected_.push_back(component());
            component& c = strongly_connected_.back();
            for (;;) {
                auto w = stack_.back();
                stack_.pop_back();
                w->on_stack_ = false;
                c.push_back(w);
                if (w == v)
                    break;
            }
        }
    }
    int index_ = 0;
    std::list<vertex<T>*> stack_;
    std::list<component> strongly_connected_;
};

template <typename T>
void print_vector(const std::vector<vertex<T>*>& vec) {
    if (!vec.empty()) {
        auto i = vec.begin();
        std::cout << (*i)->get_data();
        for (++i; i != vec.end(); ++i)
            std::cout << ' ' << (*i)->get_data();
    }
    std::cout << '\n';
}

int main() {
    graph<std::string> g;
    auto andy = g.add_vertex("Andy");
    auto bart = g.add_vertex("Bart");
    auto carl = g.add_vertex("Carl");
    auto dave = g.add_vertex("Dave");
    auto earl = g.add_vertex("Earl");
    auto fred = g.add_vertex("Fred");
    auto gary = g.add_vertex("Gary");
    auto hank = g.add_vertex("Hank");

    andy->add_neighbour(bart);
    bart->add_neighbour(carl);
    carl->add_neighbour(andy);
    dave->add_neighbours({bart, carl, earl});
    earl->add_neighbours({dave, fred});
    fred->add_neighbours({carl, gary});
    gary->add_neighbour(fred);
    hank->add_neighbours({earl, gary, hank});

    tarjan<std::string> t;
    for (auto&& s : t.run(g))
        print_vector(s);
    return 0;
}


Tau function

Given a positive integer, count the number of its positive divisors.

;Task
Show the result for the first   '''100'''   positive integers.

;Related task
*  [[Tau number]]

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

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

int main() {
    const unsigned int limit = 100;
    std::cout << "Count of divisors for the first " << limit << " positive integers:\n";
    for (unsigned int n = 1; n <= limit; ++n) {
        std::cout << std::setw(3) << divisor_count(n);
        if (n % 20 == 0)
            std::cout << '\n';
    }
}


Teacup rim text

On a set of coasters we have, there's a picture of a teacup.   On the rim of the teacup the word   '''TEA'''   appears a number of times separated by bullet characters   (*).

It occurred to me that if the bullet were removed and the words run together,   you could start at any letter and still end up with a meaningful three-letter word.

So start at the   '''T'''   and read   '''TEA'''.   Start at the   '''E'''   and read   '''EAT''',   or start at the   '''A'''   and read   '''ATE'''.

That got me thinking that maybe there are other words that could be used rather that   '''TEA'''.   And that's just English.   What about Italian or Greek or ... um ... Telugu.

For English, we will use the unixdict (now) located at:   unixdict.txt.

(This will maintain continuity with other Rosetta Code tasks that also use it.)

;Task:
Search for a set of words that could be printed around the edge of a teacup.   The words in each set are to be of the same length, that length being greater than two (thus precluding   '''AH'''   and   '''HA''',   for example.)

Having listed a set, for example   ['''ate tea eat'''],   refrain from displaying permutations of that set, e.g.:   ['''eat tea ate''']   etc.

The words should also be made of more than one letter   (thus precluding   '''III'''   and   '''OOO'''   etc.)

The relationship between these words is (using ATE as an example) that the first letter of the first becomes the last letter of the second.   The first letter of the second becomes the last letter of the third.   So   '''ATE'''   becomes   '''TEA'''   and   '''TEA'''   becomes   '''EAT'''.

All of the possible permutations, using this particular permutation technique, must be words in the list.

The set you generate for   '''ATE'''   will never included the word   '''ETA'''   as that cannot be reached via the first-to-last movement method.

Display one line for each set of teacup rim words.

Solution:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <set>
#include <string>
#include <vector>

// filename is expected to contain one lowercase word per line
std::set<std::string> load_dictionary(const std::string& filename) {
    std::ifstream in(filename);
    if (!in)
        throw std::runtime_error("Cannot open file " + filename);
    std::set<std::string> words;
    std::string word;
    while (getline(in, word))
        words.insert(word);
    return words;
}

void find_teacup_words(const std::set<std::string>& words) {
    std::vector<std::string> teacup_words;
    std::set<std::string> found;
    for (auto w = words.begin(); w != words.end(); ++w) {
        std::string word = *w;
        size_t len = word.size();
        if (len < 3 || found.find(word) != found.end())
            continue;
        teacup_words.clear();
        teacup_words.push_back(word);
        for (size_t i = 0; i + 1 < len; ++i) {
            std::rotate(word.begin(), word.begin() + 1, word.end());
            if (word == *w || words.find(word) == words.end())
                break;
            teacup_words.push_back(word);
        }
        if (teacup_words.size() == len) {
            found.insert(teacup_words.begin(), teacup_words.end());
            std::cout << teacup_words[0];
            for (size_t i = 1; i < len; ++i)
                std::cout << ' ' << teacup_words[i];
            std::cout << '\n';
        }
    }
}

int main(int argc, char** argv) {
    if (argc != 2) {
        std::cerr << "usage: " << argv[0] << " dictionary\n";
        return EXIT_FAILURE;
    }
    try {
        find_teacup_words(load_dictionary(argv[1]));
    } catch (const std::exception& ex) {
        std::cerr << ex.what() << '\n';
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}


Temperature conversion

There are quite a number of temperature scales. For this task we will concentrate on four of the perhaps best-known ones:
Rankine.

The Celsius and Kelvin scales have the same magnitude, but different null points.

: 0 degrees Celsius corresponds to 273.15 kelvin.
: 0 kelvin is absolute zero.

The Fahrenheit and Rankine scales also have the same magnitude, but different null points.

: 0 degrees Fahrenheit corresponds to 459.67 degrees Rankine.
: 0 degrees Rankine is absolute zero.

The Celsius/Kelvin and Fahrenheit/Rankine scales have a ratio of 5 : 9.

;Task
Write code that accepts a value of kelvin, converts it to values of the three other scales, and prints the result.

;Example:

K  21.00

C  -252.15

F  -421.87

R  37.80

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

//--------------------------------------------------------------------------------------------------
using namespace std;

//--------------------------------------------------------------------------------------------------
class converter
{
public:
    converter() : KTC( 273.15f ), KTDel( 3.0f / 2.0f ), KTF( 9.0f / 5.0f ), KTNew( 33.0f / 100.0f ),
          KTRank( 9.0f / 5.0f ), KTRe( 4.0f / 5.0f ), KTRom( 21.0f / 40.0f ) {}

    void convert( float kelvin )
    {
    float cel = kelvin - KTC,
          del = ( 373.15f - kelvin ) * KTDel,
          fah = kelvin * KTF - 459.67f,
          net = cel * KTNew,
          rnk = kelvin * KTRank,
          rea = cel * KTRe,
          rom = cel * KTRom + 7.5f;

    cout << endl << left
         << "TEMPERATURES:" << endl
         << "===============" << endl << setw( 13 )
         << "CELSIUS:" << cel << endl << setw( 13 )
         << "DELISLE:" << del << endl << setw( 13 )
         << "FAHRENHEIT:" << fah << endl << setw( 13 )
         << "KELVIN:" << kelvin << endl  << setw( 13 )
         << "NEWTON:" << net << endl << setw( 13 )
         << "RANKINE:" << rnk << endl << setw( 13 )
         << "REAUMUR:" << rea << endl << setw( 13 )
         << "ROMER:" << rom << endl << endl << endl;
    }
private:
    const float KTRank, KTC, KTF, KTRe, KTDel, KTNew, KTRom;
};
//--------------------------------------------------------------------------------------------------
int main( int argc, char* argv[] )
{
    converter con;
    float k;
    while( true )
    {
    cout << "Enter the temperature in Kelvin to convert: ";
    cin >> k;
    con.convert( k );
    system( "pause" );
    system( "cls" );
    }
    return 0;
}
//--------------------------------------------------------------------------------------------------


Test integerness

{| class="wikitable"
|-
! colspan=2 | Input
! colspan=2 | Output
! rowspan=2 | Comment
|-
! Type
! Value
! exact
! tolerance = 0.00001
|-
| rowspan=3 | decimal
| 25.000000
| colspan=2 | true
|
|-
| 24.999999
| false
| true
|
|-
| 25.000100
| colspan=2 | false
|
|-
| rowspan=4 | floating-point
| -2.1e120
| colspan=2 | true
| This one is tricky, because in most languages it is too large to fit into a native integer type.It is, nonetheless, mathematically an integer, and your code should identify it as such.
|-
| -5e-2
| colspan=2 | false
|
|-
| NaN
| colspan=2 | false
|
|-
| Inf
| colspan=2 | false
| This one is debatable. If your code considers it an integer, that's okay too.
|-
| rowspan=2 | complex
| 5.0+0.0i
| colspan=2 | true
|
|-
| 5-5i
| colspan=2 | false
|
|}

(The types and notations shown in these tables are merely examples - you should use the native data types and number literals of your programming language and standard library. Use a different set of test-cases, if this one doesn't demonstrate all relevant behavior.)

Solution:
#include <complex>
#include <math.h>
#include <iostream>

template<class Type>
struct Precision
{
public:
	static Type GetEps()
	{
		return eps;
	}

	static void SetEps(Type e)
	{
		eps = e;
	}

private:
	static Type eps;
};

template<class Type> Type Precision<Type>::eps = static_cast<Type>(1E-7);

template<class DigType>
bool IsDoubleEqual(DigType d1, DigType d2)
{
	return (fabs(d1 - d2) < Precision<DigType>::GetEps());
}

template<class DigType>
DigType IntegerPart(DigType value)
{
	return (value > 0) ? floor(value) : ceil(value);
}

template<class DigType>
DigType FractionPart(DigType value)
{
	return fabs(IntegerPart<DigType>(value) - value);
}

template<class Type>
bool IsInteger(const Type& value)
{
	return false;
}

#define GEN_CHECK_INTEGER(type)			\
template<>					\
bool IsInteger<type>(const type& value)         \
{						\
	return true;				\
}

#define GEN_CHECK_CMPL_INTEGER(type)					\
template<>								\
bool IsInteger<std::complex<type> >(const std::complex<type>& value)	\
{									\
	type zero = type();						\
	return value.imag() == zero;					\
}

#define GEN_CHECK_REAL(type)						\
template<>								\
bool IsInteger<type>(const type& value)					\
{									\
	type zero = type();						\
	return IsDoubleEqual<type>(FractionPart<type>(value), zero);	\
}

#define GEN_CHECK_CMPL_REAL(type)					\
template<>								\
bool IsInteger<std::complex<type> >(const std::complex<type>& value)	\
{									\
	type zero = type();						\
	return IsDoubleEqual<type>(value.imag(), zero);			\
}

#define GEN_INTEGER(type)		\
	GEN_CHECK_INTEGER(type)		\
	GEN_CHECK_CMPL_INTEGER(type)

#define GEN_REAL(type)			\
	GEN_CHECK_REAL(type)		\
	GEN_CHECK_CMPL_REAL(type)

GEN_INTEGER(char)
GEN_INTEGER(unsigned char)
GEN_INTEGER(short)
GEN_INTEGER(unsigned short)
GEN_INTEGER(int)
GEN_INTEGER(unsigned int)
GEN_INTEGER(long)
GEN_INTEGER(unsigned long)
GEN_INTEGER(long long)
GEN_INTEGER(unsigned long long)

GEN_REAL(float)
GEN_REAL(double)
GEN_REAL(long double)

template<class Type>
inline void TestValue(const Type& value)
{
	std::cout << "Value: " << value << " of type: " << typeid(Type).name() << " is integer - " << std::boolalpha << IsInteger(value) << std::endl;
}

int main()
{
	char c = -100;
	unsigned char uc = 200;
	short s = c;
	unsigned short us = uc;
	int i = s;
	unsigned int ui = us;
	long long ll = i;
	unsigned long long ull = ui;

	std::complex<unsigned int> ci1(2, 0);
	std::complex<int> ci2(2, 4);
	std::complex<int> ci3(-2, 4);
	std::complex<unsigned short> cs1(2, 0);
	std::complex<short> cs2(2, 4);
	std::complex<short> cs3(-2, 4);

	std::complex<double> cd1(2, 0);
	std::complex<float> cf1(2, 4);
	std::complex<double> cd2(-2, 4);

	float f1 = 1.0;
	float f2 = -2.0;
	float f3 = -2.4f;
	float f4 = 1.23e-5f;
	float f5 = 1.23e-10f;
	double d1 = f5;

	TestValue(c);
	TestValue(uc);
	TestValue(s);
	TestValue(us);
	TestValue(i);
	TestValue(ui);
	TestValue(ll);
	TestValue(ull);

	TestValue(ci1);
	TestValue(ci2);
	TestValue(ci3);
	TestValue(cs1);
	TestValue(cs2);
	TestValue(cs3);

	TestValue(cd1);
	TestValue(cd2);
	TestValue(cf1);

	TestValue(f1);
	TestValue(f2);
	TestValue(f3);
	TestValue(f4);
	TestValue(f5);
	std::cout << "Set float precision: 1e-15f\n";
	Precision<float>::SetEps(1e-15f);
	TestValue(f5);
	TestValue(d1);
	return 0;
}


Textonyms

When entering text on a phone's digital pad it is possible that a particular combination of digits corresponds to more than one word. Such are called textonyms.

Assuming the digit keys are mapped to letters as follows:
     2 -> ABC
     3 -> DEF
     4 -> GHI
     5 -> JKL
     6 -> MNO
     7 -> PQRS
     8 -> TUV
     9 -> WXYZ

;Task:
Write a program that finds textonyms in a list of words such as
[[Textonyms/wordlist]]   or
unixdict.txt.

The task should produce a report:

 There are #{0} words in #{1} which can be represented by the digit key mapping.
 They require #{2} digit combinations to represent them.
 #{3} digit combinations represent Textonyms.

Where:
 #{0} is the number of words in the list which can be represented by the digit key mapping.
 #{1} is the URL of the wordlist being used.
 #{2} is the number of digit combinations required to represent the words in #{0}.
 #{3} is the number of #{2} which represent more than one word.

At your discretion show a couple of examples of your solution displaying Textonyms.

E.G.:

  2748424767 -> "Briticisms", "criticisms"

;Extra credit:
Use a word list and keypad mapping other than English.

Solution:
#include <fstream>
#include <iostream>
#include <unordered_map>
#include <vector>

struct Textonym_Checker {
private:
    int total;
    int elements;
    int textonyms;
    int max_found;
    std::vector<std::string> max_strings;
    std::unordered_map<std::string, std::vector<std::string>> values;

    int get_mapping(std::string &result, const std::string &input)
    {
        static std::unordered_map<char, char> mapping = {
            {'A', '2'}, {'B', '2'}, {'C', '2'},
            {'D', '3'}, {'E', '3'}, {'F', '3'},
            {'G', '4'}, {'H', '4'}, {'I', '4'},
            {'J', '5'}, {'K', '5'}, {'L', '5'},
            {'M', '6'}, {'N', '6'}, {'O', '6'},
            {'P', '7'}, {'Q', '7'}, {'R', '7'}, {'S', '7'},
            {'T', '8'}, {'U', '8'}, {'V', '8'},
            {'W', '9'}, {'X', '9'}, {'Y', '9'}, {'Z', '9'}
        };

        result = input;
        for (char &c : result) {
            if (!isalnum(c)) return 0;
            if (isalpha(c)) c = mapping[toupper(c)];
        }

        return 1;
    }

public:
    Textonym_Checker() : total(0), elements(0), textonyms(0), max_found(0) { }

    ~Textonym_Checker() { }

    void add(const std::string &str) {
        std::string mapping;
        total++;

        if (!get_mapping(mapping, str)) return;

        const int num_strings = values[mapping].size();

        if (num_strings == 1) textonyms++;
        elements++;

        if (num_strings > max_found) {
            max_strings.clear();
            max_strings.push_back(mapping);
            max_found = num_strings;
        }
        else if (num_strings == max_found)
            max_strings.push_back(mapping);

        values[mapping].push_back(str);
    }

    void results(const std::string &filename) {
        std::cout << "Read " << total << " words from " << filename << "\n\n";

        std::cout << "There are " << elements << " words in " << filename;
        std::cout << " which can be represented by the digit key mapping.\n";
        std::cout << "They require " << values.size() <<
                     " digit combinations to represent them.\n";
        std::cout << textonyms << " digit combinations represent Textonyms.\n\n";
        std::cout << "The numbers mapping to the most words map to ";
        std::cout << max_found + 1 << " words each:\n";

        for (auto it1 : max_strings) {
            std::cout << '\t' << it1 << " maps to: ";
            for (auto it2 : values[it1])
                std::cout << it2 << " ";
            std::cout << '\n';
        }
        std::cout << '\n';
    }

    void match(const std::string &str) {
        auto match = values.find(str);

        if (match == values.end()) {
            std::cout << "Key '" << str << "' not found\n";
        }
        else {
            std::cout << "Key '" << str << "' matches: ";
            for (auto it : values[str])
                std::cout << it << " ";
            std::cout << '\n';
        }
    }
};

int main()
{
    auto filename = "unixdict.txt";
    std::ifstream input(filename);
    Textonym_Checker tc;

    if (input.is_open()) {
        std::string line;
        while (getline(input, line))
            tc.add(line);
    }

    input.close();

    tc.results(filename);
    tc.match("001");
    tc.match("228");
    tc.match("27484247");
    tc.match("7244967473642");
}


The Name Game

Write a program that accepts a name as input and outputs the lyrics to the Shirley Ellis song "The Name Game".

The regular verse

Unless your name begins with a vowel (A, E, I, O, U), 'B', 'F' or 'M' you don't have to care about special rules.
The verse for the name 'Gary' would be like this:

    Gary, Gary, bo-bary
    Banana-fana fo-fary
    Fee-fi-mo-mary
    Gary!

At the end of every line, the name gets repeated without the first letter: Gary becomes ary
If we take (X) as the full name (Gary) and (Y) as the name without the first letter (ary) the verse would look like this:

    (X), (X), bo-b(Y)
    Banana-fana fo-f(Y)
    Fee-fi-mo-m(Y)
    (X)!

Vowel as first letter of the name

If you have a vowel as the first letter of your name (e.g. Earl) you do not truncate the name.
The verse looks like this:

    Earl, Earl, bo-bearl
    Banana-fana fo-fearl
    Fee-fi-mo-mearl
    Earl!

'B', 'F' or 'M' as first letter of the name

In case of a 'B', an 'F' or an 'M' (e.g. Billy, Felix, Mary) there is a special rule.
The line which would 'rebuild' the name (e.g. bo-billy) is sung without the first letter of the name.
The verse for the name Billy looks like this:

    Billy, Billy, bo-illy
    Banana-fana fo-filly
    Fee-fi-mo-milly
    Billy!

For the name 'Felix', this would be right:

    Felix, Felix, bo-belix
    Banana-fana fo-elix
    Fee-fi-mo-melix
    Felix!

Solution:
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>

static void printVerse(const std::string& name) {
    std::string x = name;
    std::transform(x.begin(), x.end(), x.begin(), ::tolower);
    x[0] = toupper(x[0]);

    std::string y;
    switch (x[0]) {
    case 'A':
    case 'E':
    case 'I':
    case 'O':
    case 'U':
        y = x;
        std::transform(y.begin(), y.end(), y.begin(), ::tolower);
        break;
    default:
        y = x.substr(1);
        break;
    }

    std::string b("b" + y);
    std::string f("f" + y);
    std::string m("m" + y);

    switch (x[0]) {
    case 'B':
        b = y;
        break;
    case 'F':
        f = y;
        break;
    case 'M':
        m = y;
        break;
    default:
        break;
    }

    printf("%s, %s, bo-%s\n", x.c_str(), x.c_str(), b.c_str());
    printf("Banana-fana fo-%s\n", f.c_str());
    printf("Fee-fi-mo-%s\n", m.c_str());
    printf("%s!\n\n", x.c_str());
}

int main() {
    using namespace std;

    vector<string> nameList{ "Gary", "Earl", "Billy", "Felix", "Mary", "Steve" };
    for (auto& name : nameList) {
        printVerse(name);
    }

    return 0;
}


The Twelve Days of Christmas

Write a program that outputs the lyrics of the Christmas carol ''The Twelve Days of Christmas''.
The lyrics can be found here.

(You must reproduce the words in the correct order, but case, format, and punctuation are left to your discretion.)

Solution:
#include <iostream>
#include <array>
#include <string>
using namespace std;

int main()
{
    const array<string, 12> days
    {
        "first",
        "second",
        "third",
        "fourth",
        "fifth",
        "sixth",
        "seventh",
        "eighth",
        "ninth",
        "tenth",
        "eleventh",
        "twelfth"
    };

    const array<string, 12> gifts
    {
        "And a partridge in a pear tree",
        "Two turtle doves",
        "Three french hens",
        "Four calling birds",
        "FIVE GOLDEN RINGS",
        "Six geese a-laying",
        "Seven swans a-swimming",
        "Eight maids a-milking",
        "Nine ladies dancing",
        "Ten lords a-leaping",
        "Eleven pipers piping",
        "Twelve drummers drumming"
    };

    for(int i = 0; i < days.size(); ++i)
    {
        cout << "On the " << days[i] << " day of christmas, my true love gave to me\n";

        if(i == 0)
        {
            cout << "A partridge in a pear tree\n";
        }
        else
        {
            int j = i + 1;
            while(j-- > 0) cout << gifts[j] << '\n';
        }

        cout << '\n';
    }

    return 0;
}


Thue-Morse

Create a Thue-Morse sequence.

;See also
*   YouTube entry: The Fairest Sharing Sequence Ever
*   YouTube entry: Math and OCD - My story with the Thue-Morse sequence
*   Task: [[Fairshare between two and more]]

Solution:
#include <iostream>
#include <iterator>
#include <vector>
int main( int argc, char* argv[] ) {
    std::vector<bool> t;
    t.push_back( 0 );
    size_t len = 1;
    std::cout << t[0] << "\n";
    do {
        for( size_t x = 0; x < len; x++ )
            t.push_back( t[x] ? 0 : 1 );
        std::copy( t.begin(), t.end(), std::ostream_iterator<bool>( std::cout ) );
        std::cout << "\n";
        len = t.size();
    } while( len < 60 );
    return 0;
}


Top rank per group

Find the top   ''N''   salaries in each department,   where   ''N''   is provided as a parameter.

Use this data as a formatted internal data structure (adapt it to your language-native idioms, rather than parse at runtime), or identify your external data source:

Employee Name,Employee ID,Salary,Department
Tyler Bennett,E10297,32000,D101
John Rappl,E21437,47000,D050
George Woltman,E00127,53500,D101
Adam Smith,E63535,18000,D202
Claire Buckman,E39876,27800,D202
David McClellan,E04242,41500,D101
Rich Holcomb,E01234,49500,D202
Nathan Adams,E41298,21900,D050
Richard Potter,E43128,15900,D101
David Motsinger,E27002,19250,D202
Tim Sampair,E03033,27000,D101
Kim Arlich,E10001,57000,D190
Timothy Grove,E16398,29900,D190

Solution:
#include <string>
#include <set>
#include <list>
#include <map>
#include <iostream>

struct Employee
{
    std::string Name;
    std::string ID;
    unsigned long Salary;
    std::string Department;
    Employee(std::string _Name = "", std::string _ID = "", unsigned long _Salary = 0, std::string _Department = "")
    : Name(_Name), ID(_ID), Salary(_Salary), Department(_Department)
    { }

    void display(std::ostream& out) const
    {
        out << Name << "\t" << ID << "\t" << Salary << "\t" << Department << std::endl;
    }
};

// We'll tell std::set to use this to sort our employees.
struct CompareEarners
{
    bool operator()(const Employee& e1, const Employee& e2)
    {
        return (e1.Salary > e2.Salary);
    }
};

// A few typedefs to make the code easier to type, read and maintain.
typedef std::list<Employee> EMPLOYEELIST;

// Notice the CompareEarners; We're telling std::set to user our specified comparison mechanism
// to sort its contents.
typedef std::set<Employee, CompareEarners> DEPARTMENTPAYROLL;

typedef std::map<std::string, DEPARTMENTPAYROLL> DEPARTMENTLIST;

void initialize(EMPLOYEELIST& Employees)
{
    // Initialize our employee list data source.
    Employees.push_back(Employee("Tyler Bennett", "E10297", 32000, "D101"));
    Employees.push_back(Employee("John Rappl", "E21437", 47000, "D050"));
    Employees.push_back(Employee("George Woltman", "E21437", 53500, "D101"));
    Employees.push_back(Employee("Adam Smith", "E21437", 18000, "D202"));
    Employees.push_back(Employee("Claire Buckman", "E39876", 27800, "D202"));
    Employees.push_back(Employee("David McClellan", "E04242", 41500, "D101"));
    Employees.push_back(Employee("Rich Holcomb", "E01234", 49500, "D202"));
    Employees.push_back(Employee("Nathan Adams", "E41298", 21900, "D050"));
    Employees.push_back(Employee("Richard Potter", "E43128", 15900, "D101"));
    Employees.push_back(Employee("David Motsinger", "E27002", 19250, "D202"));
    Employees.push_back(Employee("Tim Sampair", "E03033", 27000, "D101"));
    Employees.push_back(Employee("Kim Arlich", "E10001", 57000, "D190"));
    Employees.push_back(Employee("Timothy Grove", "E16398", 29900, "D190"));
}

void group(EMPLOYEELIST& Employees, DEPARTMENTLIST& Departments)
{
    // Loop through all of our employees.
    for( EMPLOYEELIST::iterator iEmployee = Employees.begin();
         Employees.end() != iEmployee;
         ++iEmployee )
    {
        DEPARTMENTPAYROLL& groupSet = Departments[iEmployee->Department];

        // Add our employee to this group.
        groupSet.insert(*iEmployee);
    }
}

void present(DEPARTMENTLIST& Departments, unsigned int N)
{
    // Loop through all of our departments
    for( DEPARTMENTLIST::iterator iDepartment = Departments.begin();
         Departments.end() != iDepartment;
         ++iDepartment )
    {
        std::cout << "In department " << iDepartment->first << std::endl;
        std::cout << "Name\t\tID\tSalary\tDepartment" << std::endl;
        // Get the top three employees for each employee
        unsigned int rank = 1;
        for( DEPARTMENTPAYROLL::iterator iEmployee = iDepartment->second.begin();
             ( iDepartment->second.end() != iEmployee) && (rank <= N);
             ++iEmployee, ++rank )
        {
            iEmployee->display(std::cout);
        }
        std::cout << std::endl;
    }
}

int main(int argc, char* argv[])
{
    // Our container for our list of employees.
    EMPLOYEELIST Employees;

    // Fill our list of employees
    initialize(Employees);

    // Our departments.
    DEPARTMENTLIST Departments;

    // Sort our employees into their departments.
    // This will also rank them.
    group(Employees, Departments);

    // Display the top 3 earners in each department.
    present(Departments, 3);

    return 0;
}


Topswops

Topswops is a card game created by John Conway in the 1970's.

Assume you have a particular permutation of a set of   n   cards numbered   1..n   on both of their faces, for example the arrangement of four cards given by   [2, 4, 1, 3]   where the leftmost card is on top.

A round is composed of reversing the first   m   cards where   m   is the value of the topmost card.

Rounds are repeated until the topmost card is the number   1   and the number of swaps is recorded.

For our example the swaps produce:

    [2, 4, 1, 3]    # Initial shuffle
    [4, 2, 1, 3]
    [3, 1, 2, 4]
    [2, 1, 3, 4]
    [1, 2, 3, 4]

For a total of four swaps from the initial ordering to produce the terminating case where   1   is on top.

For a particular number    n    of cards,    topswops(n)    is the maximum swaps needed for any starting permutation of the   n   cards.

;Task:
The task is to generate and show here a table of    n    vs    topswops(n)    for    n    in the range   1..10   inclusive.

;Note:
Topswops   is also known as   Fannkuch   from the German word   ''Pfannkuchen''    meaning   pancake.

;Related tasks:
*   [[Number reversal game]]
*   [[Sorting algorithms/Pancake sort]]

Solution:
#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

int topswops(int n) {
  std::vector<int> list(n);
  std::iota(std::begin(list), std::end(list), 1);
  int max_steps = 0;
  do {
    auto temp_list = list;
    for (int steps = 1; temp_list[0] != 1; ++steps) {
      std::reverse(std::begin(temp_list), std::begin(temp_list) + temp_list[0]);
      if (steps > max_steps) max_steps = steps;
    }
  } while (std::next_permutation(std::begin(list), std::end(list)));
  return max_steps;
}

int main() {
  for (int i = 1; i <= 10; ++i) {
    std::cout << i << ": " << topswops(i) << std::endl;
  }
  return 0;
}


Trabb Pardo–Knuth algorithm

The TPK algorithm is an early example of a programming chrestomathy.
It was used in Donald Knuth and Luis Trabb Pardo's Stanford tech report The Early Development of Programming Languages.
The report traces the early history of work in developing computer languages in the 1940s and 1950s, giving several translations of the algorithm.

From the wikipedia entry:

 '''ask''' for 11 numbers to be read into a sequence ''S''
 '''reverse''' sequence ''S''
 '''for each''' ''item'' '''in''' sequence ''S''
     ''result'' ''':=''' '''call''' a function to do an ''operation''
     '''if''' ''result'' overflows
         '''alert''' user
     '''else'''
         '''print''' ''result''

The task is to implement the algorithm:
# Use the function:     f(x) = |x|^{0.5} + 5x^3
# The overflow condition is an answer of greater than 400.
# The 'user alert' should not stop processing of other items of the sequence.
# Print a prompt before accepting '''eleven''', textual, numeric inputs.
# You may optionally print the item as well as its associated result, but the results must be in reverse order of input.
# The sequence   ''' ''S'' '''   may be 'implied' and so not shown explicitly.
# ''Print and show the program in action from a typical run here''. (If the output is graphical rather than text then either add a screendump or describe textually what is displayed).

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

int main( ) {
   std::vector<double> input( 11 ) , results( 11 ) ;
   std::cout << "Please enter 11 numbers!\n" ;
   for ( int i = 0 ; i < input.size( ) ; i++ )
      std::cin >> input[i];

   std::transform( input.begin( ) , input.end( ) , results.begin( ) ,
	 [ ]( double n )-> double { return sqrt( abs( n ) ) + 5 * pow( n , 3 ) ; } ) ;
   for ( int i = 10 ; i > -1 ; i-- ) {
      std::cout << "f( " << std::setw( 3 ) << input[ i ] << " ) : " ;
      if ( results[ i ] > 400 )
	 std::cout << "too large!" ;
      else
	 std::cout << results[ i ] << " !" ;
      std::cout << std::endl ;
   }
   return 0 ;
}


Tree datastructures

The following shows a tree of data with nesting denoted by visual levels of indentation:
RosettaCode
    rocks
        code
        comparison
        wiki
    mocks
        trolling

A common datastructure for trees is to define node structures having a name and a, (possibly empty), list of child nodes. The nesting of nodes captures the indentation of the tree. Lets call this '''the nest form'''.
# E.g. if child nodes are surrounded by brackets
#      and separated by commas then:
RosettaCode(rocks(code, ...), ...)
# But only an _example_

Another datastructure for trees is to construct from the root an ordered list of the nodes level of indentation and the name of that node. The indentation for the root node is zero; node 'rocks is indented by one level from the left, and so on. Lets call this '''the indent form'''.
0 RosettaCode
1 rocks
2 code
...

;Task:
# Create/use a nest datastructure format and textual representation for arbitrary trees.
# Create/use an indent datastructure format and textual representation for arbitrary trees.
# Create methods/classes/proceedures/routines etc to:
## Change from a nest tree datastructure to an indent one.
## Change from an indent tree datastructure to a nest one
# Use the above to encode the example at the start into the nest format, and show it.
# transform the initial nest format to indent format and show it.
# transform the indent format to final nest format and show it.
# Compare initial and final nest formats which should be the same.

;Note:
* It's all about showing aspects of the contrasting datastructures as they hold the tree.
* Comparing nested datastructures is secondary - saving formatted output as a string then a string compare would suffice for this task, if its easier.

Show all output on this page.

Solution:
#include <iomanip>
#include <iostream>
#include <list>
#include <string>
#include <vector>
#include <utility>
#include <vector>

class nest_tree;

bool operator==(const nest_tree&, const nest_tree&);

class nest_tree {
public:
    explicit nest_tree(const std::string& name) : name_(name) {}
    nest_tree& add_child(const std::string& name) {
        children_.emplace_back(name);
        return children_.back();
    }
    void print(std::ostream& out) const {
        print(out, 0);
    }
    const std::string& name() const {
        return name_;
    }
    const std::list<nest_tree>& children() const {
        return children_;
    }
    bool equals(const nest_tree& n) const {
        return name_ == n.name_ && children_ == n.children_;
    }
private:
    void print(std::ostream& out, int level) const {
        std::string indent(level * 4, ' ');
        out << indent << name_ << '\n';
        for (const nest_tree& child : children_)
            child.print(out, level + 1);
    }
    std::string name_;
    std::list<nest_tree> children_;
};

bool operator==(const nest_tree& a, const nest_tree& b) {
    return a.equals(b);
}

class indent_tree {
public:
    explicit indent_tree(const nest_tree& n) {
        items_.emplace_back(0, n.name());
        from_nest(n, 0);
    }
    void print(std::ostream& out) const {
        for (const auto& item : items_)
            std::cout << item.first << ' ' << item.second << '\n';
    }
    nest_tree to_nest() const {
        nest_tree n(items_[0].second);
        to_nest_(n, 1, 0);
        return n;
    }
private:
    void from_nest(const nest_tree& n, int level) {
        for (const nest_tree& child : n.children()) {
            items_.emplace_back(level + 1, child.name());
            from_nest(child, level + 1);
        }
    }
    size_t to_nest_(nest_tree& n, size_t pos, int level) const {
        while (pos < items_.size() && items_[pos].first == level + 1) {
            nest_tree& child = n.add_child(items_[pos].second);
            pos = to_nest_(child, pos + 1, level + 1);
        }
        return pos;
    }
    std::vector<std::pair<int, std::string>> items_;
};

int main() {
    nest_tree n("RosettaCode");
    auto& child1 = n.add_child("rocks");
    auto& child2 = n.add_child("mocks");
    child1.add_child("code");
    child1.add_child("comparison");
    child1.add_child("wiki");
    child2.add_child("trolling");

    std::cout << "Initial nest format:\n";
    n.print(std::cout);

    indent_tree i(n);
    std::cout << "\nIndent format:\n";
    i.print(std::cout);

    nest_tree n2(i.to_nest());
    std::cout << "\nFinal nest format:\n";
    n2.print(std::cout);

    std::cout << "\nAre initial and final nest formats equal? "
        << std::boolalpha << n.equals(n2) << '\n';

    return 0;
}


Tree from nesting levels

Given a flat list of integers greater than zero, representing object nesting
levels, e.g. [1, 2, 4],
generate a tree formed from nested lists of those nesting level integers where:
* Every int appears, in order, at its depth of nesting.
* If the next level int is greater than the previous then it appears in a sub-list of the list containing the previous item

The generated tree data structure should ideally be in a languages nested list format that can
be used for further calculations rather than something just calculated for printing.

An input of [1, 2, 4] should produce the equivalent of: [1, [2, [[4]]]]
where 1 is at depth1, 2 is two deep and 4 is nested 4 deep.

[1, 2, 4, 2, 2, 1] should produce [1, [2, [[4]], 2, 2], 1].
All the nesting integers are in the same order but at the correct nesting
levels.

Similarly [3, 1, 3, 1] should generate [[[3]], 1, [[3]], 1]

;Task:
Generate and show here the results for the following inputs:
:* []
:* [1, 2, 4]
:* [3, 1, 3, 1]
:* [1, 2, 3, 1]
:* [3, 2, 1, 3]
:* [3, 3, 3, 1, 1, 3, 3, 3]

Solution:
#include <any>
#include <iostream>
#include <iterator>
#include <vector>

using namespace std;

// Make a tree that is a vector of either values or other trees
vector<any> MakeTree(input_iterator auto first, input_iterator auto last, int depth = 1)
{
    vector<any> tree;
    while (first < last && depth <= *first)
    {
        if(*first == depth)
        {
            // add a single value
            tree.push_back(*first);
            ++first;
        }
        else // (depth < *b)
        {
            // add a subtree
            tree.push_back(MakeTree(first, last, depth + 1));
            first = find(first + 1, last, depth);
        }
    }

    return tree;
}

// Print an input vector or tree
void PrintTree(input_iterator auto first, input_iterator auto last)
{
    cout << "[";
    for(auto it = first; it != last; ++it)
    {
        if(it != first) cout << ", ";
        if constexpr (is_integral_v<remove_reference_t<decltype(*first)>>)
        {
            // for printing the input vector
            cout << *it;
        }
        else
        {
            // for printing the tree
            if(it->type() == typeid(unsigned int))
            {
                // a single value
                cout << any_cast<unsigned int>(*it);
            }
            else
            {
                // a subtree
                const auto& subTree = any_cast<vector<any>>(*it);
                PrintTree(subTree.begin(), subTree.end());
            }
        }
    }
    cout << "]";
}

int main(void)
{
    auto execises = vector<vector<unsigned int>> {
        {},
        {1, 2, 4},
        {3, 1, 3, 1},
        {1, 2, 3, 1},
        {3, 2, 1, 3},
        {3, 3, 3, 1, 1, 3, 3, 3}
        };

    for(const auto& e : execises)
    {
        auto tree = MakeTree(e.begin(), e.end());
        PrintTree(e.begin(), e.end());
        cout << " Nests to:\n";
        PrintTree(tree.begin(), tree.end());
        cout << "\n\n";
    }
}


Tropical algebra overloading

In algebra, a max tropical semiring (also called a max-plus algebra) is the semiring
(R  -Inf, , ) containing the ring of real numbers R augmented by negative infinity,
the max function (returns the greater of two real numbers), and addition.

In max tropical algebra, x  y = max(x, y) and x  y = x + y. The identity for
is -Inf (the max of any number with -infinity is that number), and the identity for  is 0.

;Task:

* Define functions or, if the language supports the symbols as operators, operators for  and  that fit the above description. If the language does not support  and  as operators but allows overloading operators for a new object type, you may instead overload + and * for a new min tropical albrbraic type. If you cannot overload operators in the language used, define ordinary functions for the purpose.

Show that 2  -2 is 0, -0.001  -Inf is -0.001, 0  -Inf is -Inf, 1.5  -1 is 1.5, and -0.5  0 is -0.5.

* Define exponentiation as serial , and in general that a to the power of b is a * b, where a is a real number and b must be a positive integer. Use either | or similar up arrow or the carat ^, as an exponentiation operator if this can be used to overload such "exponentiation" in the language being used. Calculate 5 | 7 using this definition.

* Max tropical algebra is distributive, so that

   a  (b  c) equals a  b  b  c,

where  has precedence over . Demonstrate that 5  (8  7) equals  5  8  5  7.

* If the language used does not support operator overloading, you may use ordinary function names such as tropicalAdd(x, y) and tropicalMul(x, y).

;See also
:;*[Tropical algebra]
:;*[Tropical geometry review article]
:;*[Operator overloading]

Solution:
#include <iostream>
#include <optional>

using namespace std;

class TropicalAlgebra
{
    // use an unset std::optional to represent -infinity
    optional<double> m_value;

public:
    friend std::ostream& operator<<(std::ostream&, const TropicalAlgebra&);
    friend TropicalAlgebra pow(const TropicalAlgebra& base, unsigned int exponent) noexcept;

    // create a point that is initialized to -infinity
    TropicalAlgebra() = default;

    // construct with a value
    explicit TropicalAlgebra(double value) noexcept
        : m_value{value} {}

    // add a value to this one ( p+=q ).  it is common to also overload
    // the += operator when overloading +
    TropicalAlgebra& operator+=(const TropicalAlgebra& rhs) noexcept
    {
        if(!m_value)
        {
            // this point is -infinity so the other point is max
            *this = rhs;
        }
        else if (!rhs.m_value)
        {
            // since rhs is -infinity this point is max
        }
        else
        {
            // both values are valid, find the max
            *m_value = max(*rhs.m_value, *m_value);
        }

        return *this;
    }

    // multiply this value by another (p *= q)
    TropicalAlgebra& operator*=(const TropicalAlgebra& rhs) noexcept
    {
        if(!m_value)
        {
            // since this value is -infinity this point does not need to be
            // modified
        }
        else if (!rhs.m_value)
        {
            // the other point is -infinity, make this -infinity too
            *this = rhs;
        }
        else
        {
            *m_value += *rhs.m_value;
        }

        return *this;
    }
};

// add values (p + q)
inline TropicalAlgebra operator+(TropicalAlgebra lhs, const TropicalAlgebra& rhs) noexcept
{
    // implemented using the += operator defined above
    lhs += rhs;
    return lhs;
}

// multiply values (p * q)
inline TropicalAlgebra operator*(TropicalAlgebra lhs, const TropicalAlgebra&  rhs) noexcept
{
    lhs *= rhs;
    return lhs;
}

// pow is the idomatic way for exponentiation in C++
inline TropicalAlgebra pow(const TropicalAlgebra& base, unsigned int exponent) noexcept
{
    auto result = base;
    for(unsigned int i = 1; i < exponent; i++)
    {
        // compute the power by successive multiplication
        result *= base;
    }
    return result;
}

// print the point
ostream& operator<<(ostream& os, const TropicalAlgebra& pt)
{
    if(!pt.m_value) cout << "-Inf\n";
    else cout << *pt.m_value << "\n";
    return os;
}

int main(void) {
    const TropicalAlgebra a(-2);
    const TropicalAlgebra b(-1);
    const TropicalAlgebra c(-0.5);
    const TropicalAlgebra d(-0.001);
    const TropicalAlgebra e(0);
    const TropicalAlgebra h(1.5);
    const TropicalAlgebra i(2);
    const TropicalAlgebra j(5);
    const TropicalAlgebra k(7);
    const TropicalAlgebra l(8);
    const TropicalAlgebra m; // -Inf

    cout << "2 * -2 == " << i * a;
    cout << "-0.001 + -Inf == " << d + m;
    cout << "0 * -Inf == " << e * m;
    cout << "1.5 + -1 == " << h + b;
    cout << "-0.5 * 0 == " << c * e;
    cout << "pow(5, 7) == " << pow(j, 7);
    cout << "5 * (8 + 7)) == " << j * (l + k);
    cout << "5 * 8 + 5 * 7 == " << j * l + j * k;
}


Truncate a file

Truncate a file to a specific length.   This should be implemented as a routine that takes two parameters: the filename and the required file length (in bytes).

Truncation can be achieved using system or library calls intended for such a task, if such methods exist, or by creating a temporary file of a reduced size and renaming it, after first deleting the original file, if no other method is available.   The file may contain non human readable binary data in an unspecified format, so the routine should be "binary safe", leaving the contents of the untruncated part of the file unchanged.

If the specified filename does not exist, or the provided length is not less than the current file length, then the routine should raise an appropriate error condition.

On some systems, the provided file truncation facilities might not change the file or may extend the file, if the specified length is greater than the current length of the file.

This task permits the use of such facilities.   However, such behaviour should be noted, or optionally a warning message relating to an non change or increase in file size may be implemented.

Solution:
#include <string>
#include <fstream>

using namespace std;

void truncateFile(string filename, int max_size) {
  std::ifstream input( filename, std::ios::binary );
  char buffer;
  string outfile = filename + ".trunc";
  ofstream appendFile(outfile, ios_base::out);
  for(int i=0; i<max_size; i++) {
    input.read( &buffer, sizeof(buffer) );
    appendFile.write(&buffer,1);
  }
  appendFile.close();                                                                                }

int main () {
  truncateFile("test.txt", 5);
  return 0;
}


Truth table

A truth table is a display of the inputs to, and the output of a Boolean function organized as a table where each row gives one combination of input values and the corresponding value of the function.

;Task:
# Input a Boolean function from the user as a string then calculate and print a formatted truth table for the given function. (One can assume that the user input is correct).
# Print and show output for Boolean functions of two and three input variables, but any program should not be limited to that many variables in the function.
# Either reverse-polish or infix notation expressions are allowed.

;Related tasks:
*   [[Boolean values]]
*   [[Ternary logic]]

;See also:
*   Wolfram MathWorld entry on truth tables.
*   some "truth table" examples from Google.

Solution:
#include <iostream>
#include <stack>
#include <string>
#include <sstream>
#include <vector>

struct var {
    char name;
    bool value;
};
std::vector<var> vars;

template<typename T>
T pop(std::stack<T> &s) {
    auto v = s.top();
    s.pop();
    return v;
}

bool is_operator(char c) {
    return c == '&' || c == '|' || c == '!' || c == '^';
}

bool eval_expr(const std::string &expr) {
    std::stack<bool> sob;
    for (auto e : expr) {
        if (e == 'T') {
            sob.push(true);
        } else if (e == 'F') {
            sob.push(false);
        } else {
           auto it = std::find_if(vars.cbegin(), vars.cend(), [e](const var &v) { return v.name == e; });
           if (it != vars.cend()) {
               sob.push(it->value);
           } else {
               int before = sob.size();
               switch (e) {
               case '&':
                   sob.push(pop(sob) & pop(sob));
                   break;
               case '|':
                   sob.push(pop(sob) | pop(sob));
                   break;
               case '!':
                   sob.push(!pop(sob));
                   break;
               case '^':
                   sob.push(pop(sob) ^ pop(sob));
                   break;
               default:
                   throw std::exception("Non-conformant character in expression.");
               }
           }
        }
    }
    if (sob.size() != 1) {
        throw std::exception("Stack should contain exactly one element.");
    }
    return sob.top();
}

void set_vars(int pos, const std::string &expr) {
    if (pos > vars.size()) {
        throw std::exception("Argument to set_vars can't be greater than the number of variables.");
    }
    if (pos == vars.size()) {
        for (auto &v : vars) {
            std::cout << (v.value ? "T  " : "F  ");
        }
        std::cout << (eval_expr(expr) ? 'T' : 'F') << '\n'; //todo implement evaluation
    } else {
        vars[pos].value = false;
        set_vars(pos + 1, expr);
        vars[pos].value = true;
        set_vars(pos + 1, expr);
    }
}

/* removes whitespace and converts to upper case */
std::string process_expr(const std::string &src) {
    std::stringstream expr;

    for (auto c : src) {
        if (!isspace(c)) {
            expr << (char)toupper(c);
        }
    }

    return expr.str();
}

int main() {
    std::cout << "Accepts single-character variables (except for 'T' and 'F',\n";
    std::cout << "which specify explicit true or false values), postfix, with\n";
    std::cout << "&|!^ for and, or, not, xor, respectively; optionally\n";
    std::cout << "seperated by whitespace. Just enter nothing to quit.\n";

    while (true) {
        std::cout << "\nBoolean expression: ";

        std::string input;
        std::getline(std::cin, input);

        auto expr = process_expr(input);
        if (expr.length() == 0) {
            break;
        }

        vars.clear();
        for (auto e : expr) {
            if (!is_operator(e) && e != 'T' && e != 'F') {
                vars.push_back({ e, false });
            }
        }
        std::cout << '\n';
        if (vars.size() == 0) {
            std::cout << "No variables were entered.\n";
        } else {
            for (auto &v : vars) {
                std::cout << v.name << "  ";
            }
            std::cout << expr << '\n';

            auto h = vars.size() * 3 + expr.length();
            for (size_t i = 0; i < h; i++) {
                std::cout << '=';
            }
            std::cout << '\n';

            set_vars(0, expr);
        }
    }

    return 0;
}


Two bullet roulette

The following is supposedly a question given to mathematics graduates seeking jobs on Wall Street:

  A revolver handgun has a revolving cylinder with six chambers for bullets.

  It is loaded with the following procedure:

      1. Check the first chamber to the right of the trigger for a bullet.  If a bullet
         is seen, the cylinder is rotated one chamber clockwise and the next chamber
         checked until an empty chamber is found.

      2. A cartridge containing a bullet is placed in the empty chamber.

      3. The cylinder is then rotated one chamber clockwise.

  To randomize the cylinder's position, the cylinder is spun, which causes the cylinder to take
  a random position from 1 to 6 chamber rotations clockwise from its starting position.

  When the trigger is pulled the gun will fire if there is a bullet in position 0, which is just
  counterclockwise from the loading position.

  The gun is unloaded by removing all cartridges from the cylinder.

  According to the legend, a suicidal Russian imperial military officer plays a game of Russian
  roulette by putting two bullets in a six-chamber cylinder and pulls the trigger twice.
  If the gun fires with a trigger pull, this is considered a successful suicide.

  The cylinder is always spun before the first shot, but it may or may not be spun after putting
  in the first bullet and may or may not be spun after taking the first shot.

  Which of the following situations produces the highest probability of suicide?

    A. Spinning the cylinder after loading the first bullet, and spinning again after the first shot.

    B. Spinning the cylinder after loading the first bullet only.

    C. Spinning the cylinder after firing the first shot only.

    D. Not spinning the cylinder either after loading the first bullet or after the first shot.

    E. The probability is the same for all cases.

;Task:
# Run a repeated simulation of each of the above scenario, calculating the percentage of suicide with a randomization of the four spinning, loading and firing order scenarios.
# Show the results as a percentage of deaths for each type of scenario.
# The hand calculated probabilities are 5/9, 7/12, 5/9, and 1/2. A correct program should produce results close enough to those to allow a correct response to the interview question.

;Reference:
Youtube video on the Russian 1895 Nagant revolver [[https://www.youtube.com/watch?v=Dh1mojMaEtM]]

Solution:
#include <array>
#include <iomanip>
#include <iostream>
#include <random>
#include <sstream>

class Roulette {
private:
    std::array<bool, 6> cylinder;

    std::mt19937 gen;
    std::uniform_int_distribution<> distrib;

    int next_int() {
        return distrib(gen);
    }

    void rshift() {
        std::rotate(cylinder.begin(), cylinder.begin() + 1, cylinder.end());
    }

    void unload() {
        std::fill(cylinder.begin(), cylinder.end(), false);
    }

    void load() {
        while (cylinder[0]) {
            rshift();
        }
        cylinder[0] = true;
        rshift();
    }

    void spin() {
        int lim = next_int();
        for (int i = 1; i < lim; i++) {
            rshift();
        }
    }

    bool fire() {
        auto shot = cylinder[0];
        rshift();
        return shot;
    }

public:
    Roulette() {
        std::random_device rd;
        gen = std::mt19937(rd());
        distrib = std::uniform_int_distribution<>(1, 6);

        unload();
    }

    int method(const std::string &s) {
        unload();
        for (auto c : s) {
            switch (c) {
            case 'L':
                load();
                break;
            case 'S':
                spin();
                break;
            case 'F':
                if (fire()) {
                    return 1;
                }
                break;
            }
        }
        return 0;
    }
};

std::string mstring(const std::string &s) {
    std::stringstream ss;
    bool first = true;

    auto append = [&ss, &first](const std::string s) {
        if (first) {
            first = false;
        } else {
            ss << ", ";
        }
        ss << s;
    };

    for (auto c : s) {
        switch (c) {
        case 'L':
            append("load");
            break;
        case 'S':
            append("spin");
            break;
        case 'F':
            append("fire");
            break;
        }
    }

    return ss.str();
}

void test(const std::string &src) {
    const int tests = 100000;
    int sum = 0;

    Roulette r;
    for (int t = 0; t < tests; t++) {
        sum += r.method(src);
    }

    double pc = 100.0 * sum / tests;

    std::cout << std::left << std::setw(40) << mstring(src) << " produces " << pc << "% deaths.\n";
}

int main() {
    test("LSLSFSF");
    test("LSLSFF");
    test("LLSFSF");
    test("LLSFF");

    return 0;
}


UPC

Goal:
Convert UPC bar codes to decimal.

Specifically:

The UPC standard is actually a collection of standards -- physical standards, data format standards, product reference standards...

Here,   in this task,   we will focus on some of the data format standards,   with an imaginary physical+electrical implementation which converts physical UPC bar codes to ASCII   (with spaces and   '''#'''   characters representing the presence or absence of ink).

;Sample input:
Below, we have a representation of ten different UPC-A bar codes read by our imaginary bar code reader:

         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #
        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #
         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #
       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #
         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #
          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #
         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #
        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #
         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #
        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #

Some of these were entered upside down,   and one entry has a timing error.

;Task:
Implement code to find the corresponding decimal representation of each, rejecting the error.

Extra credit for handling the rows entered upside down   (the other option is to reject them).

;Notes:
Each digit is represented by 7 bits:

    0:  0 0 0 1 1 0 1
    1:  0 0 1 1 0 0 1
    2:  0 0 1 0 0 1 1
    3:  0 1 1 1 1 0 1
    4:  0 1 0 0 0 1 1
    5:  0 1 1 0 0 0 1
    6:  0 1 0 1 1 1 1
    7:  0 1 1 1 0 1 1
    8:  0 1 1 0 1 1 1
    9:  0 0 0 1 0 1 1

On the left hand side of the bar code a space represents a '''0''' and a '''#''' represents a '''1'''.
On the right hand side of the bar code, a '''#''' represents a '''0''' and a space represents a '''1'''
Alternatively (for the above):   spaces always represent zeros and '''#''' characters always represent ones, but the representation is logically negated -- '''1'''s and '''0'''s are flipped -- on the right hand side of the bar code.

;The UPC-A bar code structure:
::*   It begins with at least 9 spaces   (which our imaginary bar code reader unfortunately doesn't always reproduce properly),
::*   then has a     ''' # # '''     sequence marking the start of the sequence,
::*   then has the six "left hand" digits,
::*   then has a   ''' # # '''   sequence in the middle,
::*   then has the six "right hand digits",
::*   then has another   ''' # # '''   (end sequence),   and finally,
::*   then ends with nine trailing spaces   (which might be eaten by wiki edits, and in any event, were not quite captured correctly by our imaginary bar code reader).

Finally, the last digit is a checksum digit which may be used to help detect errors.

;Verification:
Multiply each digit in the represented 12 digit sequence by the corresponding number in   (3,1,3,1,3,1,3,1,3,1,3,1)   and add the products.

The sum (mod 10) must be '''0'''   (must have a zero as its last digit)   if the UPC number has been read correctly.

Solution:
#include <iostream>
#include <locale>
#include <map>
#include <vector>

std::string trim(const std::string &str) {
    auto s = str;

    //rtrim
    auto it1 = std::find_if(s.rbegin(), s.rend(), [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    s.erase(it1.base(), s.end());

    //ltrim
    auto it2 = std::find_if(s.begin(), s.end(), [](char ch) { return !std::isspace<char>(ch, std::locale::classic()); });
    s.erase(s.begin(), it2);

    return s;
}

template <typename T>
std::ostream &operator<<(std::ostream &os, const std::vector<T> &v) {
    auto it = v.cbegin();
    auto end = v.cend();

    os << '[';
    if (it != end) {
        os << *it;
        it = std::next(it);
    }
    while (it != end) {
        os << ", " << *it;
        it = std::next(it);
    }
    return os << ']';
}

const std::map<std::string, int> LEFT_DIGITS = {
    {"   ## #", 0},
    {"  ##  #", 1},
    {"  #  ##", 2},
    {" #### #", 3},
    {" #   ##", 4},
    {" ##   #", 5},
    {" # ####", 6},
    {" ### ##", 7},
    {" ## ###", 8},
    {"   # ##", 9}
};

const std::map<std::string, int> RIGHT_DIGITS = {
    {"###  # ", 0},
    {"##  ## ", 1},
    {"## ##  ", 2},
    {"#    # ", 3},
    {"# ###  ", 4},
    {"#  ### ", 5},
    {"# #    ", 6},
    {"#   #  ", 7},
    {"#  #   ", 8},
    {"### #  ", 9}
};

const std::string END_SENTINEL = "# #";
const std::string MID_SENTINEL = " # # ";

void decodeUPC(const std::string &input) {
    auto decode = [](const std::string &candidate) {
        using OT = std::vector<int>;
        OT output;
        size_t pos = 0;

        auto part = candidate.substr(pos, END_SENTINEL.length());
        if (part == END_SENTINEL) {
            pos += END_SENTINEL.length();
        } else {
            return std::make_pair(false, OT{});
        }

        for (size_t i = 0; i < 6; i++) {
            part = candidate.substr(pos, 7);
            pos += 7;

            auto e = LEFT_DIGITS.find(part);
            if (e != LEFT_DIGITS.end()) {
                output.push_back(e->second);
            } else {
                return std::make_pair(false, output);
            }
        }

        part = candidate.substr(pos, MID_SENTINEL.length());
        if (part == MID_SENTINEL) {
            pos += MID_SENTINEL.length();
        } else {
            return std::make_pair(false, OT{});
        }

        for (size_t i = 0; i < 6; i++) {
            part = candidate.substr(pos, 7);
            pos += 7;

            auto e = RIGHT_DIGITS.find(part);
            if (e != RIGHT_DIGITS.end()) {
                output.push_back(e->second);
            } else {
                return std::make_pair(false, output);
            }
        }

        part = candidate.substr(pos, END_SENTINEL.length());
        if (part == END_SENTINEL) {
            pos += END_SENTINEL.length();
        } else {
            return std::make_pair(false, OT{});
        }

        int sum = 0;
        for (size_t i = 0; i < output.size(); i++) {
            if (i % 2 == 0) {
                sum += 3 * output[i];
            } else {
                sum += output[i];
            }
        }
        return std::make_pair(sum % 10 == 0, output);
    };

    auto candidate = trim(input);

    auto out = decode(candidate);
    if (out.first) {
        std::cout << out.second << '\n';
    } else {
        std::reverse(candidate.begin(), candidate.end());
        out = decode(candidate);
        if (out.first) {
            std::cout << out.second << " Upside down\n";
        } else if (out.second.size()) {
            std::cout << "Invalid checksum\n";
        } else {
            std::cout << "Invalid digit(s)\n";
        }
    }
}

int main() {
    std::vector<std::string> barcodes = {
        "         # #   # ##  #  ## #   ## ### ## ### ## #### # # # ## ##  #   #  ##  ## ###  # ##  ## ### #  # #       ",
        "        # # #   ##   ## # #### #   # ## #   ## #   ## # # # ###  # ###  ##  ## ###  # #  ### ###  # # #         ",
        "         # #    # # #  ###  #   #    # #  #   #    # # # # ## #   ## #   ## #   ##   # # #### ### ## # #         ",
        "       # # ##  ## ##  ##   #  #   #  # ###  # ##  ## # # #   ## ##  #  ### ## ## #   # #### ## #   # #        ",
        "         # # ### ## #   ## ## ###  ##  # ##   #   # ## # # ### #  ## ##  #    # ### #  ## ##  #      # #          ",
        "          # #  #   # ##  ##  #   #   #  # ##  ##  #   # # # # #### #  ##  # #### #### # #  ##  # #### # #         ",
        "         # #  #  ##  ##  # #   ## ##   # ### ## ##   # # # #  #   #   #  #  ### # #    ###  # #  #   # #        ",
        "        # # #    # ##  ##   #  # ##  ##  ### #   #  # # # ### ## ## ### ## ### ### ## #  ##  ### ## # #         ",
        "         # # ### ##   ## # # #### #   ## # #### # #### # # #   #  # ###  #    # ###  # #    # ###  # # #       ",
        "        # # # #### ##   # #### # #   ## ## ### #### # # # #  ### # ###  ###  # # ###  #    # #  ### # #         ",
    };
    for (auto &barcode : barcodes) {
        decodeUPC(barcode);
    }
    return 0;
}


URL encoding

Provide a function or mechanism to convert a provided string into URL encoding representation.

In URL encoding, special characters, control characters and extended characters
are converted into a percent symbol followed by a two digit hexadecimal code,
So a space character encodes into %20 within the string.

For the purposes of this task, every character except 0-9, A-Z and a-z requires conversion, so the following characters all require conversion by default:

* ASCII control codes (Character ranges 00-1F hex (0-31 decimal) and 7F (127 decimal).
* ASCII symbols (Character ranges 32-47 decimal (20-2F hex))
* ASCII symbols (Character ranges 58-64 decimal (3A-40 hex))
* ASCII symbols (Character ranges 91-96 decimal (5B-60 hex))
* ASCII symbols (Character ranges 123-126 decimal (7B-7E hex))
* Extended characters with character codes of 128 decimal (80 hex) and above.

;Example:
The string "http://foo bar/" would be encoded as "http%3A%2F%2Ffoo%20bar%2F".

;Variations:
* Lowercase escapes are legal, as in "http%3a%2f%2ffoo%20bar%2f".
* Special characters have different encodings for different standards:
** RFC 3986, ''Uniform Resource Identifier (URI): Generic Syntax'', section 2.3, says to preserve "-._~".
** HTML 5, section 4.10.22.5 URL-encoded form data, says to preserve "-._*", and to encode space " " to "+".
** encodeURI function in Javascript will preserve "-._~" (RFC 3986) and ";,/?:@&=+$!*'()#".

;Options:
It is permissible to use an exception string (containing a set of symbols
that do not need to be converted).
However, this is an optional feature and is not a requirement of this task.

;Related tasks:
*   [[URL decoding]]
*   [[URL parser]]

Solution:
#include <QByteArray>
#include <iostream>

int main( ) {
   QByteArray text ( "http://foo bar/" ) ;
   QByteArray encoded( text.toPercentEncoding( ) ) ;
   std::cout << encoded.data( ) << '\n' ;
   return 0 ;
}


Unbias a random generator

Given a weighted one-bit generator of random numbers where the probability of a one occurring, P_1, is not the same as P_0, the probability of a zero occurring, the probability of the occurrence of a one followed by a zero is P_1 x P_0, assuming independence. This is the same as the probability of a zero followed by a one: P_0 x P_1.

;Task details:
* Use your language's random number generator to create a function/method/subroutine/... '''randN''' that returns a one or a zero, but with one occurring, on average, 1 out of N times, where N is an integer from the range 3 to 6 inclusive.
* Create a function '''unbiased''' that uses only randN as its source of randomness to become an unbiased generator of random ones and zeroes.
* For N over its range, generate and show counts of the outputs of randN and unbiased(randN).

The actual unbiasing should be done by generating two numbers at a time from randN and only returning a 1 or 0 if they are different. As long as you always return the first number or always return the second number, the probabilities discussed above should take over the biased probability of randN.

This task is an implementation of Von Neumann debiasing, first described in a 1951 paper.

Solution:
#include <iostream>
#include <random>

std::default_random_engine generator;
bool biased(int n) {
    std::uniform_int_distribution<int> distribution(1, n);
    return distribution(generator) == 1;
}

bool unbiased(int n) {
    bool flip1, flip2;

    /* Flip twice, and check if the values are the same.
     * If so, flip again. Otherwise, return the value of the first flip. */

    do {
        flip1 = biased(n);
        flip2 = biased(n);
    } while (flip1 == flip2);

    return flip1;
}

int main() {
    for (size_t n = 3; n <= 6; n++) {
        int biasedZero = 0;
        int biasedOne = 0;
        int unbiasedZero = 0;
        int unbiasedOne = 0;

        for (size_t i = 0; i < 100000; i++) {
            if (biased(n)) {
                biasedOne++;
            } else {
                biasedZero++;
            }
            if (unbiased(n)) {
                unbiasedOne++;
            } else {
                unbiasedZero++;
            }
        }

        std::cout << "(N = " << n << ")\n";
        std::cout << "Biased:\n";
        std::cout << "   0 = " << biasedZero << "; " << biasedZero / 1000.0 << "%\n";
        std::cout << "   1 = " << biasedOne << "; " << biasedOne / 1000.0 << "%\n";
        std::cout << "Unbiased:\n";
        std::cout << "   0 = " << unbiasedZero << "; " << unbiasedZero / 1000.0 << "%\n";
        std::cout << "   1 = " << unbiasedOne << "; " << unbiasedOne / 1000.0 << "%\n";
        std::cout << '\n';
    }
    return 0;
}


Universal Turing machine

One of the foundational mathematical constructs behind computer science
is the universal Turing Machine.

(Alan Turing introduced the idea of such a machine in 1936-1937.)

Indeed one way to definitively prove that a language
is turing-complete
is to implement a universal Turing machine in it.

;Task:
Simulate such a machine capable
of taking the definition of any other Turing machine and executing it.

Of course, you will not have an infinite tape,
but you should emulate this as much as is possible.

The three permissible actions on the tape are "left", "right" and "stay".

To test your universal Turing machine (and prove your programming language
is Turing complete!), you should execute the following two Turing machines
based on the following definitions.

'''Simple incrementer'''
* '''States:''' q0, qf
* '''Initial state:''' q0
* '''Terminating states:''' qf
* '''Permissible symbols:''' B, 1
* '''Blank symbol:''' B
* '''Rules:'''
** (q0, 1, 1, right, q0)
** (q0, B, 1, stay,  qf)

The input for this machine should be a tape of 1 1 1

'''Three-state busy beaver'''
* '''States:''' a, b, c, halt
* '''Initial state:''' a
* '''Terminating states:''' halt
* '''Permissible symbols:''' 0, 1
* '''Blank symbol:''' 0
* '''Rules:'''
** (a, 0, 1, right, b)
** (a, 1, 1, left,  c)
** (b, 0, 1, left,  a)
** (b, 1, 1, right, b)
** (c, 0, 1, left,  b)
** (c, 1, 1, stay,  halt)

The input for this machine should be an empty tape.

'''Bonus:'''

'''5-state, 2-symbol probable Busy Beaver machine from Wikipedia'''
* '''States:''' A, B, C, D, E, H
* '''Initial state:''' A
* '''Terminating states:''' H
* '''Permissible symbols:''' 0, 1
* '''Blank symbol:''' 0
* '''Rules:'''
** (A, 0, 1, right, B)
** (A, 1, 1, left,  C)
** (B, 0, 1, right, C)
** (B, 1, 1, right, B)
** (C, 0, 1, right, D)
** (C, 1, 0, left,  E)
** (D, 0, 1, left,  A)
** (D, 1, 1, left,  D)
** (E, 0, 1, stay,  H)
** (E, 1, 0, left,  A)

The input for this machine should be an empty tape.

This machine runs for more than 47 millions steps.

Solution:
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <fstream>
#include <iomanip>
//--------------------------------------------------------------------------------------------------
typedef unsigned int uint;
using namespace std;
const uint TAPE_MAX_LEN = 49152;
//--------------------------------------------------------------------------------------------------
struct action { char write, direction; };
//--------------------------------------------------------------------------------------------------
class tape
{
public:
    tape( uint startPos = TAPE_MAX_LEN >> 1 ) : MAX_LEN( TAPE_MAX_LEN ) { _sp = startPos; reset(); }
    void reset() { clear( '0' ); headPos = _sp; }
    char read(){ return _t[headPos]; }
    void input( string a ){ if( a == "" ) return; for( uint s = 0; s < a.length(); s++ ) _t[headPos + s] = a[s]; }
    void clear( char c ) {  _t.clear(); blk = c; _t.resize( MAX_LEN, blk ); }
    void action( const action* a ) { write( a->write ); move( a->direction ); }
    void print( int c = 10 )
    {
	int ml = static_cast<int>( MAX_LEN ), st = static_cast<int>( headPos ) - c, ed = static_cast<int>( headPos ) + c + 1, tx;
	for( int x = st; x < ed; x++ )
	{ tx = x; if( tx < 0 ) tx += ml; if( tx >= ml ) tx -= ml; cout << _t[tx]; }
	cout << endl << setw( c + 1 ) << "^" << endl;
    }
private:
    void move( char d ) { if( d == 'N' ) return; headPos += d == 'R' ? 1 : -1; if( headPos >= MAX_LEN ) headPos = d == 'R' ? 0 : MAX_LEN - 1; }
    void write( char a ) { if( a != 'N' ) { if( a == 'B' ) _t[headPos] = blk; else _t[headPos] = a; } }
    string _t; uint headPos, _sp; char blk; const uint MAX_LEN;
};
//--------------------------------------------------------------------------------------------------
class state
{
public:
    bool operator ==( const string o ) { return o == name; }
    string name, next; char symbol, write, direction;
};
//--------------------------------------------------------------------------------------------------
class actionTable
{
public:
    bool loadTable( string file )
    {
	reset();
	ifstream mf; mf.open( file.c_str() ); if( mf.is_open() )
	{
	    string str; state stt;
	    while( mf.good() )
	    {
		getline( mf, str ); if( str[0] == '\'' ) break;
		parseState( str, stt ); states.push_back( stt );
	    }
	    while( mf.good() )
	    {
		getline( mf, str ); if( str == "" ) continue;
		if( str[0] == '!' ) blank = str.erase( 0, 1 )[0];
		if( str[0] == '^' ) curState = str.erase( 0, 1 );
		if( str[0] == '>' ) input = str.erase( 0, 1 );
	    }
	    mf.close(); return true;
	}
	cout << "Could not open " << file << endl; return false;
    }

    bool action( char symbol, action& a )
    {
	vector<state>::iterator f = states.begin();
	while( true )
	{
	    f = find( f, states.end(), curState );
	    if( f == states.end() ) return false;
	    if( ( *f ).symbol == '*' || ( *f ).symbol == symbol || ( ( *f ).symbol == 'B' && blank == symbol ) )
	    { a.direction = ( *f ).direction; a.write = ( *f ).write; curState = ( *f ).next; break; }
	    f++;
	}
	return true;
    }
    void reset() { states.clear(); blank = '0'; curState = input = ""; }
    string getInput() { return input; }
    char getBlank() { return blank; }
private:
    void parseState( string str, state& stt )
    {
	string a[5]; int idx = 0;
	for( string::iterator si = str.begin(); si != str.end(); si++ )
	{ if( ( *si ) == ';' ) idx++; else a[idx].append( &( *si ), 1 ); }
	stt.name = a[0]; stt.symbol = a[1][0]; stt.write = a[2][0]; stt.direction = a[3][0]; stt.next = a[4];
    }
    vector<state> states; char blank; string curState, input;
};
//--------------------------------------------------------------------------------------------------
class utm
{
public:
    utm() { files[0] = "incrementer.utm"; files[1] = "busy_beaver.utm"; files[2] = "sort.utm"; }
    void start()
    {
	while( true )
	{
	    reset(); int t = showMenu(); if( t == 0 ) return;
	    if( !at.loadTable( files[t - 1] ) ) return; startMachine();
	}
    }
private:
    void simulate()
    {
	char r; action a;
	while( true ) { tp.print(); r = tp.read(); if( !( at.action( r, a ) ) ) break; tp.action( &a ); }
	cout << endl << endl; system( "pause" );
    }

    int showMenu()
    {
	int t = -1;
	while( t < 0 || t > 3 )
	{
	    system( "cls" ); cout << "1. Incrementer\n2. Busy beaver\n3. Sort\n\n0. Quit";
	    cout << endl << endl << "Choose an action "; cin >> t;
	}
	return t;
    }

    void reset() { tp.reset(); at.reset(); }
    void startMachine() { system( "cls" ); tp.clear( at.getBlank() ); tp.input( at.getInput() ); simulate(); }

    tape tp; actionTable at; string files[7];
};
//--------------------------------------------------------------------------------------------------
int main( int a, char* args[] ){ utm mm; mm.start(); return 0; }
//--------------------------------------------------------------------------------------------------