//Array practice
/**
 * Benis Munezero
 * COSC 237 Sec 001
 * Lab 2 Task 1, Array
 */
import java.util.Random;
import java.util.Scanner;
public class Main {
  public static final int MIN = 1;
  public static final int MAX = 100;
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    System.out.println("How many elements/list: ");
    int elements = getInt(sc, "Please enter an intenger!\n");
    int[] nums = new int[elements];
    initRand(nums, MIN, MAX);
    printArray(nums);
    boolean Even = isAllEven(nums);
    boolean Unique = isUnique(nums);
    String option;
    do {
      option = menu();
      switch (option) {
        case "1":
          if (Even) {
            System.out.println("The list is all even numbers!");
          } else {
            System.out.println("The list is not all even numbers!");
          }
          break;
        case "2":
          if (Unique) {
            System.out.println("The list is made up of all unique numbers!");
          } else {
            System.out.println("The list is not made up of all unique numbers!");
          }
          break;
        case "3":
          System.out.println("The minimum gap between 2 adjacent values is " + minGap(nums));
          break;
        case "4":
          for (int i = 0; i < nums.length; i++) {
          System.out.printf("%d ", nums[i]  );
            }
          System.out.println("\nThe mean of the list is " + getMean(nums));
          System.out.printf("The variance for this list is: %.2f", getVariance(nums));
          System.out.printf("\nThe standard deviation for this list is: %.2f\n", Math.sqrt(getVariance(nums)));
          break;
        case "5":
          System.out.printf("The list sorted in ascending order is: %s2\n", bubbleSort(nums));
          System.out.printf("80%-percentile from the list: %s2\n ", top_20(nums));
          break;
        default:
          System.out.println("Please enter a valid option!");
      }      
    } while (!option.equals("0")); 
    System.out.println("Testing Completed!");
  }
  public static int getInt(Scanner in, String prompt) {
    System.out.print(prompt);
    while (!in.hasNextInt()) {
      in.next();
      System.out.println("Error! Not a valid intenger.\n Please input a valid intenger!");
    }
    return in.nextInt();
  }
  public static void initRand(int[] nums, int low, int up) {
    Random rand = new Random();
    for (int i = 0; i < nums.length; i++)
      nums[i] = rand.nextInt(up - low + 1) + low;
  }
  public static void printArray(int[] nums) {
    for (int i = 0; i < nums.length; i++)
      System.out.printf("%d ", nums[i]);
    System.out.println();
  }
  public static boolean isAllEven(int[] nums) {
    for (int i = 0; i < nums.length; i++) {
      if (nums[i] % 2 != 0)
        return false;
    }
    return true;
  }
  public static boolean isUnique(int[] nums) {
    for (int i = 0; i < nums.length - 1; i++) {
      for (int j = i + 1; j < nums.length; j++) {
        if (nums[i] == nums[j]) {
          return false;
        }
      }
    }
    return true;
  }
  public static int minGap(int[] nums) {
    int minimum = MAX;
    for (int i = 0; i < nums.length - 1; i++) {
      int difference = nums[i + 1] - nums[i];
      if (difference < minimum) {
        minimum = difference;
      }
    }
    return minimum;
  }
  public static String menu() {
    System.out.println("Your options are: \n ----------------- " +
        "\n1) All the even values? \n2) All unique values? \n3) Print" +
        " min gap between values \n4) Statistics \n5) Print 80% percentile"
        + " \n0) Exit");
    Scanner sc = new Scanner(System.in);
    String option = sc.next();
    return option;
  }
  public static int[] bubbleSort(int[] nums) {
    int[] sorted = copy(nums);
    for (int i = 0; i < sorted.length - 1; i++) {
      for (int j = 0; j < sorted.length - i - 1; j++) {
        if (sorted[j] > sorted[j + 1]) {
          int temp = sorted[j];
          sorted[j] = sorted[j + 1];
          sorted[j + 1] = temp;
        }
      }
    }
    return sorted;
  }
  public static int[] copy(int[] source) {
    int[] dest = new int[source.length];
    for (int i = 0; i < source.length; i++) {
      dest[i] = source[i];
    }
    return dest;
  }
  public static int[] top_20(int[] nums) {
    int[] sorted = bubbleSort(nums);
    int top20Length = (int) Math.ceil(0.2 * sorted.length);
    int[] top20 = new int[top20Length];
    for (int i = nums.length -1 ; i >= nums.length - top20Length; i--) {
      top20[nums.length - i - 1] = sorted[i];
    }
    return top20;
  }
  public static double getMean(int[] nums) {
    int sum = 0;
    for (int i = 0; i < nums.length; i++) {
      sum += nums[i];
    }
    return sum / nums.length;
  }
  public static double getVariance(int[] nums) {
    double mean = 0;
    for (int i = 0; i < nums.length; i++) {
      mean += nums[i];
    }
    mean /= nums.length;
    double[] deviations = new double[nums.length];
    for (int i = 0; i < nums.length; i++) {
      deviations[i] = (nums[i] - mean) * (nums[i] - mean);
    }
    double variance = 0;
    for (int i = 0; i < nums.length; i++) {
      variance += deviations[i];
    }
    variance /= nums.length;
    return variance;
  }
}
