
interface UnaryFunc 	{ public int apply(int i); }
interface BinaryFunc 	{ public int apply(int i,int j); }
interface PolyFunc 		{ public int apply(int i[]); }


class Array
	{
	int as[];
	int start;
	int end;
	public Array(int n_start,int n_end)
		{
		end=n_end;	start=n_start;
		as=new int[end-start];
		}
	public void setToCount(int a,int b,int step)
		{
		for(int i=0;i<(b-a)/step;i++)
			{
			set(i+start,a+i*step);
			}
		}
	public void set(int a1,int a2,int a_step,Array t,int b1,int b2,int b_step)
		{
		int num=Math.min(a2-a1/a_step,b2-b1/b_step);
		for(int i=0;i<num;i++)
			{
			set(i*a_step+a1,t.get(i*b_step+b1));
			}
		}
	public void set(Array t)
		{
		for(int i=0;i<end-start;i++)
			setABS(i,t.getABS(i));
		}
	public void plus(Array t)
		{
		for(int i=0;i<end-start;i++)
			setABS(i,getABS(i)+t.getABS(i));
		}
	public void times(Array t)
		{
		for(int i=0;i<end-start;i++)
			setABS(i,getABS(i)+t.getABS(i));
		}
	public void apply(UnaryFunc f)
		{
		for(int i=0;i<end-start;i++)
			setABS(i,f.apply(getABS(i)));
		}
	public void apply(BinaryFunc f,Array t)
		{
		for(int i=0;i<end-start;i++)
			setABS(i,f.apply(getABS(i),t.getABS(i)));
		}
	public void apply(PolyFunc f,Array ts[])
		{
		int size=ts.length;
		int vs[]=new int[size];
		for(int i=0;i<end-start;i++)
			{
			for(int j=0;j<size;j++)
				{
				vs[j]=ts[j].getABS(i);
				}
			setABS(i,f.apply(vs));
			}
		}

	public int get(int i) 				{ return as[i-start]; }
	public int getABS(int i) 			{ return as[i]; }
	public void set(int i,int v) 		{ as[i-start]=v; }
	public void setABS(int i,int v) 	{ as[i]=v; }

	public String toString()
		{
		String ret="Array ("+start+":"+end+")={";
		for(int i=start;i<end;i++)
			{
			ret+=get(i)+",";
			}
		return ret+"}";
		}
	}


class Negate implements UnaryFunc
	{
	public int apply(int i)	{	return -i;	}
	}

class Divide implements BinaryFunc
	{
	public int apply(int i,int j)	{	return i/j;	}
	}

class Sum implements PolyFunc
	{
	public int apply(int is[])	
		{
		int ret=0;
		for(int i=0;i<is.length;i++)	ret+=is[i];	
		return ret;	
		}
	}


public class FortranArraysTest
	{
	public static void main(String args[])
		{
		Array t=new Array(10,60);
		Array s=new Array(0,10);
		Array r=new Array(0,10);
		Array q=new Array(0,10);
		Array p=new Array(0,10);
		Array o=new Array(0,10);
		Array n=new Array(0,10);

		t.setToCount(1,101,2);
		s.set(0,10,1,t,10,60,5);
		r.set(s);
		r.times(r);
		q.set(r);
		q.plus(s);
		p.set(r);
		p.apply(new Negate());
		o.set(r);
		o.apply(new Divide(),p);
		n.set(r);
		Array arrays[]={s,r,q,p,o,n};
		n.apply(new Sum(),arrays);


		System.out.println(t);
		System.out.println(s);
		System.out.println(r);
		System.out.println(q);
		System.out.println(p);
		System.out.println(o);
		System.out.println(n);
		}
	}
