package lab10;

import java.util.Arrays;
import java.util.function.BiFunction;
import java.util.function.Function;

public class XmpFunc {

	// No constructor and no fields... this is just to provide a method
	
	public static double reduce(double[] array,BiFunction<Double,Double,Double> fn,double init) {
		double answer=init;
		for(Double elem : array) {
			answer=fn.apply(answer,elem);
		}
		return answer;
	}
	
	public static double[] sequence(double init,Function<Double,Double> fn,int count) {
		double[] answer=new double[count];
		int i;
		answer[0]=init;
		for(i=1;i<count;i++) {
			answer[i]=fn.apply(answer[i-1]);
		}
		return answer;
	}
	
	public static double[] indexSequence(double init,BiFunction<Integer,Double,Double> fn,int count) {
		double[] answer=new double[count];
		int i;
		answer[0]=init;
		for(i=1;i<count;i++) {
			answer[i]=fn.apply(i,answer[i-1]);
		}
		return answer;
	}
	
	public static double[] biSequence(double init0,double init1,BiFunction<Double,Double,Double> fn,int count) {
		double[] answer=new double[count];
		int i;
		answer[0]=init0;
		answer[1]=init1;
		for(i=2;i<count;i++) {
			answer[i]=fn.apply(answer[i-2],answer[i-1]);
		}
		return answer;
	}

	public static void main(String[] args) {
		double[] nums = { 1.1, 2.2, 3.3, 4.4 };
		System.out.println("Sequence x+1: " + Arrays.toString(sequence(1,x->x+1,10)));
		System.out.println("Sequence 1/(x+1): " + Arrays.toString(sequence(2,x->1/(x+1),10)));
		System.out.println("Sequence 2x+1: " + Arrays.toString(sequence(1,x->(2*x+1),10)));
		
		System.out.println("The sum of nums is " + reduce(nums,(x,y)->x+y,0.0));
		System.out.println("The product of nums is " + reduce(nums,(x,y)->x*y,1.0));
		System.out.println("The diff of nums is " + reduce(nums,(x,y)->y-x,0.0));
		System.out.println("The div of nums is " + reduce(nums,(x,y)->y/x,1.0));
		
		
		System.out.println("Sequence4: " + Arrays.toString(indexSequence(1,(x,y)->(x+y),10)));
		System.out.println("Sequence5: " + Arrays.toString(indexSequence(1,(x,y)->(x*y),10)));
		System.out.println("Sequence6: " + Arrays.toString(biSequence(1,1,(x,y)->(x+y),10)));
		System.out.println("The sum of 10 fibs is " + reduce(biSequence(1,1,(x,y)->(x+y),10),(x,y)->(x+y),0.0));
	}

}
