Sudoku Algorithm 4

Combination

CombinationTest.lzh

Permutations are ordered in the generated digit group. Combination is an unordered number group. Like permutations, The combination class has a skip function.

public class Combination{
    private int N;
    private int R;
    public int[] Cmb=null;
    private bool First=false;
    public Combination( int N, int R ){
        this.N=N;
        this.R=R;
        if( R>0 && R<=N ){
            Cmb=new int[R];
            Cmb[0]=0;
            for( int m=1; m<R; m++ ) Cmb[m]=Cmb[m-1]+1;
            First=true;
        }
    }

    public bool Successor(){
        if( First ){ First=false; }
        else{
            int m=R-1;
            while( m>=0 && Cmb[m]==(N-R+m) ) m--;
            if( m<0 ){ Cmb=null; return false; }
            Cmb[m]++;
            for( int k=m+1; k<R; k++ ) Cmb[k]=Cmb[k-1]+1;
        }
        return true;
    }
    public bool Successor( int px ){
        if( First ){ First=false; return (Cmb!=null); }

        int k;//actual change position
        if( Cmb[0]==N-R ) return false;
        if( px<R-1 ){
            for( k=px; k>=0; k-- ){ if( Cmb[k]<=N-R ) break; }
            if( k<0 )  return false;
        }
        else{
            for( k=R-1; k>0 && Cmb[k]==N-R+k; --k );
        }

        ++Cmb[k]; 
        for( int j=k; j<R-1; ++j )  Cmb[j+1]=Cmb[j]+1; // Fill the number after the change position
        return true;
    }

    public override string ToString(){
        string st="";
        Array.ForEach( Cmb, p=>{ st+=(" "+p);} );
        return st;
    }
}

Combination is used as follows.
The change position can be changed dynamically.The position designation is from 0 to size-1. In other cases or omitting specification, the skip function does not work.

var cmb = new Combination (6,3);
int px=4;
while(cmb.Successor(px) ){
   (Evaluation processing) 
   (Set change position px of next permutation generation) 
}

Sample(test program)

static void Main( string[ ] args ){
    for( int px=0; px<5; px++ ){
        Combination cmb = new Combination(6,4);
        Console.WriteLine("\n ===== Combination(6,4) px={0}",px );
        while( cmb.Successor(px) )  Console.WriteLine(cmb);
        Console.ReadKey();
    }
}

Execution result

(left: permutation generation result right: work data inside function)

===== Combination(6,4) px=0
 0 1 2 3
 1 2 3 4
 2 3 4 5

 ===== Combination(6,4) px=1
 0 1 2 3
 0 2 3 4
 0 3 4 5
 1 2 3 4
 1 3 4 5
 2 3 4 5

 ===== Combination(6,4) px=2
 0 1 2 3
 0 1 3 4
 0 2 3 4
 0 3 4 5
 1 2 3 4
 1 3 4 5
 2 3 4 5
 
===== Combination(6,4) px=3
 0 1 2 3
 0 1 2 4
 0 1 2 5
 0 1 3 4
 0 1 3 5
 0 1 4 5
 0 2 3 4
 0 2 3 5
 0 2 4 5
 0 3 4 5
 1 2 3 4
 1 2 3 5
 1 2 4 5
 1 3 4 5
 2 3 4 5

 ===== Combination(6,4) px=4
 0 1 2 3
 0 1 2 4
 0 1 2 5
 0 1 3 4
 0 1 3 5
 0 1 4 5
 0 2 3 4
 0 2 3 5
 0 2 4 5
 0 3 4 5
 1 2 3 4
 1 2 3 5
 1 2 4 5
 1 3 4 5
 2 3 4 5