Task: Latin Squares in reduced form


C++: #include <algorithm>
#include <functional>
#include <iostream>
#include <numeric>
#include <vector>

typedef std::vector<std::vector<int>> matrix;

matrix dList(int n, int start) {
    start--; 

    std::vector<int> a(n);
    std::iota(a.begin(), a.end(), 0);
    a[start] = a[0];
    a[0] = start;
    std::sort(a.begin() + 1, a.end());
    auto first = a[1];
    
    matrix r;
    std::function<void(int)> recurse;
    recurse = [&](int last) {
        if (last == first) {
            
            
            for (size_t j = 1; j < a.size(); j++) {
                auto v = a[j];
                if (j == v) {
                    return; 
                }
            }
            
            std::vector<int> b;
            std::transform(a.cbegin(), a.cend(), std::back_inserter(b), [](int v) { return v + 1; });
            r.push_back(b);
            return;
        }
        for (int i = last; i >= 1; i--) {
            std::swap(a[i], a[last]);
            recurse(last - 1);
            std::swap(a[i], a[last]);
        }
    };
    recurse(n - 1);
    return r;
}

void printSquare(const matrix &latin, int n) {
    for (auto &row : latin) {
        auto it = row.cbegin();
        auto end = row.cend();
        std::cout << '[';
        if (it != end) {
            std::cout << *it;
            it = std::next(it);
        }
        while (it != end) {
            std::cout << ", " << *it;
            it = std::next(it);
        }
        std::cout << "]\n";
    }
    std::cout << '\n';
}

unsigned long reducedLatinSquares(int n, bool echo) {
    if (n <= 0) {
        if (echo) {
            std::cout << "[]\n";
        }
        return 0;
    } else if (n == 1) {
        if (echo) {
            std::cout << "[1]\n";
        }
        return 1;
    }

    matrix rlatin;
    for (int i = 0; i < n; i++) {
        rlatin.push_back({});
        for (int j = 0; j < n; j++) {
            rlatin[i].push_back(j);
        }
    }
    
    for (int j = 0; j < n; j++) {
        rlatin[0][j] = j + 1;
    }

    unsigned long count = 0;
    std::function<void(int)> recurse;
    recurse = [&](int i) {
        auto rows = dList(n, i);

        for (size_t r = 0; r < rows.size(); r++) {
            rlatin[i - 1] = rows[r];
            for (int k = 0; k < i - 1; k++) {
                for (int j = 1; j < n; j++) {
                    if (rlatin[k][j] == rlatin[i - 1][j]) {
                        if (r < rows.size() - 1) {
                            goto outer;
                        }
                        if (i > 2) {
                            return;
                        }
                    }
                }
            }
            if (i < n) {
                recurse(i + 1);
            } else {
                count++;
                if (echo) {
                    printSquare(rlatin, n);
                }
            }
        outer: {}
        }
    };

    
    recurse(2);
    return count;
}

unsigned long factorial(unsigned long n) {
    if (n <= 0) return 1;
    unsigned long prod = 1;
    for (unsigned long i = 2; i <= n; i++) {
        prod *= i;
    }
    return prod;
}

int main() {
    std::cout << "The four reduced lating squares of order 4 are:\n";
    reducedLatinSquares(4, true);

    std::cout << "The size of the set of reduced latin squares for the following orders\n";
    std::cout << "and hence the total number of latin squares of these orders are:\n\n";
    for (int n = 1; n < 7; n++) {
        auto size = reducedLatinSquares(n, false);
        auto f = factorial(n - 1);
        f *= f * n * size;
        std::cout << "Order " << n << ": Size " << size << " x " << n << "! x " << (n - 1) << "! => Total " << f << '\n';
    }

    return 0;
}






Python: def dList(n, start):
    start -= 1 
    a = range(n)
    a[start] = a[0]
    a[0] = start
    a[1:] = sorted(a[1:])
    first = a[1]
    
    r = []
    def recurse(last):
        if (last == first):
            
            
            
            for j,v in enumerate(a[1:]):
                if j + 1 == v:
                    return 
            b = [x + 1 for x in a]
            r.append(b)
            return
        for i in xrange(last, 0, -1):
            a[i], a[last] = a[last], a[i]
            recurse(last - 1)
            a[i], a[last] = a[last], a[i]
    recurse(n - 1)
    return r

def printSquare(latin,n):
    for row in latin:
        print row
    print

def reducedLatinSquares(n,echo):
    if n <= 0:
        if echo:
            print []
        return 0
    elif n == 1:
        if echo:
            print [1]
        return 1

    rlatin = [None] * n
    for i in xrange(n):
        rlatin[i] = [None] * n
    
    for j in xrange(0, n):
        rlatin[0][j] = j + 1

    class OuterScope:
        count = 0
    def recurse(i):
        rows = dList(n, i)

        for r in xrange(len(rows)):
            rlatin[i - 1] = rows[r]
            justContinue = False
            k = 0
            while not justContinue and k < i - 1:
                for j in xrange(1, n):
                    if rlatin[k][j] == rlatin[i - 1][j]:
                        if r < len(rows) - 1:
                            justContinue = True
                            break
                        if i > 2:
                            return
                k += 1
            if not justContinue:
                if i < n:
                    recurse(i + 1)
                else:
                    OuterScope.count += 1
                    if echo:
                        printSquare(rlatin, n)

    
    recurse(2)
    return OuterScope.count

def factorial(n):
    if n == 0:
        return 1
    prod = 1
    for i in xrange(2, n + 1):
        prod *= i
    return prod

print "The four reduced latin squares of order 4 are:\n"
reducedLatinSquares(4,True)

print "The size of the set of reduced latin squares for the following orders"
print "and hence the total number of latin squares of these orders are:\n"
for n in xrange(1, 7):
    size = reducedLatinSquares(n, False)
    f = factorial(n - 1)
    f *= f * n * size
    print "Order %d: Size %-4d x %d! x %d! => Total %d" % (n, size, n, n - 1, f)