Example #1
0
        static matrix DList(int n, int start)
        {
            start--; // use 0 basing
            var a = Enumerable.Range(0, n).ToArray();

            a[start] = a[0];
            a[0]     = start;
            Array.Sort(a, 1, a.Length - 1);
            var first = a[1];
            // recursive closure permutes a[1:]
            matrix r = new matrix();

            void recurse(int last)
            {
                if (last == first)
                {
                    // bottom of recursion. you get here once for each permutation.
                    // test if permutation is deranged.
                    for (int j = 1; j < a.Length; j++)
                    {
                        var v = a[j];
                        if (j == v)
                        {
                            return; //no, ignore it
                        }
                    }
                    // yes, save a copy with 1 based indexing
                    var b = a.Select(v => v + 1).ToArray();
                    r.Add(b.ToList());
                    return;
                }
                for (int i = last; i >= 1; i--)
                {
                    Swap(ref a[i], ref a[last]);
                    recurse(last - 1);
                    Swap(ref a[i], ref a[last]);
                }
            }

            recurse(n - 1);
            return(r);
        }
Example #2
0
        static ulong ReducedLatinSquares(int n, bool echo)
        {
            if (n <= 0)
            {
                if (echo)
                {
                    Console.WriteLine("[]\n");
                }
                return(0);
            }
            else if (n == 1)
            {
                if (echo)
                {
                    Console.WriteLine("[1]\n");
                }
                return(1);
            }

            matrix rlatin = new matrix();

            for (int i = 0; i < n; i++)
            {
                rlatin.Add(new List <int>());
                for (int j = 0; j < n; j++)
                {
                    rlatin[i].Add(0);
                }
            }
            // first row
            for (int j = 0; j < n; j++)
            {
                rlatin[0][j] = j + 1;
            }

            ulong count = 0;

            void recurse(int i)
            {
                var rows = DList(n, i);

                for (int r = 0; r < rows.Count; 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.Count - 1)
                                {
                                    goto outer;
                                }
                                if (i > 2)
                                {
                                    return;
                                }
                            }
                        }
                    }
                    if (i < n)
                    {
                        recurse(i + 1);
                    }
                    else
                    {
                        count++;
                        if (echo)
                        {
                            PrintSquare(rlatin, n);
                        }
                    }
                    outer : { }
                }
            }

            //remaing rows
            recurse(2);
            return(count);
        }