
public class ListHelp {

    public static boolean matchOrdered(int[] f, int[] g) {
	if(f.length!=g.length) return false;
	for(int i=0;i<f.length;++i) {
	    if(f[i]!=g[i]) return false;
	}
	return true;
    }

    public static boolean matchUnordered(int[] f,int[] g) {
	if(f.length!=g.length) return false;
	if(isSubset(f,g)==false) return false;
	return true;
    }

    public static boolean isSubset(int[] Z1,int[] Z2) {
	for(int i=0;i<Z1.length;++i) {
	    if(onList(Z1[i],Z2,Z2.length)==false) return(false);
	}
	return(true);
    }

    public static boolean isOverlap(int[] Z1,int[] Z2) {
	for(int i=0;i<Z1.length;++i) {
	    if(onList(Z1[i],Z2,Z2.length)==true) return(true);
	}
	return(false);
    }

    public static int[] intersection(int[] Z1,int[] Z2) {
	int[] W=new int[Z1.length];
	int count=0;
	for(int i=0;i<Z1.length;++i) {
	    if(onList(Z1[i],Z2,Z2.length)==true) {
		W[count]=Z1[i];
		++count;
	    }
	}
	return trim(W,count);
    }

    public static int[] append(int[] a,int b) {
	if(a==null) {
	    int[] A={b};
	    return A;
	}
	int n=a.length;
	int[] c=new int[n+1];
	for(int i=0;i<n;++i) c[i]=a[i];
	c[n]=b;
	return c;
    }
    

    public static int[] irredundant(int[] LIST) {
	int L=LIST.length;
	int count=0;
	int[] LIST2=new int[L];
	
	for(int i=0;i<L;++i) {
	    boolean test=onList(LIST[i],LIST2,count);
	    if(test==false) {
		LIST2[count]=LIST[i];
		++count;
	    }
	}
	return trim(LIST2,count);
    }


    public static int[][] irredundant(int[][] LIST) {
	int L=LIST.length;
	int count=0;
	int[][] LIST2=new int[L][0];
	
	for(int i=0;i<L;++i) {
	    boolean test=onList(LIST[i],LIST2,count);
	    if(test==false) {
		LIST2[count]=LIST[i];
		++count;
	    }
	}
	return trim(LIST2,count);
    }
    

    public static boolean onList(int q,int[] a,int n) {
	for(int i=0;i<n;++i) {
	    if(q==a[i]) return true;
	}
	return false;
    }

    

    public static boolean onList(int q,int[] a) {
	return onList(q,a,a.length);
    }
    

    public static boolean onList(int[] q,int[][] a,int n) {
	for(int i=0;i<n;++i) {
	    if(matchOrdered(q,a[i])==true) return true;
	}
	return false;
    }
    
    public static int position(int q,int[] a) {
	int n=a.length;
	for(int i=0;i<n;++i) {
	    if(q==a[i]) return i;
	}
	return -1;
    }
    

    public static int position(int[] q,int[][] a) {
	int n=a.length;
	for(int i=0;i<n;++i) {
	    if(matchOrdered(q,a[i])==true) return i;
	}
	return -1;
    }
    
    public static int[][] merge(int[][] a,int[][] b) {
 	int[][] c=new int[a.length+b.length][0];
	int count=0;
	for(int i=0;i<a.length;++i) {
	    c[count]=copy(a[i]);
	    ++count;
	}
	for(int i=0;i<b.length;++i) {
	    c[count]=copy(b[i]);
	    ++count;
	}
	return c;
    }


    public static int[] merge(int[] a,int[] b) {
	if(a==null) return b;
	if(b==null) return a;
 	int[] c=new int[a.length+b.length];
	int count=0;
	for(int i=0;i<a.length;++i) {
	    c[count]=a[i];
	    ++count;
	}
	for(int i=0;i<b.length;++i) {
	    c[count]=b[i];
	    ++count;
	}
	return c;
    }

    public static Complex[] merge(Complex[] a,Complex[] b) {
 	Complex[] c=new Complex[a.length+b.length];
	int count=0;
	for(int i=0;i<a.length;++i) {
	    c[count]=new Complex(a[i]);
	    ++count;
	}
	for(int i=0;i<b.length;++i) {
	    c[count]=new Complex(b[i]);
	    ++count;
	}
	return c;
    }


    /**This is for Eisenstein integers*/
    public static boolean onList(Complex q,Complex[] a) {
	int n=a.length;
	for(int i=0;i<n;++i) {
	    if(Complex.dist(q,a[i])<.0001) return true;
	}
	return false;
    }
    


    

    public static int[] copy(int[] a) {
	return trim(a,a.length);
    }
    

    /**trimming routines*/
    public static double[] trim(double[] a,int count) {
	double[] b=new double[count];
	for(int i=0;i<count;++i) b[i]=a[i];
	return b;
    }
    
    public static int[] trim(int[] a,int count) {
	int[] b=new int[count];
	for(int i=0;i<count;++i) b[i]=a[i];
	return b;
    }
    
    public static int[][] trim(int[][] a,int count) {
	int[][] b=new int[count][0];
  	for(int i=0;i<count;++i) b[i]=a[i];
	return b;
    }

    public static int[][][] trim(int[][][] a,int count) {
	int[][][] b=new int[count][0][0];
  	for(int i=0;i<count;++i) b[i]=a[i];
	return b;
    }
    
    public static Complex[] trim(Complex[] a,int count) {
	Complex[] b=new Complex[count];
  	for(int i=0;i<count;++i) b[i]=new Complex(a[i]);
	return b;
    }
    
    /* end trimming routines*/
    

    public static int lookup(int k,int[] LIST) {
	for(int i=0;i<LIST.length;++i) {
	    if(LIST[i]==k) return i;
	}
	return -1;
    }


    public static int[] reverse(int[] a) {
	int n=a.length;
	int[] b=new int[n];
	for(int i=0;i<n;++i) {
	    int j=n-i-1;
	    b[i]=a[j];
	}
	return b;
    }

    

    public static int[] rotate(int[] a,int k) {
	int n=a.length;
	int[] b=new int[n];
	for(int i=0;i<n;++i) {
	    int j=(i+k)%n;
	    b[i]=a[j];
	}
	return b;
    }

    public static int[] flatten(int[][] a) {
	int[] list=new int[0];
	for(int i=0;i<a.length;++i) list=merge(list,a[i]);
	return list;
    }


    /** permutation routines*/
    
    public static int[] randomPermutation(int n) {
	int[] b=new int[0];
	boolean test=false;
	while(test==false) {
	    int k=(int)(n*Math.random());
	    if(ListHelp.onList(k,b)==false) b=ListHelp.append(b,k);
	    if(b.length==n) test=true;
	}
    return b;
    }
    
    
    
    /**end permutation routines*/

     

    /**printing routines*/
    
    public static void print(int[] a) {
	if(a==null) return;
	for(int i=0;i<a.length;++i) System.out.print(a[i]+"  ");
	System.out.println("");
    }
    
    public static void print(double[] a) {
	if(a==null) return;
	for(int i=0;i<a.length;++i) {
	    double b=clean(a[i]);
	    System.out.print(b+"  ");
	}
	System.out.println("");
    }

    public static double clean(double a) {
	for(int i=-10;i<10;++i) {
	    if(Math.abs(a-i)<.00000000001) return 1.0*i;
	}
	return a;
    }
    
    public static void print(int[] a,int l) {
	for(int i=0;i<l;++i) System.out.print(a[i]+"  ");
	System.out.println("");
    }
    
    public static void print2(int[] a) {
	for(int i=0;i<a.length;++i) {
	    if(i==0) System.out.print("{");
	    if(i<a.length-1) System.out.print(a[i]+",");
	    if(i==a.length-1) System.out.print(a[i]+"},");
	}
    }
    
    public static void print2(double[] a) {
	for(int i=0;i<a.length;++i) {
	    if(i==0) System.out.print("{");
	    if(i<a.length-1) System.out.print(a[i]+",");
	    if(i==a.length-1) System.out.print(a[i]+"},");
	}
    }
    
}
