// g++ -std=c++11 -O3 -Wall -Wextra -Wpedantic -o perms perms.cpp && ./perms
// | sort -u | wc -l

#include <iostream>
#include <utility>
#include <vector>

// Obviously bad, but that isn't the point.
using Symbol = int;
using Perm   = std::vector<Symbol>;
using Perms  = std::vector<Perm>;

Perms listPermsRecursive(Perm perm)
{
    if (perm.size() == 1)
        return Perms{std::move(perm)};

    Perms ret;
    auto remember = [&ret](Perms perms, Symbol const & symbol)
    {
        for (auto & perm : perms)
        {
            perm.push_back(symbol);
            ret.push_back(std::move(perm));
        }
    };

    auto symbol = perm.back();
    perm.pop_back();
    remember(listPermsRecursive(perm), symbol);
    for (auto & symbol_new : perm)
    {
        std::swap(symbol_new, symbol);
        remember(listPermsRecursive(perm), symbol);
    }
    return ret;
}

int main()
{
    auto perms = listPermsRecursive({0, 1, 2, 3});
    for (auto const & perm : perms)
    {
        for (auto const & symbol : perm)
            std::cout << symbol << " ";
        std::cout << std::endl;
    }
}