package esami;

public class novembre27 {


	public static void main(String[] args) {
		//ricorsioneInfinita(1);
		//loop1();
		//loop2();
		//System.out.println(1);
		//System.out.println (Fibonacci(46));
		//System.out.println (potenza(2,60));
		//System.out.println (potenza(2,60));
		//System.out.println (potRic(2,60));
		int[] pippo = {4, -5, 0, 20, 11, 3};
		//System.out.println(somma(pippo));
		//System.out.println(somma2(pippo));
		System.out.println(minimo(pippo));
		System.out.println(cerca10(pippo));
	}
	
	
	   //esempio di metodo iterativo che non termina
		static void loop () {
			for (long i=0; i<10; i--) {
				 System.out.println(i);
				}
		}
		
		
		static void loop1 () {
			long i=-9223372036854775806L; // numero long negativo pių piccolo -9223372036854775808L
			for (int j=0; j<5; j++) {
				System.out.println(i);
				i--;
				}
		}
		static void loop2 () {
			int i=-2147483646; // numero intero negativo pių piccolo -2147483648
			for (int j=0; j<5; j++) {
				System.out.println(i);
				i--;
				}
		}
		//esempio di metodo ricorsivo che non termina
		static int ricorsioneInfinita(int n) {
			if (n==0) return 1;
			return 2*ricorsioneInfinita(n+1);
		}
		
		
	/*versione ricorsiva Fibonacci
	* Fib(n)=1 se n=0 o n=1
	* Fib(n)=Fib(n-1) + Fib(n-2) se n>1
	*/
		
	 static long Fib (int n) {
		 if (n<0) return 0; //situazione anomala
		 if (n==0 ||n==1) return 1; // caso base
		 return Fib(n-1) + Fib (n-2); //caso ricorsivo		
	}
	
		
	
	/*versione iterativa Fibonacci
	 * casi base e situazioni anomale
	 * per i=2,...,n fibnuovo=fibcorr + fibprec 
	 * e si aggiornano fibprec e fibcorr per la prossima iterazione
	 * inizializzato con fibcorr=fibprec=1
	 */
	
	  static long Fibonacci (int n) {
		  if (n<0) return 0; 
		  long fibprec=1;
		  long fibcorr=1;
		  long fibnuovo=1;
		  for (int i=2; i<=n; i++)
		  {fibnuovo=fibprec+fibcorr;
		  fibprec=fibcorr;
		  fibcorr=fibnuovo;
		  }
		  return fibnuovo;
		  }
	 
	
	
	/* versione iterativa potenza: risultato 0 per esponente negativo
	 * potenza (base, esponente)=base*base*....*base (esponente volte)
	*/
	
	 static long potenza (int base, int esponente) {	
		 if (esponente <0 || base==0) return 0;
		 long risultato=1;
		 for (int i=1; i<=esponente; i++)
		         { risultato=risultato*base;}
		 return risultato;
	}
	
	
	/*versione ricorsiva potRic: risultato 0 per potenza negativa o per base uguale a 0
	* potRic (base, esponente)=1    se esponente=0
	* potRic (base, esponente)=base * potRic (base, esponente-1 )  se esponente>0
	*/
	
	static long potRic (int base, int esponente) {
		     if (esponente <0 || base==0) return 0;         //situazione anomala
		         if (esponente ==0)  return 1;         //caso base
				return base* potRic(base, esponente-1);			//caso ricorsivo
		}
	
	

	/*
	 * scrivere un metodo ricorsivo somma
	 * che, preso come parametro un array di int,
	 * restituisce la somma dei suoi elementi
	 * la ricorsione č sul numero degli elementi dell'array
	 */
	//1° soluzione "scolastica"
	
	 static int somma (int[] a) {
				if (a.length==0) return 0;// caso base e situazione anomala
				int []b=new int[a.length -1];
				for (int i=0; i<b.length;i++){b[i]=a[i+1];}
				return a[0] + somma(b);// caso ricorsivo
     }
     
	
	/* 2° soluzione (MIGLIORE)
	 * si usa un metodo ausiliario iniziale che fa la prima chiamata di quello ricorsivo
	*/
	
	static int somma2 (int[] a, int inizio) {	
	if (inizio==a.length) return 0;
	return a[inizio]+ somma2(a,inizio+1);}
	
	
	/* metodo ausiliario per la prima chiamata
	 */
	
	 static int somma2 (int[]a) {return somma2(a,0);
	}
	
		
	/* scrivere un metodo ricorsivo minimo
	 * che, preso come parametro un array di int,
	 * restituisce il minimo tra i suoi elementi
	 * ATTENZIONE: il caso base č l'array lungo 1
	 * Array lungo 0 situazione anomala
	 */
	
	 static int minimo (int[] a, int inizio) {	
		 if (inizio> a.length-1) return 0;
		 if (inizio== a.length-1) return a[inizio];
		 int m=minimo(a, inizio+1);
		if (a[inizio] <m) return a[inizio];
		return m;
	}
	
	
	static int minimo (int[]a) {
	return minimo(a,0);
	}
	
	static boolean palindromo (char[] arr)
	{//int j=arr.length-1;
	for (int i=0; i<arr.length/2; i++)
		{if (arr[i]!=arr[arr.length-1-i]) return false; }
	return true;
	
	}
		
	/* scrivere un metodo cerca10 che 
	 * preso come parametro un array di int
	 * restituisce true se e solo se
	 * l'array contiene il numero 10
	 */
	
	static boolean cerca10 (int[]a, int inizio) {
		if (inizio==a.length) return false;
		if (a[inizio] ==10) return true;
		return cerca10(a, inizio +1);
	}
     static boolean cerca10 (int[]a) {return cerca10(a,0);
	}
	
}

