R
R
readical2015-06-04 09:20:15
Algorithms
readical, 2015-06-04 09:20:15

How can you generate permutations with additional constraints on elements iteratively?

Are there code examples or algorithms that can generate permutations with additional constraints on elements iteratively?
That is, for every two elements there must be a truly defined arithmetic-logical expression.
What I have found in old books is using goto.
Recursively, tasks are easily solved.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
M
Mrrl, 2015-06-04
@readical

What's not to like about goto? A completely legal operator. In which case, it is easy to get rid of it by converting the code into a state machine (you get a cycle with one switch inside). Although more often one additional logical variable is enough.
And what type of restriction? And is there a restriction on the order in which permutations are issued?
UPD. Here is a solution in C#. Not the most efficient though.

class Program{
        static IEnumerable<int[]> Permutations(int N,Func<int,int,bool>Cond1,Func<int,int,int,int,bool> Cond2) {
            int[] res=new int[N];
            int k=0;
            res[0]=0;
            while(k>=0){
                if(++res[k]<=N){
                    if(Cond1(k+1,res[k]) && GoodValue(res,k,Cond2)){
                        if(k==N-1) yield return res;
                        else res[++k]=0;
                    }
                }else k--;
            }
        }
        static private bool GoodValue(int[] res,int k,Func<int,int,int,int,bool> Cond) {
            for(int i=0;i<k;i++) {
                if(res[i]==res[k] || !Cond(i+1,res[i],k+1,res[k])) return false;
            }
            return true;
        }

        static int N=6;
        static bool Cond1(int a,int va) {
            if(a==1) return va==1;
            if(a==N) return va==N;
            return true;
        }
        static bool Cond2(int a,int va,int b,int vb) { 
            return Math.Abs(a-b)>1 || Math.Abs(va-vb)<=3;
        }
        static void Main(string[] args) {
            foreach(int[] perm in Permutations(N,Cond1,Cond2))
                Console.WriteLine(String.Join(",",perm));
        }
    }

The Permutations function is passed two conditions. The first Cond1(a,va) checks if element va can be at position a, the second Cond2(a,va,b,vb) checks if va can be at position a and vb at position b at the same time.
As an example, printing permutations from the frog problem from ProjectEuler: https://projecteuler.net/problem=490
For N=6, it prints the expected 14 permutations:
1,2,3,4,5,6
1,2,3,5,4,6
1,2,4,3,5,6
1,2,4,5,3,6
1,2,5,3,4,6
1,2,5,4,3,6
1,3,2,4,5,6
1,3,2,5,4,6
1,3,4,2,5,6
1,3,5,2,4,6
1,4,2,3,5,6
1,4,2,5,3,6
1,4,3,2,5,6
1,4,5,2,3,6

If you don’t like the yield return construct, insert your permutation processing instead, and describe the function as void. If we remove the check res[I]==res[k] from GoodValue, then instead of permutations, all N-element sets of numbers 1..N that satisfy the condition will be printed.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question